Sanguosha.Core.Games.RoleGame.RoleGameRuleTrigger.Run C# (CSharp) Méthode

Run() public méthode

public Run ( Sanguosha.Core.Triggers.GameEvent gameEvent, GameEventArgs eventArgs ) : void
gameEvent Sanguosha.Core.Triggers.GameEvent
eventArgs Sanguosha.Core.Triggers.GameEventArgs
Résultat void
            public override void Run(GameEvent gameEvent, GameEventArgs eventArgs)
            {
                RoleGame game = Game.CurrentGame as RoleGame;

                foreach (Player pp in game.Players)
                {
                    game.HandCardVisibility.Add(pp, new List<Player>() { pp });
                }

                int numberOfDefectors = (game.Players.Count > 2 ? game.Settings.NumberOfDefectors : 1);

                // Put the whole deck in the dealing deck

                foreach (Card card in game.CardSet)
                {
                    // We don't want hero cards
                    if (card.Type is HeroCardHandler)
                    {
                        bool isSPHero = false;
                        if (!game.IsClient || game.IsPanorama) isSPHero = (card.Type as HeroCardHandler).Hero.IsSpecialHero;
                        else isSPHero = card.Id == Card.UnknownSPHeroId;
                        if (isSPHero)
                        {
                            game.Decks[DeckType.SpecialHeroes].Add(card);
                            card.Place = new DeckPlace(null, DeckType.SpecialHeroes);
                        }
                        else
                        {
                            game.Decks[DeckType.Heroes].Add(card);
                            card.Place = new DeckPlace(null, DeckType.Heroes);
                        }

                    }
                    else if (card.Type is RoleCardHandler)
                    {
                        card.Place = new DeckPlace(null, RoleDeckType);
                    }
                    else
                    {
                        game.Decks[DeckType.Dealing].Add(card);
                        card.Place = new DeckPlace(null, DeckType.Dealing);
                    }
                }
                if (game.Players.Count == 0)
                {
                    return;
                }
                // Await role decision
                int seed = DateTime.Now.Millisecond;
                game.Seed = seed;
                Trace.TraceError("Seed is {0}", seed);
                if (game.RandomGenerator == null)
                {
                    game.RandomGenerator = new Random(seed);
                    Random random = game.RandomGenerator;
                }
                int rulerId = 0;

                game.Decks[null, RoleDeckType].Add(_FindARoleCard(Role.Ruler));
                Trace.Assert(game.Players.Count > 1);
                Trace.Assert(numberOfDefectors + 1 <= game.Players.Count);
                int t = numberOfDefectors;
                while (t-- > 0)
                {
                    game.Decks[null, RoleDeckType].Add(_FindARoleCard(Role.Defector));
                }
                int remaining = game.Players.Count - numberOfDefectors;
                int rebel;
                int loyalist;
                if (remaining <= 1)
                {
                    rebel = 0;
                    loyalist = 0;
                }
                else
                {
                    rebel = (int)Math.Ceiling(((double)remaining) / 2);
                    loyalist = remaining - rebel - 1;
                }

                Trace.Assert(rebel + loyalist + numberOfDefectors + 1 == game.Players.Count);
                game.NumberOfDefectors = numberOfDefectors;
                game.NumberOfRebels = rebel;
                game.AvailableRoles.Add(Role.Ruler);

                for (int dd = 0; dd < game.NumberOfDefectors; dd++)
                {
                    game.AvailableRoles.Add(Role.Defector);
                }

                while (rebel-- > 0)
                {
                    game.Decks[null, RoleDeckType].Add(_FindARoleCard(Role.Rebel));
                    game.AvailableRoles.Add(Role.Rebel);
                }
                while (loyalist-- > 0)
                {
                    game.Decks[null, RoleDeckType].Add(_FindARoleCard(Role.Loyalist));
                    game.AvailableRoles.Add(Role.Loyalist);
                }

                game.Shuffle(game.Decks[null, RoleDeckType]);

                if (game.IsClient)
                {
                    int count = game.Decks[null, RoleDeckType].Count;
                    game.Decks[null, RoleDeckType].Clear();
                    while (count-- > 0)
                    {
                        Card c = new Card(SuitType.None, 0, new UnknownRoleCardHandler());
                        c.Id = Card.UnknownRoleId;
                        c.Place = new DeckPlace(null, RoleDeckType);
                        game.Decks[null, RoleDeckType].Add(c);
                    }
                    game.SyncImmutableCardAll(game.Decks[null, RoleDeckType][0]);
                }
                else
                {
                    foreach (Card c in game.Decks[null, RoleDeckType])
                    {
                        c.Place = new DeckPlace(null, RoleDeckType);
                        if ((c.Type as RoleCardHandler).Role == Role.Ruler)
                        {
                            game.SyncImmutableCardAll(c);
                        }
                    }
                }

                int i = 0;
                for (i = 0; i < game.Players.Count; i++)
                {
                    game.SyncImmutableCard(game.Players[i], game.Decks[null, RoleDeckType][i]);
                }

                List<CardsMovement> moves = new List<CardsMovement>();
                i = 0;
                foreach (Player p in game.Players)
                {
                    CardsMovement move = new CardsMovement();
                    move.Cards = new List<Card>() { game.Decks[null, RoleDeckType][i] };
                    move.To = new DeckPlace(p, RoleDeckType);
                    moves.Add(move);
                    i++;
                }
                game.MoveCards(moves, null, GameDelays.GameStart);

                i = 0;
                foreach (Player player in game.Players)
                {
                    Card card = game.Decks[player, RoleDeckType][0];
                    var role = card.Type as RoleCardHandler;
                    if (role != null)
                    {
                        if (role.Role == Role.Ruler)
                        {
                            rulerId = i;
                        }
                        player.Role = role.Role;
                    }
                    i++;
                }

                GameDelays.Delay(GameDelays.RoleDistribute);

                game.NotificationProxy.NotifyLogEvent(new LogEvent("HerosInitialization"), new List<Player>());
                if (!game.IsClient) GameDelays.Delay(GameDelays.ServerSideCompensation);

                //hero allocation
                game.Shuffle(game.Decks[DeckType.Heroes]);
                if (!game.IsClient)
                {
                    foreach (var hero in new List<Card>(game.Decks[DeckType.Heroes]))
                    {
                        foreach (var s in (hero.Type as HeroCardHandler).Hero.Skills)
                        {
                            if (s.IsRulerOnly)
                            {
                                game.Decks[DeckType.Heroes].Remove(hero);
                                game.Decks[DeckType.Heroes].Insert(0, hero);
                            }
                        }
                    }
                }
                int numHeroes = Game.CurrentGame.Settings.DualHeroMode ? 2 : 1;
                List<Card> rulerDraw = new List<Card>();
                int toDraw = 12 + (Game.CurrentGame.Settings.DualHeroMode ? 3 : 0);
                for (int rc = 0; rc < toDraw; rc++)
                {
                    game.SyncImmutableCardAll(game.Decks[DeckType.Heroes][rc]);
                    rulerDraw.Add(game.Decks[DeckType.Heroes][rc]);
                }
                game.SyncImmutableCards(game.Players[rulerId], rulerDraw);
                DeckType tempHero = DeckType.Register("TempHero");
                game.Decks[null, tempHero].AddRange(rulerDraw);
                Trace.TraceInformation("Ruler is {0}", rulerId);
                game.Players[rulerId].Role = Role.Ruler;
                List<DeckPlace> sourceDecks = new List<DeckPlace>();
                sourceDecks.Add(new DeckPlace(null, tempHero));
                List<string> resultDeckNames = new List<string>();
                resultDeckNames.Add("HeroChoice");
                List<int> resultDeckMaximums = new List<int>();
                resultDeckMaximums.Add(numHeroes);
                List<List<Card>> answer;
                var newVer = new RequireCardsChoiceVerifier(numHeroes, false, true);
                if (numHeroes > 1) newVer.Helper.ExtraTimeOutSeconds = 10;
                if (!game.UiProxies[game.Players[rulerId]].AskForCardChoice(new CardChoicePrompt("RulerHeroChoice"), sourceDecks, resultDeckNames, resultDeckMaximums, newVer, out answer))
                {
                    answer = new List<List<Card>>();
                    answer.Add(new List<Card>());
                    answer[0].Add(game.Decks[DeckType.Heroes][0]);
                    if (Game.CurrentGame.Settings.DualHeroMode)
                    {
                        answer[0].Add(game.Decks[DeckType.Heroes][1]);
                    }
                }
                game.SyncImmutableCardAll(answer[0][0]);
                if (Game.CurrentGame.Settings.DualHeroMode)
                {
                    game.SyncImmutableCardAll(answer[0][1]);
                }
                game.Decks[DeckType.Heroes].Remove(answer[0][0]);
                if (Game.CurrentGame.Settings.DualHeroMode)
                {
                    game.Decks[DeckType.Heroes].Remove(answer[0][1]);
                }

                HeroCardHandler h = (HeroCardHandler)answer[0][0].Type;
                Trace.TraceInformation("Assign {0} to player {1}", h.Hero.Name, rulerId);
                Game.CurrentGame.Players[rulerId].Hero = h.Hero;
                Game.CurrentGame.Players[rulerId].Allegiance = h.Hero.Allegiance;
                Game.CurrentGame.Players[rulerId].IsMale = h.Hero.IsMale ? true : false;
                Game.CurrentGame.Players[rulerId].IsFemale = h.Hero.IsMale ? false : true;
                if (Game.CurrentGame.Settings.DualHeroMode)
                {
                    h = (HeroCardHandler)answer[0][1].Type;
                    var hero2 = h.Hero.Clone() as Hero;
                    Trace.TraceInformation("Assign {0} to player {1}", hero2.Name, rulerId);
                    Game.CurrentGame.Players[rulerId].Hero2 = hero2;
                }
                Game.CurrentGame.Players[rulerId].MaxHealth = Game.CurrentGame.Players[rulerId].Health = (game as RoleGame).GetMaxHealth(Game.CurrentGame.Players[rulerId]);

                int optionalHeros = game.Settings.NumHeroPicks;
                toDraw = optionalHeros + (Game.CurrentGame.Settings.DualHeroMode ? Math.Max(6 - optionalHeros, 0) : 0);
                game.Shuffle(game.Decks[DeckType.Heroes]);
                Dictionary<Player, List<Card>> restDraw = new Dictionary<Player, List<Card>>();
                List<Player> players = new List<Player>(game.Players);
                players.Remove(game.Players[rulerId]);
                int idx = 0;
                foreach (Player p in players)
                {
                    restDraw.Add(p, new List<Card>());
                    for (int n = 0; n < toDraw; n++)
                    {
                        game.SyncImmutableCard(p, game.Decks[DeckType.Heroes][idx]);
                        restDraw[p].Add(game.Decks[DeckType.Heroes][idx]);
                        idx++;
                    }
                }

                var heroSelection = new Dictionary<Player, List<Card>>();
                game.GlobalProxy.AskForHeroChoice(restDraw, heroSelection, numHeroes, newVer);

                bool notUsed = true;
                game.SyncConfirmationStatus(ref notUsed);

                foreach (var pxy in game.UiProxies)
                {
                    pxy.Value.Freeze();
                }

                List<Card> toRemove = new List<Card>();
                for (int repeat = 0; repeat < 2; repeat++)
                {
                    if (repeat == 1 && !Game.CurrentGame.Settings.DualHeroMode) break;
                    foreach (Player p in players)
                    {
                        Card c;
                        //only server has the result
                        if (!game.IsClient)
                        {
                            idx = repeat;
                            if (heroSelection.ContainsKey(p))
                            {
                                c = heroSelection[p][repeat];
                                idx = restDraw[p].IndexOf(c);
                            }
                            else
                            {
                                c = restDraw[p][idx];
                            }
                            if (game.GameServer != null)
                            {
                                foreach (Player player in game.Players)
                                {
                                    game.GameServer.SendPacket(player.Id, new StatusSync() { Status = idx });
                                }
                                game.GameServer.SendPacket(game.Players.Count, new StatusSync() { Status = idx });
                            }
                        }
                        // you are client
                        else
                        {
                            idx = (int)game.GameClient.Receive();
                            c = restDraw[p][idx];
                        }
                        game.SyncImmutableCardAll(c);
                        toRemove.Add(c);
                        h = (HeroCardHandler)c.Type;
                        Trace.TraceInformation("Assign {0} to player {1}", h.Hero.Name, p.Id);
                        var hero = h.Hero.Clone() as Hero;
                        foreach (var skill in new List<ISkill>(hero.Skills))
                        {
                            if (skill.IsRulerOnly)
                            {
                                hero.Skills.Remove(skill);
                            }
                        }
                        if (repeat == 1) p.Hero2 = hero;
                        else p.Hero = hero;
                        if (repeat == 0) p.Allegiance = hero.Allegiance;
                        if (repeat == 0)
                        {
                            p.MaxHealth = p.Health = hero.MaxHealth;
                            p.IsMale = hero.IsMale ? true : false;
                            p.IsFemale = hero.IsMale ? false : true;
                        }
                        if (repeat == 1)
                        {
                            int aveHp = (p.Hero2.MaxHealth + p.Hero.MaxHealth) / 2;
                            p.MaxHealth = p.Health = aveHp;
                        }

                    }
                }
                foreach (var card in toRemove)
                {
                    game.Decks[DeckType.Heroes].Remove(card);
                }

                if (game.IsClient)
                {
                    foreach (var card in game.Decks[DeckType.Heroes])
                    {
                        card.Type = new UnknownHeroCardHandler();
                        card.Id = Card.UnknownHeroId;
                    }
                }
                game.Shuffle(game.Decks[DeckType.Heroes]);

                foreach (var pxy in game.UiProxies)
                {
                    pxy.Value.Freeze();
                }

                //Heroes Convert and handle god hero
                var toCheck = new List<Player>(game.Players);
                game.SortByOrderOfComputation(game.Players[rulerId], toCheck);
                Dictionary<string, List<Card>> convertibleHeroes = new Dictionary<string, List<Card>>();
                game.SyncImmutableCardsAll(game.Decks[DeckType.SpecialHeroes]);
                foreach (Card card in game.Decks[DeckType.SpecialHeroes])
                {
                    var hero = (card.Type as HeroCardHandler).Hero.HeroConvertFrom;
                    if (!convertibleHeroes.Keys.Contains(hero)) convertibleHeroes[hero] = new List<Card>();
                    convertibleHeroes[hero].Add(card);
                }
                foreach (var p in toCheck)
                {
                    bool changeHero = false;
                    for (int heroIndex = 0; heroIndex < 2; heroIndex++)
                    {
                        if (heroIndex == 1 && !Game.CurrentGame.Settings.DualHeroMode) break;
                        Hero playerHero = heroIndex == 0 ? p.Hero : p.Hero2;
                        if (convertibleHeroes.Keys.Contains(playerHero.Name))
                        {
                            DeckType tempSpHeroes = DeckType.Register("tempSpHeroes");
                            DeckPlace heroesConvert = new DeckPlace(p, tempSpHeroes);
                            game.Decks[heroesConvert].AddRange(convertibleHeroes[playerHero.Name]);
                            List<List<Card>> choice;
                            AdditionalCardChoiceOptions options = new AdditionalCardChoiceOptions();
                            options.IsCancellable = true;
                            if (p.AskForCardChoice(new CardChoicePrompt("HeroesConvert", p),
                                new List<DeckPlace>() { heroesConvert },
                                new List<string>() { "convert" },
                                new List<int>() { 1 },
                                new RequireOneCardChoiceVerifier(false, true),
                                out choice,
                                options))
                            {
                                foreach (var sk in playerHero.Skills)
                                {
                                    sk.Owner = null;
                                }
                                Hero hero = ((choice[0][0].Type as HeroCardHandler).Hero.Clone()) as Hero;
                                foreach (var skill in new List<ISkill>(hero.Skills))
                                {
                                    if (skill.IsRulerOnly && (p.Role != Role.Ruler || heroIndex == 1))
                                    {
                                        hero.Skills.Remove(skill);
                                    }
                                }
                                if (heroIndex == 0)
                                {
                                    p.Hero = hero;
                                    p.Allegiance = hero.Allegiance;
                                    p.IsMale = hero.IsMale ? true : false;
                                    p.IsFemale = hero.IsMale ? false : true;
                                }
                                else p.Hero2 = hero;
                                changeHero = true;
                                game.Emit(GameEvent.PlayerChangedHero, new GameEventArgs() { Source = p });
                            }
                            game.Decks[heroesConvert].Clear();
                        }
                    }
                    if (changeHero) p.MaxHealth = p.Health = (game as RoleGame).GetMaxHealth(p);
                    Game.CurrentGame.HandleGodHero(p);
                }

                game.Shuffle(game.Decks[null, DeckType.Dealing]);

                Player current = game.CurrentPlayer = game.Players[rulerId];

                GameDelays.Delay(GameDelays.GameBeforeStart);
                StartGameDeal(game);

                Game.CurrentGame.NotificationProxy.NotifyGameStart();
                GameDelays.Delay(GameDelays.GameStart);
                GameDelays.Delay(GameDelays.GameStart);

                foreach (var act in game.AlivePlayers)
                {
                    game.Emit(GameEvent.PlayerGameStartAction, new GameEventArgs() { Source = act });
                }

                while (true)
                {
                    GameEventArgs args = new GameEventArgs();
                    args.Source = current;
                    game.CurrentPhaseEventIndex = 0;
                    game.CurrentPhase = TurnPhase.BeforeStart;
                    game.CurrentPlayer = current;
                    game.Emit(GameEvent.DoPlayer, args);
                    current = game.NextAlivePlayer(current);
                }
            }