// Choose a target for this effect, and then spawn a specific effect and process it public override void Process(Game game) { int amountToGain = this.amountToGain_provider.GetValue(this, game, default(int)); IList <Readable_LifeTarget> availableTargets = this.targetsProvider.GetValue(this, game, (IList <Readable_LifeTarget>)null); // multiple choices of what to heal/damage, so ask the player what to do List <GameEffect> options = new List <GameEffect>(); foreach (Readable_LifeTarget target in availableTargets) { options.Add(new Specific_LifeEffect(target.GetID((Readable_LifeTarget)null), amountToGain)); } if (this.affectAll) { foreach (GameEffect option in options) { option.Process(game); } } else { if (options.Count == 0 || !this.TargetRequired) { options.Add(new EmptyEffect()); } // ask the game to choose one of these options Readable_GamePlayer controller = this.chooserProvider.GetValue(this, game, (Readable_GamePlayer)null); game.AddChoice(new GameChoice(options, controller.GetID((Readable_GamePlayer)null))); } }
public void AddPlayer(Readable_GamePlayer player) { WriteControlled_Item <Readable_GamePlayer, Writable_GamePlayer> playerPair = new WriteControlled_Item <Readable_GamePlayer, Writable_GamePlayer>(new PlayerConverter()); playerPair.PutReadonly(player); this.players.PutReadonly(player); this.TurnOrder.AddLast(player.GetID((Readable_GamePlayer)null)); }
public void CopyFrom(Readable_GamePlayer original) { // the hand should be small enough that we can just clone it for the moment this.hand.PutReadonly(original.Get_ReadableHand()); this.Deck = original.GetDeck().Clone(); this.Health = original.GetHealth(); this.MaxHealth = original.GetMaxHealth(); this.NumDrawsSkipped = original.Get_NumDrawsSkipped(); this.sourcePlayer = original.SourcePlayer; this.ID = original.GetID((Readable_GamePlayer)null).ToInt(); this.MonsterIDsInPlay = new WriteControlled_Item <IReadOnlyList <ID <Readable_MonsterCard> >, List <ID <Readable_MonsterCard> > >(new ListConverter <ID <Readable_MonsterCard> >()); this.MonsterIDsInPlay.PutReadonly(original.Get_MonsterIDsInPlay()); this.CurrentResources = original.Get_CurrentResources(); this.ResourcesPerTurn = original.Get_ResourcesPerTurn(); }
public GameChoice Get_NextChoice() { if (this.pendingEffects.Count > 0) { // a previous effect still requires a player to make a choice, so that must be done before moving on to normal options (like playing more cards, attacking, or ending the turn) GameChoice choice = this.pendingEffects.First(); this.pendingEffects.RemoveFirst(); return(choice); } // There aren't any effects still requiring user input, so now the active player can choose on of the usual choices (playing a card, attacking, ending the turn or whatever) Readable_GamePlayer activePlayer = this.ActivePlayer; return(new GameChoice(this.Referee.Get_AvailableGameActions(this, activePlayer), activePlayer.GetID((Readable_GamePlayer)null))); }
public List <GameEffect> Get_AvailableGameActions(Game game, Readable_GamePlayer player) { // This function only gets called when there are no effects in progress (like choosing the target of a triggered effect). List <GameEffect> options = new List <GameEffect>(); // So, a player has these types of options: 1. Play a card. 2. Attack with a monster. 3. Activate their special ability. 4. End their turn // Let the player play any card foreach (ID <ReadableCard> cardId in player.Get_ReadableHand()) { ReadableCard card = game.Get_ReadableSnapshot(cardId); if (card.IsPlayable(game)) { options.Add(new PlayCard_Effect(card.GetID((ReadableCard)null))); } } // Let the player attack with any monster IEnumerable <ID <Readable_MonsterCard> > availableAttacker_IDs = player.Get_MonsterIDsInPlay(); // first figure out which monsters can be attacked (if any monsters have Taunt, they are the only ones that may be attacked) foreach (ID <Readable_GamePlayer> playerId in game.TurnOrder) { // make sure this is a different player if (!playerId.Equals(player.GetID((Readable_GamePlayer)null))) { LinkedList <ID <Readable_LifeTarget> > requiredTarget_IDs = new LinkedList <ID <Readable_LifeTarget> >(); LinkedList <ID <Readable_LifeTarget> > allTarget_Ids = new LinkedList <ID <Readable_LifeTarget> >(); Readable_GamePlayer controller = game.Get_ReadableSnapshot(playerId); foreach (ID <Readable_MonsterCard> monsterId in controller.Get_MonsterIDsInPlay()) { Readable_MonsterCard monster = game.Get_ReadableSnapshot(monsterId); ID <Readable_LifeTarget> convertedID = monster.GetID((Readable_LifeTarget)null); allTarget_Ids.AddLast(convertedID); if (monster.Get_MustBeAttacked()) { requiredTarget_IDs.AddLast(convertedID); } } if (requiredTarget_IDs.Count != 0) { // There is a monster with taunt, so the only valid targets are the monsters with taunt allTarget_Ids = requiredTarget_IDs; } else { // There are no monsters with taunt, so the valid targets are all monsters and the opponent too allTarget_Ids.AddLast(controller.GetID((Readable_LifeTarget)null)); } // Now allow each monster to attack each available target foreach (ID <Readable_MonsterCard> attackerId in availableAttacker_IDs) { if (game.Get_ReadableSnapshot(attackerId).Get_CanAttack()) { foreach (ID <Readable_LifeTarget> targetId in allTarget_Ids) { options.Add(new AttackEffect(attackerId.AsType((Readable_LifeTarget)null), targetId)); } } } } } // Let the player end their turn options.Add(new EndTurn_Effect(player.GetID((Readable_GamePlayer)null))); return(options); }