From 3197e9f537da462b95e0fad2114e4e03b4984d35 Mon Sep 17 00:00:00 2001 From: MarcinSc Date: Thu, 16 May 2024 18:49:29 +0700 Subject: [PATCH] Migrated Gandalf cards in set 10 to hjson --- .../lotro/cards/set10/gandalf/Card10_014.java | 85 ----------- .../lotro/cards/set10/gandalf/Card10_015.java | 50 ------- .../lotro/cards/set10/gandalf/Card10_016.java | 54 ------- .../lotro/cards/set10/gandalf/Card10_017.java | 51 ------- .../lotro/cards/set10/gandalf/Card10_018.java | 67 --------- .../official/set10}/set10-Gandalf.hjson | 139 ++++++++++++------ .../cards/unofficial/pc/setV01/V1_elven.hjson | 9 +- .../field/effect/EffectAppenderFactory.java | 2 + .../field/effect/appender/ChooseAndHeal.java | 20 +-- ...xchangeCardsInHandWithCardsInDeadPile.java | 77 ++++++++++ ...ExchangeCardsInHandWithCardsInDiscard.java | 75 ++++++++++ .../PutCardsFromHandOnBottomOfDeck.java | 11 +- 12 files changed, 260 insertions(+), 380 deletions(-) delete mode 100644 gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_014.java delete mode 100644 gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_015.java delete mode 100644 gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_016.java delete mode 100644 gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_017.java delete mode 100644 gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_018.java rename gemp-lotr/gemp-lotr-cards/src/main/resources/{card-stubs => cards/official/set10}/set10-Gandalf.hjson (64%) create mode 100644 gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ExchangeCardsInHandWithCardsInDeadPile.java create mode 100644 gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ExchangeCardsInHandWithCardsInDiscard.java diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_014.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_014.java deleted file mode 100644 index 07b92bacc..000000000 --- a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_014.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.gempukku.lotro.cards.set10.gandalf; - -import com.gempukku.lotro.common.*; -import com.gempukku.lotro.filters.Filters; -import com.gempukku.lotro.game.PhysicalCard; -import com.gempukku.lotro.game.state.LotroGame; -import com.gempukku.lotro.logic.GameUtils; -import com.gempukku.lotro.logic.actions.PlayEventAction; -import com.gempukku.lotro.logic.cardtype.AbstractEvent; -import com.gempukku.lotro.logic.effects.ChoiceEffect; -import com.gempukku.lotro.logic.effects.choose.ChooseCardsFromDeadPileEffect; -import com.gempukku.lotro.logic.effects.choose.ChooseCardsFromDiscardEffect; -import com.gempukku.lotro.logic.effects.choose.ChooseCardsFromHandEffect; -import com.gempukku.lotro.logic.timing.Effect; -import com.gempukku.lotro.logic.timing.PlayConditions; - -import java.util.*; - -/** - * Set: Mount Doom - * Side: Free - * Culture: Gandalf - * Twilight Cost: 1 - * Type: Event • Fellowship - * Game Text: Spot your Wizard to exchange a companion in hand with a companion in your dead pile or discard pile. - */ -public class Card10_014 extends AbstractEvent { - public Card10_014() { - super(Side.FREE_PEOPLE, 1, Culture.GANDALF, "Borne Far Away", Phase.FELLOWSHIP); - } - - @Override - public boolean checkPlayRequirements(LotroGame game, PhysicalCard self) { - return PlayConditions.canSpot(game, Filters.owner(self.getOwner()), Race.WIZARD); - } - - @Override - public PlayEventAction getPlayEventCardAction(final String playerId, LotroGame game, final PhysicalCard self) { - final PlayEventAction action = new PlayEventAction(self); - action.appendEffect( - new ChooseCardsFromHandEffect(playerId, 1, 1, CardType.COMPANION) { - @Override - protected void cardsSelected(LotroGame game, Collection selectedCards) { - for (final PhysicalCard cardInHand : selectedCards) { - List possibleEffects = new LinkedList<>(); - possibleEffects.add( - new ChooseCardsFromDiscardEffect(playerId, 1, 1, CardType.COMPANION) { - @Override - protected void cardsSelected(LotroGame game, Collection cards) { - for (PhysicalCard cardInDiscard : cards) { - Set cardsToRemove = new HashSet<>(); - cardsToRemove.add(cardInHand); - cardsToRemove.add(cardInDiscard); - - game.getGameState().sendMessage(playerId + " exchanges " + GameUtils.getCardLink(cardInDiscard) + " from discard with " + GameUtils.getCardLink(cardInHand) + " in hand"); - game.getGameState().removeCardsFromZone(playerId, cardsToRemove); - game.getGameState().addCardToZone(game, cardInDiscard, Zone.HAND); - game.getGameState().addCardToZone(game, cardInHand, Zone.DISCARD); - } - } - }); - possibleEffects.add( - new ChooseCardsFromDeadPileEffect(playerId, 1, 1, CardType.COMPANION) { - @Override - protected void cardsSelected(LotroGame game, Collection cards) { - for (PhysicalCard cardInDeadPile : cards) { - Set cardsToRemove = new HashSet<>(); - cardsToRemove.add(cardInHand); - cardsToRemove.add(cardInDeadPile); - - game.getGameState().sendMessage(playerId + " exchanges " + GameUtils.getCardLink(cardInDeadPile) + " from dead pile with " + GameUtils.getCardLink(cardInHand) + " in hand"); - game.getGameState().removeCardsFromZone(playerId, cardsToRemove); - game.getGameState().addCardToZone(game, cardInDeadPile, Zone.HAND); - game.getGameState().addCardToZone(game, cardInHand, Zone.DEAD); - } - } - }); - action.appendEffect( - new ChoiceEffect(action, playerId, possibleEffects)); - } - } - }); - return action; - } -} diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_015.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_015.java deleted file mode 100644 index 14a82cebd..000000000 --- a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_015.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.gempukku.lotro.cards.set10.gandalf; - -import com.gempukku.lotro.logic.cardtype.AbstractPermanent; -import com.gempukku.lotro.logic.timing.PlayConditions; -import com.gempukku.lotro.logic.timing.TriggerConditions; -import com.gempukku.lotro.logic.effects.choose.ChooseAndDiscardCardsFromPlayEffect; -import com.gempukku.lotro.logic.effects.choose.ChooseOpponentEffect; -import com.gempukku.lotro.common.*; -import com.gempukku.lotro.filters.Filters; -import com.gempukku.lotro.game.PhysicalCard; -import com.gempukku.lotro.game.state.LotroGame; -import com.gempukku.lotro.logic.actions.OptionalTriggerAction; -import com.gempukku.lotro.logic.timing.EffectResult; - -import java.util.Collections; -import java.util.List; - -/** - * Set: Mount Doom - * Side: Free - * Culture: Gandalf - * Twilight Cost: 1 - * Type: Condition • Support Area - * Game Text: Each time you lose initiative (except during the fellowship phase), you may spot a [GANDALF] companion - * to choose an opponent who must discard one of his or her conditions. - */ -public class Card10_015 extends AbstractPermanent { - public Card10_015() { - super(Side.FREE_PEOPLE, 1, CardType.CONDITION, Culture.GANDALF, "Brooding on Tomorrow", null, true); - } - - @Override - public List getOptionalAfterTriggers(String playerId, LotroGame game, EffectResult effectResult, PhysicalCard self) { - if (TriggerConditions.losesInitiative(effectResult, Side.FREE_PEOPLE) - && game.getGameState().getCurrentPhase() != Phase.FELLOWSHIP - && PlayConditions.canSpot(game, Culture.GANDALF, CardType.COMPANION)) { - final OptionalTriggerAction action = new OptionalTriggerAction(self); - action.appendEffect( - new ChooseOpponentEffect(playerId) { - @Override - protected void opponentChosen(String opponentId) { - action.appendEffect( - new ChooseAndDiscardCardsFromPlayEffect(action, opponentId, 1, 1, Filters.owner(opponentId), CardType.CONDITION)); - } - }); - return Collections.singletonList(action); - } - return null; - } -} diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_016.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_016.java deleted file mode 100644 index c39bc526c..000000000 --- a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_016.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.gempukku.lotro.cards.set10.gandalf; - -import com.gempukku.lotro.common.*; -import com.gempukku.lotro.filters.Filters; -import com.gempukku.lotro.game.PhysicalCard; -import com.gempukku.lotro.game.state.LotroGame; -import com.gempukku.lotro.logic.actions.PlayEventAction; -import com.gempukku.lotro.logic.cardtype.AbstractEvent; -import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; -import com.gempukku.lotro.logic.decisions.IntegerAwaitingDecision; -import com.gempukku.lotro.logic.effects.AddUntilStartOfPhaseModifierEffect; -import com.gempukku.lotro.logic.effects.PlayoutDecisionEffect; -import com.gempukku.lotro.logic.effects.choose.ChooseAndExertCharactersEffect; -import com.gempukku.lotro.logic.modifiers.StrengthModifier; -import com.gempukku.lotro.logic.timing.PlayConditions; - -/** - * Set: Mount Doom - * Side: Free - * Culture: Gandalf - * Twilight Cost: 2 - * Type: Event • Maneuver - * Game Text: Exert your Wizard and choose a number. Make each minion with that twilight cost strength -2 until - * the regroup phase. - */ -public class Card10_016 extends AbstractEvent { - public Card10_016() { - super(Side.FREE_PEOPLE, 2, Culture.GANDALF, "Gathering Wind", Phase.MANEUVER); - } - - @Override - public boolean checkPlayRequirements(LotroGame game, PhysicalCard self) { - return PlayConditions.canExert(self, game, Race.WIZARD); - } - - @Override - public PlayEventAction getPlayEventCardAction(String playerId, LotroGame game, final PhysicalCard self) { - final PlayEventAction action = new PlayEventAction(self); - action.appendCost( - new ChooseAndExertCharactersEffect(action, playerId, 1, 1, Filters.owner(playerId), Race.WIZARD)); - action.appendEffect( - new PlayoutDecisionEffect(playerId, - new IntegerAwaitingDecision(1, "Choose a number", 0) { - @Override - public void decisionMade(String result) throws DecisionResultInvalidException { - int twilightCost = getValidatedResult(result); - action.appendEffect( - new AddUntilStartOfPhaseModifierEffect( - new StrengthModifier(self, Filters.and(CardType.MINION, Filters.printedTwilightCost(twilightCost)), -2), Phase.REGROUP)); - } - })); - return action; - } -} diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_017.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_017.java deleted file mode 100644 index e192dcff7..000000000 --- a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_017.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.gempukku.lotro.cards.set10.gandalf; - -import com.gempukku.lotro.common.*; -import com.gempukku.lotro.filters.Filters; -import com.gempukku.lotro.game.PhysicalCard; -import com.gempukku.lotro.game.state.LotroGame; -import com.gempukku.lotro.logic.PlayUtils; -import com.gempukku.lotro.logic.actions.PlayEventAction; -import com.gempukku.lotro.logic.cardtype.AbstractResponseEvent; -import com.gempukku.lotro.logic.effects.DiscardCardsFromPlayEffect; -import com.gempukku.lotro.logic.effects.choose.ChooseAndExertCharactersEffect; -import com.gempukku.lotro.logic.timing.EffectResult; -import com.gempukku.lotro.logic.timing.PlayConditions; -import com.gempukku.lotro.logic.timing.TriggerConditions; - -import java.util.Collections; -import java.util.List; - -/** - * Set: Mount Doom - * Side: Free - * Culture: Gandalf - * Twilight Cost: 3 - * Type: Event • Response - * Game Text: If the fellowship moves during the regroup phase, exert your Wizard to discard each minion. - */ -public class Card10_017 extends AbstractResponseEvent { - public Card10_017() { - super(Side.FREE_PEOPLE, 3, Culture.GANDALF, "Out of the High Airs"); - } - - @Override - public boolean checkPlayRequirements(LotroGame game, PhysicalCard self) { - return PlayConditions.canExert(self, game, Filters.owner(self.getOwner()), Race.WIZARD); - } - - @Override - public List getPlayResponseEventAfterActions(String playerId, LotroGame game, EffectResult effectResult, PhysicalCard self) { - if (TriggerConditions.moves(game, effectResult) - && PlayUtils.checkPlayRequirements(game, self, Filters.any, 0, 0, false, false) - && game.getGameState().getCurrentPhase() == Phase.REGROUP) { - PlayEventAction action = new PlayEventAction(self); - action.appendCost( - new ChooseAndExertCharactersEffect(action, playerId, 1, 1, Filters.owner(playerId), Race.WIZARD)); - action.appendEffect( - new DiscardCardsFromPlayEffect(self.getOwner(), self, CardType.MINION)); - return Collections.singletonList(action); - } - return null; - } -} diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_018.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_018.java deleted file mode 100644 index 8c8bbf315..000000000 --- a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set10/gandalf/Card10_018.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.gempukku.lotro.cards.set10.gandalf; - -import com.gempukku.lotro.common.CardType; -import com.gempukku.lotro.common.Culture; -import com.gempukku.lotro.common.Phase; -import com.gempukku.lotro.common.Race; -import com.gempukku.lotro.filters.Filters; -import com.gempukku.lotro.game.PhysicalCard; -import com.gempukku.lotro.game.state.LotroGame; -import com.gempukku.lotro.logic.actions.ActivateCardAction; -import com.gempukku.lotro.logic.cardtype.AbstractCompanion; -import com.gempukku.lotro.logic.effects.SelfExertEffect; -import com.gempukku.lotro.logic.effects.choose.ChooseAndDiscardCardsFromPlayEffect; -import com.gempukku.lotro.logic.effects.choose.ChooseAndPlayCardFromDiscardEffect; -import com.gempukku.lotro.logic.effects.choose.ChooseOpponentEffect; -import com.gempukku.lotro.logic.timing.PlayConditions; - -import java.util.Collections; -import java.util.List; - -/** - * Set: Mount Doom - * Side: Free - * Culture: Gandalf - * Twilight Cost: 5 - * Type: Companion • Ent - * Strength: 12 - * Vitality: 4 - * Resistance: 6 - * Game Text: To play, spot 3 [GANDALF] companions. Regroup: Exert Treebeard twice to play a [GANDALF] condition from - * your discard pile and make an opponent discard one of his or her conditions. - */ -public class Card10_018 extends AbstractCompanion { - public Card10_018() { - super(5, 12, 4, 6, Culture.GANDALF, Race.ENT, null, "Treebeard", "Keeper of the Watchwood", true); - } - - @Override - public boolean checkPlayRequirements(LotroGame game, PhysicalCard self) { - return PlayConditions.canSpot(game, 3, Culture.GANDALF, CardType.COMPANION); - } - - @Override - public List getPhaseActionsInPlay(String playerId, LotroGame game, PhysicalCard self) { - if (PlayConditions.canUseFPCardDuringPhase(game, Phase.REGROUP, self) - && PlayConditions.canSelfExert(self, 2, game) - && PlayConditions.canPlayFromDiscard(playerId, game, Culture.GANDALF, CardType.CONDITION)) { - final ActivateCardAction action = new ActivateCardAction(self); - action.appendCost( - new SelfExertEffect(action, self)); - action.appendCost( - new SelfExertEffect(action, self)); - action.appendEffect( - new ChooseAndPlayCardFromDiscardEffect(playerId, game, Culture.GANDALF, CardType.CONDITION)); - action.appendEffect( - new ChooseOpponentEffect(playerId) { - @Override - protected void opponentChosen(String opponentId) { - action.appendEffect( - new ChooseAndDiscardCardsFromPlayEffect(action, opponentId, 1, 1, Filters.owner(opponentId), CardType.CONDITION)); - } - }); - return Collections.singletonList(action); - } - return null; - } -} diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/card-stubs/set10-Gandalf.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set10/set10-Gandalf.hjson similarity index 64% rename from gemp-lotr/gemp-lotr-cards/src/main/resources/card-stubs/set10-Gandalf.hjson rename to gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set10/set10-Gandalf.hjson index e4df0297d..7bda7ab69 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/card-stubs/set10-Gandalf.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set10/set10-Gandalf.hjson @@ -22,20 +22,31 @@ twilight: 1 type: Event keywords: Fellowship - /*requires: { - - } - */ effects: { type: event - cost: { - type: SendMessage - text: Placeholder effect for development. - }, + requires: { + type: canSpot + filter: your,wizard + } effect: [ { - type: SendMessage - text: Placeholder effect for development. + type: choice + texts: [ + Exchange with card in dead pile + Exchange with card in discard + ] + effects: [ + { + type: exchangeCardsInHandWithCardsInDeadPile + filterInHand: choose(companion) + filterInDeadPile: choose(companion) + } + { + type: exchangeCardsInHandWithCardsInDiscard + filterInHand: choose(companion) + filterInDiscard: choose(companion) + } + ] } ] } @@ -72,17 +83,25 @@ twilight: 1 type: Condition keywords: Support Area - /*requires: { - - } effects: [ - { - - } - { - - } - ]*/ + { + type: trigger + optional: true + trigger: { + type: losesInitiative + side: free people + } + requires: { + type: canSpot + filter: culture(gandalf),companion + } + effect: { + type: discard + player: shadow + filter: choose(side(shadow),condition) + } + } + ] gametext: Each time you lose initiative (except during the fellowship phase), you may spot a [gandalf] companion to choose an opponent who must discard one of his or her conditions. lore: ...tomorrow will be certain to bring worse than today, for many days to come.' promotext: "" @@ -116,20 +135,25 @@ twilight: 2 type: Event keywords: Maneuver - /*requires: { - - } - */ effects: { type: event cost: { - type: SendMessage - text: Placeholder effect for development. + type: exert + filter: choose(your,wizard) }, effect: [ { - type: SendMessage - text: Placeholder effect for development. + type: chooseANumber + text: Choose a minion cost + from: 0 + to: 100 + memorize: chosenNumber + } + { + type: modifyStrength + filter: all(minion,printedTwilightCostFromMemory(chosenNumber)) + amount: -2 + until: regroup } ] } @@ -166,26 +190,26 @@ twilight: 3 type: Event keywords: Response - /*requires: { - - } - */ effects: { type: responseEvent trigger: { - + type: moves + } + requires: { + type: phase + phase: regroup } cost: { - type: SendMessage - text: Placeholder effect for development. + type: exert + filter: choose(your,wizard) } effect: [ { - type: SendMessage - text: Placeholder effect for development. + type: discard + filter: all(minion) } ] - ] + } gametext: If the fellowship moves during the regroup phase, exert your Wizard to discard each minion. lore: ...the Nazgûl turned and fled, and vanished into Mordor's shadows.... promotext: "" @@ -223,17 +247,36 @@ strength: 12 vitality: 4 resistance: 6 - /*requires: { - - } effects: [ - { - - } - { - - } - ]*/ + { + type: toPlay + requires: { + type: canSpot + filter: culture(gandalf),companion + count: 3 + } + } + { + type: activated + phase: regroup + cost: { + type: exert + filter: self + times: 2 + } + effect: [ + { + type: playCardFromDiscard + filter: choose(culture(gandalf),condition) + } + { + type: discard + player: shadow + filter: choose(side(shadow),condition) + } + ] + } + ] gametext: To play, spot 3 [gandalf] companions.
Regroup: Exert Treebeard twice to play a [gandalf] condition from your discard pile and make an opponent discard one of his or her conditions. lore: Leave it to the Ents!... Trees are coming back to live here, old trees, wild trees.' promotext: "" diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV01/V1_elven.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV01/V1_elven.hjson index 73bc43a76..d97bdd785 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV01/V1_elven.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV01/V1_elven.hjson @@ -340,11 +340,14 @@ } { type: chooseAndHeal - optional: true filter: companion count: { - type: fromMemory - memory: stackedCultures + type: range + from: 0 + to: { + type: fromMemory + memory: stackedCultures + } } } { diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/EffectAppenderFactory.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/EffectAppenderFactory.java index c1aa23b0e..71422abe3 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/EffectAppenderFactory.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/EffectAppenderFactory.java @@ -67,6 +67,8 @@ public class EffectAppenderFactory { effectAppenderProducers.put("enableparticipationinarcheryfireandskirmishes", new EnableParticipationInArcheryFireAndSkirmishes()); effectAppenderProducers.put("enableparticipationinskirmishes", new EnableParticipationInSkirmishes()); effectAppenderProducers.put("endphase", new EndPhase()); + effectAppenderProducers.put("exchangecardsinhandwithcardsindeadpile", new ExchangeCardsInHandWithCardsInDeadPile()); + effectAppenderProducers.put("exchangecardsinhandwithcardsindiscard", new ExchangeCardsInHandWithCardsInDiscard()); effectAppenderProducers.put("exert", new Exert()); effectAppenderProducers.put("exhaust", new Exhaust()); effectAppenderProducers.put("filtercardsinmemory", new FilterCardsInMemory()); diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ChooseAndHeal.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ChooseAndHeal.java index f15b51498..9073295f3 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ChooseAndHeal.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ChooseAndHeal.java @@ -6,44 +6,38 @@ import com.gempukku.lotro.cards.build.field.effect.EffectAppender; import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer; import com.gempukku.lotro.cards.build.field.effect.appender.resolver.PlayerResolver; import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver; -import com.gempukku.lotro.game.PhysicalCard; import com.gempukku.lotro.logic.actions.CostToEffectAction; import com.gempukku.lotro.logic.effects.ChooseAndHealCharactersEffect; import com.gempukku.lotro.logic.timing.Effect; import org.json.simple.JSONObject; -import java.util.Collection; import java.util.LinkedList; import java.util.List; public class ChooseAndHeal implements EffectAppenderProducer { @Override public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { - FieldUtils.validateAllowedFields(effectObject, "count", "optional", "filter", "player"); + FieldUtils.validateAllowedFields(effectObject, "count", "filter", "player"); final ValueSource count = ValueResolver.resolveEvaluator(effectObject.get("count"), 1, environment); - final boolean optional = FieldUtils.getBoolean(effectObject.get("optional"), "optional", false); - final int min = optional ? 0 : 1; final String filter = FieldUtils.getString(effectObject.get("filter"), "filter"); final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment); final String player = FieldUtils.getString(effectObject.get("player"), "player", "you"); final PlayerSource playerSource = PlayerResolver.resolvePlayer(player, environment); - //Might implement this later - final String memory = FieldUtils.getString(effectObject.get("memorize"), "memorize", "_temp"); - DelayedAppender result = new DelayedAppender() { @Override protected List createEffects(boolean cost, CostToEffectAction action, ActionContext actionContext) { - final Collection cardsFromMemory = actionContext.getCardsFromMemory(memory); List result = new LinkedList<>(); - final int healCount = count.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null); - for (int i = 0; i < healCount; i++) { - final int remainingHeals = healCount - i; + final int maxHealCount = count.getMaximum(actionContext); + final int minHealCount = count.getMinimum(actionContext); + for (int i = 0; i < maxHealCount; i++) { + final int remainingHeals = maxHealCount - i; //If the healing is optional (like sanctuary healing, an implied "up to" the maximum), then the minimum // is set to 0, otherwise 1 (as in, the player /must/ choose a character to heal). + int min = (i < minHealCount) ? 1 : 0; ChooseAndHealCharactersEffect healEffect = new ChooseAndHealCharactersEffect(action, playerSource.getPlayer(actionContext), - min, 1, filterableSource.getFilterable(actionContext)); + min, 1, filterableSource.getFilterable(actionContext)); healEffect.setChoiceText("Choose card to heal - remaining heals: " + remainingHeals); result.add(healEffect); } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ExchangeCardsInHandWithCardsInDeadPile.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ExchangeCardsInHandWithCardsInDeadPile.java new file mode 100644 index 000000000..5b3b41d07 --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ExchangeCardsInHandWithCardsInDeadPile.java @@ -0,0 +1,77 @@ +package com.gempukku.lotro.cards.build.field.effect.appender; + +import com.gempukku.lotro.cards.build.ActionContext; +import com.gempukku.lotro.cards.build.CardGenerationEnvironment; +import com.gempukku.lotro.cards.build.InvalidCardDefinitionException; +import com.gempukku.lotro.cards.build.ValueSource; +import com.gempukku.lotro.cards.build.field.FieldUtils; +import com.gempukku.lotro.cards.build.field.effect.EffectAppender; +import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer; +import com.gempukku.lotro.cards.build.field.effect.appender.resolver.CardResolver; +import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver; +import com.gempukku.lotro.common.Zone; +import com.gempukku.lotro.filters.Filters; +import com.gempukku.lotro.game.PhysicalCard; +import com.gempukku.lotro.game.state.LotroGame; +import com.gempukku.lotro.logic.GameUtils; +import com.gempukku.lotro.logic.actions.CostToEffectAction; +import com.gempukku.lotro.logic.timing.AbstractEffect; +import com.gempukku.lotro.logic.timing.Effect; +import org.json.simple.JSONObject; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +public class ExchangeCardsInHandWithCardsInDeadPile implements EffectAppenderProducer { + @Override + public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(effectObject, "filterInHand", "filterInDeadPile", "countInHand", "countInDeadPile"); + + final String filterHand = FieldUtils.getString(effectObject.get("filterInHand"), "filterInHand"); + final ValueSource countHand = ValueResolver.resolveEvaluator(effectObject.get("countInHand"), 1, environment); + final String filterDeadPile = FieldUtils.getString(effectObject.get("filterInDeadPile"), "filterInDeadPile"); + final ValueSource countDeadPile = ValueResolver.resolveEvaluator(effectObject.get("countInDeadPile"), 1, environment); + + MultiEffectAppender result = new MultiEffectAppender(); + + result.addEffectAppender( + CardResolver.resolveCardsInHand(filterHand, countHand, "_tempHand", "you", "you", "Choose cards to exchange in hand", environment)); + result.addEffectAppender( + CardResolver.resolveCardsInDeadPile(filterDeadPile, actionContext -> Filters.any, actionContext -> Filters.any, + countDeadPile, "_tempDeadPile", "you", "Choose cards to exchange in dead pile", environment)); + result.addEffectAppender( + new DelayedAppender() { + @Override + protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { + String performingPlayer = actionContext.getPerformingPlayer(); + Collection handCards = actionContext.getCardsFromMemory("_tempHand"); + Collection deadPileCards = actionContext.getCardsFromMemory("_tempDeadPile"); + return new AbstractEffect() { + @Override + protected FullEffectResult playEffectReturningResult(LotroGame game) { + Set cardsToRemove = new HashSet<>(); + cardsToRemove.addAll(handCards); + cardsToRemove.addAll(deadPileCards); + game.getGameState().sendMessage(performingPlayer + " exchanges " + GameUtils.getAppendedNames(deadPileCards) + " from dead pile with " + GameUtils.getAppendedNames(handCards) + " in hand"); + game.getGameState().removeCardsFromZone(performingPlayer, cardsToRemove); + for (PhysicalCard deadPileCard : deadPileCards) { + game.getGameState().addCardToZone(game, deadPileCard, Zone.HAND); + } + for (PhysicalCard handCard : handCards) { + game.getGameState().addCardToZone(game, handCard, Zone.DEAD); + } + return null; + } + + @Override + public boolean isPlayableInFull(LotroGame game) { + return true; + } + }; + } + }); + + return result; + } +} diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ExchangeCardsInHandWithCardsInDiscard.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ExchangeCardsInHandWithCardsInDiscard.java new file mode 100644 index 000000000..18e6e9b39 --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ExchangeCardsInHandWithCardsInDiscard.java @@ -0,0 +1,75 @@ +package com.gempukku.lotro.cards.build.field.effect.appender; + +import com.gempukku.lotro.cards.build.ActionContext; +import com.gempukku.lotro.cards.build.CardGenerationEnvironment; +import com.gempukku.lotro.cards.build.InvalidCardDefinitionException; +import com.gempukku.lotro.cards.build.ValueSource; +import com.gempukku.lotro.cards.build.field.FieldUtils; +import com.gempukku.lotro.cards.build.field.effect.EffectAppender; +import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer; +import com.gempukku.lotro.cards.build.field.effect.appender.resolver.CardResolver; +import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver; +import com.gempukku.lotro.common.Zone; +import com.gempukku.lotro.game.PhysicalCard; +import com.gempukku.lotro.game.state.LotroGame; +import com.gempukku.lotro.logic.GameUtils; +import com.gempukku.lotro.logic.actions.CostToEffectAction; +import com.gempukku.lotro.logic.timing.AbstractEffect; +import com.gempukku.lotro.logic.timing.Effect; +import org.json.simple.JSONObject; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +public class ExchangeCardsInHandWithCardsInDiscard implements EffectAppenderProducer { + @Override + public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(effectObject, "filterInHand", "filterInDiscard", "countInHand", "countInDiscard"); + + final String filterHand = FieldUtils.getString(effectObject.get("filterInHand"), "filterInHand"); + final ValueSource countHand = ValueResolver.resolveEvaluator(effectObject.get("countInHand"), 1, environment); + final String filterDiscard = FieldUtils.getString(effectObject.get("filterInDiscard"), "filterInDiscard"); + final ValueSource countDiscard = ValueResolver.resolveEvaluator(effectObject.get("countInDiscard"), 1, environment); + + MultiEffectAppender result = new MultiEffectAppender(); + + result.addEffectAppender( + CardResolver.resolveCardsInHand(filterHand, countHand, "_tempHand", "you", "you", "Choose cards to exchange in hand", environment)); + result.addEffectAppender( + CardResolver.resolveCardsInDiscard(filterDiscard, countDiscard, "_tempDiscard", "you", "Choose cards to exchange in discard", environment)); + result.addEffectAppender( + new DelayedAppender() { + @Override + protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { + String performingPlayer = actionContext.getPerformingPlayer(); + Collection handCards = actionContext.getCardsFromMemory("_tempHand"); + Collection discardCards = actionContext.getCardsFromMemory("_tempDiscard"); + return new AbstractEffect() { + @Override + protected FullEffectResult playEffectReturningResult(LotroGame game) { + Set cardsToRemove = new HashSet<>(); + cardsToRemove.addAll(handCards); + cardsToRemove.addAll(discardCards); + game.getGameState().sendMessage(performingPlayer + " exchanges " + GameUtils.getAppendedNames(discardCards) + " from discard with " + GameUtils.getAppendedNames(handCards) + " in hand"); + game.getGameState().removeCardsFromZone(performingPlayer, cardsToRemove); + for (PhysicalCard discardCard : discardCards) { + game.getGameState().addCardToZone(game, discardCard, Zone.HAND); + } + for (PhysicalCard handCard : handCards) { + game.getGameState().addCardToZone(game, handCard, Zone.DISCARD); + } + return null; + } + + @Override + public boolean isPlayableInFull(LotroGame game) { + return true; + } + }; + } + }); + + return result; + } +} diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutCardsFromHandOnBottomOfDeck.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutCardsFromHandOnBottomOfDeck.java index 5bcac84e9..3200cf061 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutCardsFromHandOnBottomOfDeck.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutCardsFromHandOnBottomOfDeck.java @@ -22,24 +22,17 @@ import java.util.List; public class PutCardsFromHandOnBottomOfDeck implements EffectAppenderProducer { @Override public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { - FieldUtils.validateAllowedFields(effectObject, "player", "optional", "filter", "count", "reveal"); + FieldUtils.validateAllowedFields(effectObject, "player", "filter", "count", "reveal"); final String player = FieldUtils.getString(effectObject.get("player"), "player", "you"); - final boolean optional = FieldUtils.getBoolean(effectObject.get("optional"), "optional", false); final String filter = FieldUtils.getString(effectObject.get("filter"), "filter", "choose(any)"); final ValueSource count = ValueResolver.resolveEvaluator(effectObject.get("count"), 1, environment); final boolean reveal = FieldUtils.getBoolean(effectObject.get("reveal"), "reveal", true); - ValueSource valueSource; - if (optional) - valueSource = ValueResolver.resolveEvaluator("0-" + count, environment); - else - valueSource = count; - MultiEffectAppender result = new MultiEffectAppender(); result.addEffectAppender( - CardResolver.resolveCardsInHand(filter, valueSource, "_temp", player, player, "Choose cards from hand", environment)); + CardResolver.resolveCardsInHand(filter, count, "_temp", player, player, "Choose cards from hand", environment)); result.addEffectAppender( new DelayedAppender() { @Override