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);
}
}