From 1c57dd67bd034c99616cce3d5534d6ccd73384d6 Mon Sep 17 00:00:00 2001 From: "marcin.sciesinski" Date: Fri, 6 Sep 2019 10:57:52 -0700 Subject: [PATCH] Couple of Sauron cards --- .../main/web/cards/set40/set40-sauron.json | 111 +++++++++++++++++- .../main/web/cards/set40/set40-wraith.json | 2 +- .../src/main/web/cards/set40/set40.json | 6 +- .../cards/build/BuiltLotroCardBlueprint.java | 31 ++++- .../build/field/EffectFieldProcessor.java | 1 + .../field/effect/EffectAppenderFactory.java | 4 +- .../effect/InHandTriggerEffectProcessor.java | 31 +++++ .../{AddBurden.java => AddBurdens.java} | 2 +- .../effect/appender/RevealCardsFromHand.java | 46 ++++++++ .../appender/resolver/CardResolver.java | 20 +++- .../field/effect/trigger/PutsOnRing.java | 27 +++++ .../effect/trigger/TriggerCheckerFactory.java | 1 + 12 files changed, 269 insertions(+), 13 deletions(-) create mode 100644 gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/InHandTriggerEffectProcessor.java rename gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/{AddBurden.java => AddBurdens.java} (97%) create mode 100644 gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/RevealCardsFromHand.java create mode 100644 gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/trigger/PutsOnRing.java diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40/set40-sauron.json b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40/set40-sauron.json index 399d49bfe..bdbfc2761 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40/set40-sauron.json +++ b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40/set40-sauron.json @@ -177,6 +177,115 @@ } ] }, + "40_218": { + "title": "*Gathering Evil", + "culture": "sauron", + "cost": 2, + "type": "condition", + "keyword": "support area", + "effects": { + "type": "trigger", + "optional": true, + "trigger": { + "type": "startOfPhase", + "phase": "shadow" + }, + "condition": { + "type": "cantSpotFPCultures", + "amount": 3 + }, + "effect": { + "type": "choice", + "texts": [ + "Play [Sauron] minion from your draw deck", + "Play [Sauron] minion from your discard pile" + ], + "effects": [ + { + "type": "playCardFromDrawDeck", + "filter": "choose(culture(sauron),minion)" + }, + { + "type": "playCardFromDiscard", + "filter": "choose(culture(sauron),minion)" + } + ] + } + } + }, + "40_219": { + "title": "*The Great Eye", + "subtitle": "Wreathed in Flame", + "culture": "sauron", + "cost": 3, + "type": "minion", + "strength": 6, + "vitality": 4, + "site": 6, + "keyword": "cunning", + "effects": [ + { + "type": "trigger", + "trigger": { + "type": "played", + "filter": "self" + }, + "effect": { + "type": "addThreats", + "amount": { + "type": "forEachYouCanSpot", + "filter": "companion", + "over": 4 + } + } + }, + { + "type": "inHandTrigger", + "trigger": { + "type": "putsOnRing" + }, + "cost": { + "type": "revealCardsFromHand", + "filter": "self" + }, + "effect": { + "type": "addBurdens", + "amount": 1 + } + }, + { + "type": "activated", + "phase": "skirmish", + "cost": { + "type": "exert", + "filter": "self" + }, + "effect": { + "type": "modifyStrength", + "filter": "choose(culture(sauron),minion)", + "amount": 2 + } + } + ] + }, + "40_220": { + "title": "Hate", + "culture": "sauron", + "cost": 0, + "type": "event", + "keyword": "maneuver", + "effects": { + "type": "event", + "cost": { + "type": "exert", + "filter": "choose(culture(sauron),orc)" + }, + "effect": { + "type": "wound", + "filter": "choose(companion,not(ring bearer))" + } + } + }, "40_221": { "title": "It Will Destroy Them All", "culture": "sauron", @@ -220,7 +329,7 @@ ], "effects": [ { - "type": "addBurden", + "type": "addBurdens", "player": "fp" }, { diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40/set40-wraith.json b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40/set40-wraith.json index 3def21a6d..0e03c1f31 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40/set40-wraith.json +++ b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40/set40-wraith.json @@ -48,7 +48,7 @@ "filter": "choose(ring bearer)" }, { - "type": "addBurden", + "type": "addBurdens", "player": "fp" } ] diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40/set40.json b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40/set40.json index ce6714b08..403c5a40d 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40/set40.json +++ b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40/set40.json @@ -27,7 +27,7 @@ "filter": "all(bearer)" }, { - "type": "addBurden" + "type": "addBurdens" } ] }, @@ -90,7 +90,7 @@ "filter": "all(bearer)" }, { - "type": "addBurden" + "type": "addBurdens" } ] }, @@ -115,7 +115,7 @@ "filter": "all(bearer)" }, { - "type": "addBurden" + "type": "addBurdens" }, { "type": "putOnRing" diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/BuiltLotroCardBlueprint.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/BuiltLotroCardBlueprint.java index 5b81cdaea..d72f2ed7b 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/BuiltLotroCardBlueprint.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/BuiltLotroCardBlueprint.java @@ -51,6 +51,8 @@ public class BuiltLotroCardBlueprint implements LotroCardBlueprint { private List optionalInHandBeforeActions; private List optionalInHandAfterActions; + private List optionalInHandAfterTriggers; + private List inPlayPhaseActions; private List fromStackedPhaseActions; @@ -85,6 +87,12 @@ public class BuiltLotroCardBlueprint implements LotroCardBlueprint { discountSources.add(discountSource); } + public void appendOptionalInHandAfterTrigger(ActionSource actionSource) { + if (optionalInHandAfterTriggers == null) + optionalInHandAfterTriggers = new LinkedList<>(); + optionalInHandAfterTriggers.add(actionSource); + } + public void appendOptionalInHandBeforeAction(ActionSource actionSource) { if (optionalInHandBeforeActions == null) optionalInHandBeforeActions = new LinkedList<>(); @@ -603,6 +611,24 @@ public class BuiltLotroCardBlueprint implements LotroCardBlueprint { return result; } + @Override + public List getOptionalInHandAfterTriggers(String playerId, LotroGame game, EffectResult effectResult, PhysicalCard self) { + if (optionalInHandAfterTriggers == null) + return null; + + List result = new LinkedList<>(); + for (ActionSource optionalInHandAfterTrigger : optionalInHandAfterTriggers) { + DefaultActionContext actionContext = new DefaultActionContext(playerId, game, self, effectResult, null); + if (optionalInHandAfterTrigger.isValid(actionContext)) { + OptionalTriggerAction action = new OptionalTriggerAction(self); + optionalInHandAfterTrigger.createAction(action, actionContext); + result.add(action); + } + } + + return result; + } + @Override public List getExtraCostToPlay(LotroGame game, PhysicalCard self) { if (extraPlayCosts == null) @@ -630,11 +656,6 @@ public class BuiltLotroCardBlueprint implements LotroCardBlueprint { return null; } - @Override - public List getOptionalInHandAfterTriggers(String playerId, LotroGame game, EffectResult effectResult, PhysicalCard self) { - return null; - } - @Override public boolean isExtraPossessionClass(LotroGame game, PhysicalCard self, PhysicalCard attachedTo) { if (extraPossessionClassTest != null) diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/EffectFieldProcessor.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/EffectFieldProcessor.java index 0c3fde3d2..6a804b6be 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/EffectFieldProcessor.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/EffectFieldProcessor.java @@ -17,6 +17,7 @@ public class EffectFieldProcessor implements FieldProcessor { public EffectFieldProcessor() { effectProcessors.put("trigger", new TriggerEffectProcessor()); + effectProcessors.put("inhandtrigger", new InHandTriggerEffectProcessor()); effectProcessors.put("activatedtrigger", new ActivatedTriggerEffectProcessor()); effectProcessors.put("activated", new ActivatedEffectProcessor()); effectProcessors.put("event", new EventEffectProcessor()); 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 0d523df8d..b2517b489 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 @@ -21,7 +21,7 @@ public class EffectAppenderFactory { effectAppenderProducers.put("modifystrength", new ModifyStrength()); effectAppenderProducers.put("addkeyword", new AddKeyword()); effectAppenderProducers.put("modifyarcherytotal", new ModifyArcheryTotal()); - effectAppenderProducers.put("addburden", new AddBurden()); + effectAppenderProducers.put("addburdens", new AddBurdens()); effectAppenderProducers.put("discardtopcardsfromdeck", new DiscardTopCardFromDeck()); effectAppenderProducers.put("addtwilight", new AddTwilight()); effectAppenderProducers.put("wound", new Wound()); @@ -82,6 +82,8 @@ public class EffectAppenderFactory { effectAppenderProducers.put("addmodifier", new AddModifier()); effectAppenderProducers.put("playnextsite", new PlayNextSite()); effectAppenderProducers.put("duplicate", new Duplicate()); + effectAppenderProducers.put("revealcardsfromhand", new RevealCardsFromHand()); + effectAppenderProducers.put("revealcardsfromhand", new RevealCardsFromHand()); } public EffectAppender getEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/InHandTriggerEffectProcessor.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/InHandTriggerEffectProcessor.java new file mode 100644 index 000000000..984025270 --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/InHandTriggerEffectProcessor.java @@ -0,0 +1,31 @@ +package com.gempukku.lotro.cards.build.field.effect; + +import com.gempukku.lotro.cards.build.BuiltLotroCardBlueprint; +import com.gempukku.lotro.cards.build.CardGenerationEnvironment; +import com.gempukku.lotro.cards.build.InvalidCardDefinitionException; +import com.gempukku.lotro.cards.build.field.EffectProcessor; +import com.gempukku.lotro.cards.build.field.FieldUtils; +import com.gempukku.lotro.cards.build.field.effect.trigger.TriggerChecker; +import org.json.simple.JSONObject; + +public class InHandTriggerEffectProcessor implements EffectProcessor { + @Override + public void processEffect(JSONObject value, BuiltLotroCardBlueprint blueprint, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(value, "trigger", "condition", "cost", "effect"); + + final JSONObject[] triggerArray = FieldUtils.getObjectArray(value.get("trigger"), "trigger"); + + for (JSONObject trigger : triggerArray) { + final TriggerChecker triggerChecker = environment.getTriggerCheckerFactory().getTriggerChecker(trigger, environment); + final boolean before = triggerChecker.isBefore(); + if (before) + throw new InvalidCardDefinitionException("Only after triggers from hand are supported"); + + DefaultActionSource triggerActionSource = new DefaultActionSource(); + triggerActionSource.addPlayRequirement(triggerChecker); + EffectUtils.processRequirementsCostsAndEffects(value, environment, triggerActionSource); + + blueprint.appendOptionalInHandAfterTrigger(triggerActionSource); + } + } +} diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/AddBurden.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/AddBurdens.java similarity index 97% rename from gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/AddBurden.java rename to gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/AddBurdens.java index 8246db194..0a494bc14 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/AddBurden.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/AddBurdens.java @@ -14,7 +14,7 @@ import com.gempukku.lotro.logic.timing.Effect; import com.gempukku.lotro.logic.timing.PlayConditions; import org.json.simple.JSONObject; -public class AddBurden implements EffectAppenderProducer { +public class AddBurdens implements EffectAppenderProducer { @Override public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { FieldUtils.validateAllowedFields(effectObject, "amount", "player"); diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/RevealCardsFromHand.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/RevealCardsFromHand.java new file mode 100644 index 000000000..9301a2e4c --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/RevealCardsFromHand.java @@ -0,0 +1,46 @@ +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.game.PhysicalCard; +import com.gempukku.lotro.logic.actions.CostToEffectAction; +import com.gempukku.lotro.logic.effects.RevealCardsFromYourHandEffect; +import com.gempukku.lotro.logic.timing.Effect; +import org.json.simple.JSONObject; + +import java.util.Collection; + +public class RevealCardsFromHand implements EffectAppenderProducer { + @Override + public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(effectObject, "count", "filter", "memorize"); + + final String filter = FieldUtils.getString(effectObject.get("filter"), "filter", "choose(any)"); + final String memorize = FieldUtils.getString(effectObject.get("memorize"), "memorize", "_temp"); + + final ValueSource countSource = ValueResolver.resolveEvaluator(effectObject.get("count"), 1, environment); + + MultiEffectAppender result = new MultiEffectAppender(); + + result.addEffectAppender( + CardResolver.resolveCardsInHand(filter, countSource, memorize, "you", "Choose cards to reveal", environment)); + result.addEffectAppender( + new DelayedAppender() { + @Override + protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { + final Collection cardsToReveal = actionContext.getCardsFromMemory(memorize); + return new RevealCardsFromYourHandEffect(actionContext.getSource(), actionContext.getPerformingPlayer(), cardsToReveal); + } + }); + + return result; + } + +} diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/resolver/CardResolver.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/resolver/CardResolver.java index bc3f424e2..47864b53e 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/resolver/CardResolver.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/resolver/CardResolver.java @@ -4,6 +4,7 @@ import com.gempukku.lotro.cards.build.*; import com.gempukku.lotro.cards.build.field.effect.EffectAppender; import com.gempukku.lotro.cards.build.field.effect.appender.DelayedAppender; import com.gempukku.lotro.common.Filterable; +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; @@ -110,7 +111,24 @@ public class CardResolver { } public static EffectAppender resolveCardsInHand(String type, FilterableSource additionalFilter, ValueSource countSource, String memory, String choicePlayer, String choiceText, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { - if (type.startsWith("memory(") && type.endsWith(")")) { + if (type.equals("self")) { + return new DelayedAppender() { + @Override + public boolean isPlayableInFull(ActionContext actionContext) { + return actionContext.getSource().getZone() == Zone.HAND; + } + + @Override + protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { + return new UnrespondableEffect() { + @Override + protected void doPlayEffect(LotroGame game) { + actionContext.setCardMemory(memory, actionContext.getSource()); + } + }; + } + }; + } else if (type.startsWith("memory(") && type.endsWith(")")) { final PlayerSource playerSource = PlayerResolver.resolvePlayer(choicePlayer, environment); String sourceMemory = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/trigger/PutsOnRing.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/trigger/PutsOnRing.java new file mode 100644 index 000000000..987de80dd --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/trigger/PutsOnRing.java @@ -0,0 +1,27 @@ +package com.gempukku.lotro.cards.build.field.effect.trigger; + +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.field.FieldUtils; +import com.gempukku.lotro.logic.timing.EffectResult; +import org.json.simple.JSONObject; + +public class PutsOnRing implements TriggerCheckerProducer { + @Override + public TriggerChecker getTriggerChecker(JSONObject value, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(value, "filter"); + + return new TriggerChecker() { + @Override + public boolean accepts(ActionContext actionContext) { + return actionContext.getEffectResult().getType() == EffectResult.Type.PUT_ON_THE_ONE_RING; + } + + @Override + public boolean isBefore() { + return false; + } + }; + } +} diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/trigger/TriggerCheckerFactory.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/trigger/TriggerCheckerFactory.java index 6a8ae7b27..2249c70b5 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/trigger/TriggerCheckerFactory.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/trigger/TriggerCheckerFactory.java @@ -28,6 +28,7 @@ public class TriggerCheckerFactory { triggerCheckers.put("losesinitiative", new LosesInitiative()); triggerCheckers.put("takeswound", new TakesWound()); triggerCheckers.put("discardfromhand", new DiscardFromHand()); + triggerCheckers.put("putsonring", new PutsOnRing()); } public TriggerChecker getTriggerChecker(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {