public int FlipCoins(int coins) { int heads; if (forcedFlips.Count > 0) { heads = 0; while (forcedFlips.Count > 0) { if (forcedFlips.Dequeue()) { heads++; } } } else { heads = CoinFlipper.FlipCoins(coins); } GameLog?.AddMessage($"Flips {coins} coins and gets {heads} heads"); var results = new List <bool>(); for (int i = 0; i < heads; i++) { results.Add(true); } for (int i = 0; i < coins - heads; i++) { results.Add(false); } SendEventToPlayers(new CoinsFlippedEvent(results)); LastCoinFlipResult = heads > 0; LastCoinFlipHeadCount = heads; return(heads); }
private void PlayStadiumCard(TrainerCard trainerCard) { trainerCard.RevealToAll(); CurrentTrainerCard = trainerCard; TriggerAllAbilitiesOfType(TriggerType.TrainerCardPlayed); GameLog.AddMessage(ActivePlayer.NetworkPlayer?.Name + " Plays " + trainerCard.GetName()); PushGameLogUpdatesToPlayers(); ActivePlayer.Hand.Remove(trainerCard); var trainerEvent = new StadiumCardPlayedEvent() { Card = trainerCard, Player = ActivePlayer.Id }; SendEventToPlayers(trainerEvent); trainerCard.Process(this, ActivePlayer, NonActivePlayer); if (StadiumCard != null) { StadiumCard.Owner.DiscardPile.Add(StadiumCard); } StadiumCard = trainerCard; CurrentTrainerCard = null; if (ActivePlayer.IsDead) { GameLog.AddMessage($"{ActivePlayer.NetworkPlayer?.Name} loses because they drew to many cards"); EndGame(NonActivePlayer.Id); } SendEventToPlayers(new GameInfoEvent { }); }
private void CheckDeadBenchedPokemon(Player player) { var opponent = GetOpponentOf(player); var killedPokemons = new List <PokemonCard>(); foreach (PokemonCard pokemon in player.BenchedPokemon.ValidPokemonCards) { if (pokemon == null || !pokemon.IsDead()) { continue; } SendEventToPlayers(new PokemonDiedEvent { Pokemon = pokemon }); killedPokemons.Add(pokemon); TriggerAbilityOfType(TriggerType.Dies, pokemon); if (opponent.PrizeCards.Count <= 1 && pokemon.PrizeCards > 0) { GameLog.AddMessage(opponent.NetworkPlayer?.Name + " wins the game"); EndGame(opponent.Id); return; } else { PushInfoToPlayer("Opponent is selecting a prize card", player); opponent.SelectPrizeCard(pokemon.PrizeCards, this); } } foreach (var pokemon in killedPokemons) { player.KillBenchedPokemon(pokemon); } }
private void CheckDeadPokemon() { if (IsDraw()) { GameLog.AddMessage("It's a draw!"); EndGame(Id); return; } CheckDeadBenchedPokemon(NonActivePlayer); CheckDeadBenchedPokemon(ActivePlayer); if (NonActivePlayer.ActivePokemonCard != null && NonActivePlayer.ActivePokemonCard.IsDead()) { GameLog.AddMessage(NonActivePlayer.ActivePokemonCard.GetName() + " Dies"); NonActivePlayer.ActivePokemonCard.KnockedOutBy = ActivePlayer.ActivePokemonCard; SendEventToPlayers(new PokemonDiedEvent { Pokemon = NonActivePlayer.ActivePokemonCard }); TriggerAbilityOfType(TriggerType.Dies, NonActivePlayer.ActivePokemonCard); TriggerAbilityOfType(TriggerType.Kills, ActivePlayer.ActivePokemonCard); NonActivePlayer.ActivePokemonCard.KnockedOutBy = ActivePlayer.ActivePokemonCard; PushGameLogUpdatesToPlayers(); if (ActivePlayer.PrizeCards.Count == 1 && NonActivePlayer.ActivePokemonCard.PrizeCards > 0) { GameLog.AddMessage(NonActivePlayer.NetworkPlayer?.Name + $" has no pokémon left, {ActivePlayer.NetworkPlayer?.Name} wins the game"); EndGame(ActivePlayer.Id); return; } else if (NonActivePlayer.BenchedPokemon.Count == 0) { GameLog.AddMessage(ActivePlayer.NetworkPlayer?.Name + " wins the game"); EndGame(ActivePlayer.Id); return; } else { PushInfoToPlayer("Opponent is selecting a prize card", NonActivePlayer); ActivePlayer.SelectPrizeCard(NonActivePlayer.ActivePokemonCard.PrizeCards, this); } NonActivePlayer.KillActivePokemon(); if (NonActivePlayer.BenchedPokemon.Count > 0) { PushInfoToPlayer("Opponent is selecting a new active Pokémon", ActivePlayer); NonActivePlayer.SelectActiveFromBench(this); } else { GameLog.AddMessage(NonActivePlayer.NetworkPlayer?.Name + $" has no pokémon left, {ActivePlayer.NetworkPlayer?.Name} wins the game"); EndGame(ActivePlayer.Id); return; } } PushGameLogUpdatesToPlayers(); if (ActivePlayer.ActivePokemonCard != null && ActivePlayer.ActivePokemonCard.IsDead()) { GameLog.AddMessage(ActivePlayer.ActivePokemonCard.GetName() + "Dies"); SendEventToPlayers(new PokemonDiedEvent { Pokemon = ActivePlayer.ActivePokemonCard }); TriggerAbilityOfType(TriggerType.Dies, ActivePlayer.ActivePokemonCard); var prizeCardValue = ActivePlayer.ActivePokemonCard.PrizeCards; ActivePlayer.ActivePokemonCard.KnockedOutBy = NonActivePlayer.ActivePokemonCard; ActivePlayer.KillActivePokemon(); if (ActivePlayer.BenchedPokemon.Count > 0) { PushInfoToPlayer("Opponent is selecting a prize card", ActivePlayer); NonActivePlayer.SelectPrizeCard(prizeCardValue, this); PushInfoToPlayer("Opponent is selecting a new active Pokémon", NonActivePlayer); ActivePlayer.SelectActiveFromBench(this); } else { GameLog.AddMessage(ActivePlayer.NetworkPlayer?.Name + $" has no pokémon left, {NonActivePlayer.NetworkPlayer?.Name} wins the game"); EndGame(NonActivePlayer.Id); return; } } PushGameLogUpdatesToPlayers(); }
public void PlayTrainerCard(TrainerCard trainerCard, Player asPlayer = null) { var caster = asPlayer == null ? ActivePlayer : asPlayer; var opponent = GetOpponentOf(caster); if (asPlayer == null && !caster.Hand.Contains(trainerCard)) { GameLog.AddMessage($"{ActivePlayer?.NetworkPlayer?.Name} Tried to play a trainer ({trainerCard.Name}) card not in his hand"); return; } if (GetAllPassiveAbilities().Any(ability => ability.ModifierType == PassiveModifierType.StopTrainerCast)) { GameLog.AddMessage($"{trainerCard.Name} stopped by ability"); return; } else if (!trainerCard.CanCast(this, caster, opponent)) { GameLog.AddMessage($"{trainerCard.Name} could not be cast because something is missing"); return; } if (trainerCard.IsStadium()) { PlayStadiumCard(trainerCard); return; } trainerCard.RevealToAll(); CurrentTrainerCard = trainerCard; TriggerAllAbilitiesOfType(TriggerType.TrainerCardPlayed); GameLog.AddMessage(caster.NetworkPlayer?.Name + " Plays " + trainerCard.GetName()); PushGameLogUpdatesToPlayers(); caster.Hand.Remove(trainerCard); var trainerEvent = new TrainerCardPlayed() { Card = trainerCard, Player = caster.Id }; SendEventToPlayers(trainerEvent); trainerCard.Process(this, caster, opponent); if (trainerCard.AddToDiscardWhenCasting) { trainerCard.Owner.DiscardPile.Add(trainerCard); } CurrentTrainerCard = null; if (caster.IsDead) { GameLog.AddMessage($"{caster.NetworkPlayer?.Name} loses because they drew to many cards"); EndGame(opponent.Id); } SendEventToPlayers(new GameInfoEvent { }); }
public void Attack(Attack attack) { if (attack.Disabled || !attack.CanBeUsed(this, ActivePlayer, NonActivePlayer) || !ActivePlayer.ActivePokemonCard.CanAttack() || !ActivePlayer.ActivePokemonCard.Attacks.Contains(attack)) { GameLog.AddMessage($"Attack not used because FirstTurn: {FirstTurn} or Disabled: {attack.Disabled} or CanBeUsed:{attack.CanBeUsed(this, ActivePlayer, NonActivePlayer)}"); PushGameLogUpdatesToPlayers(); return; } GameState = GameFieldState.Attacking; GameLog.AddMessage($"{ActivePlayer.NetworkPlayer?.Name} activates attack {attack.Name}"); attack.PayExtraCosts(this, ActivePlayer, NonActivePlayer); CurrentDefender = NonActivePlayer.ActivePokemonCard; if (ActivePlayer.ActivePokemonCard.IsConfused && FlipCoins(1) == 0) { HitItselfInConfusion(); if (!IgnorePostAttack) { PostAttack(); } return; } SendEventToPlayers(new PokemonAttackedEvent() { Player = ActivePlayer.Id }); ActivePlayer.ActivePokemonCard.LastAttackUsed = attack; TriggerAbilityOfType(TriggerType.Attacks, ActivePlayer.ActivePokemonCard); TriggerAbilityOfType(TriggerType.Attacked, NonActivePlayer.ActivePokemonCard); var abilities = new List <Ability>(); abilities.AddRange(NonActivePlayer.ActivePokemonCard.GetAllActiveAbilities(this, NonActivePlayer, ActivePlayer)); abilities.AddRange(ActivePlayer.ActivePokemonCard.GetAllActiveAbilities(this, NonActivePlayer, ActivePlayer)); foreach (var ability in abilities.OfType <IAttackStoppingAbility>()) { if (ability.IsStopped(this, ActivePlayer.ActivePokemonCard, NonActivePlayer.ActivePokemonCard)) { if (!IgnorePostAttack) { PostAttack(); } return; } } DealDamageWithAttack(attack); attack.ProcessEffects(this, ActivePlayer, NonActivePlayer); CurrentDefender = null; GameState = GameFieldState.PostAttack; if (!IgnorePostAttack) { PostAttack(); } }
public void OnActivePokemonSelected(NetworkId ownerId, PokemonCard activePokemon) { Player owner = Players.First(p => p.Id.Equals(ownerId)); if (GameState != GameFieldState.BothSelectingActive) { if (!ActivePlayer.Id.Equals(ownerId)) { GameLog.AddMessage($"{owner?.NetworkPlayer?.Name} tried to play a pokemon when not allowed"); return; } } if (activePokemon.Stage == 0) { GameLog.AddMessage($"{owner.NetworkPlayer?.Name} is setting {activePokemon.GetName()} as active"); owner.SetActivePokemon(activePokemon); if (GameState != GameFieldState.BothSelectingActive) { SendEventToPlayers(new PokemonBecameActiveEvent { NewActivePokemon = activePokemon }); } } else { return; } lock (lockObject) { if (GameState == GameFieldState.BothSelectingActive) { if (!owner.Hand.OfType <PokemonCard>().Any(card => card.Stage == 0)) { playersSetStartBench.Add(owner.Id); } if (Players.All(p => p.ActivePokemonCard != null)) { if (playersSetStartBench.Count == 2) { foreach (var player in Players) { player.SetPrizeCards(PrizeCardCount); } GameState = GameFieldState.InTurn; SendEventToPlayers(new GameSyncEvent { Game = this }); } else { GameState = GameFieldState.BothSelectingBench; SendEventToPlayers(new GameSyncEvent { Game = this, Info = "Select Pokémons to add to your starting bench" }); return; } } else { PushInfoToPlayer("Opponent is selecting active...", owner); } SendEventMessage(new GameSyncEvent { Game = this }, Players.First(x => x.Id.Equals(ownerId))); } } PushGameLogUpdatesToPlayers(); }