diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40.json b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40.json index 56cb2a189..aff9e7c7f 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40.json +++ b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40.json @@ -142,7 +142,7 @@ "filter": "self" }, "effect": { - "type": "stackTopCardOfDrawDeck", + "type": "stackTopCardsOfDrawDeck", "where": "self" } }, @@ -227,7 +227,7 @@ "effects": { "type": "event", "cost": { - "type": "stackTopCardOfDrawDeck", + "type": "stackTopCardsOfDrawDeck", "deck": "owner", "where": "choose(culture(dwarven),support area,condition)", "count": 3 @@ -554,7 +554,187 @@ } } ] - } + }, + "40_18": { + "title": "*Gimli", + "subtitle": "Stalwart Protector", + "side": "free people", + "culture": "dwarven", + "cost": 3, + "type": "companion", + "race": "dwarf", + "strength": 6, + "vitality": 4, + "resistance": 7, + "keyword": "damage+1", + "effects": [ + { + "type": "modifyOwnCost", + "condition": { + "type": "phase", + "phase": "play starting fellowship" + }, + "amount": -1 + }, + { + "type": "modifyStrength", + "condition": { + "type": "location", + "filter": "or(mountain,underground)" + }, + "amount": 2 + }, + { + "type": "canttakemorewoundsthan", + "phase": "skirmish", + "amount": 1 + } + ] + }, + "40_19": { + "title": "*Gimli's Battle Axe", + "subtitle": "Weapon of Erebor", + "side": "free people", + "culture": "dwarven", + "cost": 2, + "type": "possession", + "possession": "hand weapon", + "strength": 2, + "target": "dwarf", + "effects": [ + { + "type": "addKeyword", + "filter": "hasAttached(self),name(Gimli)", + "keyword": "damage+1" + }, + { + "type": "trigger", + "optional": true, + "trigger": { + "type": "winsSkirmish", + "filter": "hasAttached(self)" + }, + "effect": { + "type": "stackCardsFromDiscard", + "where": "choose(culture(dwarven),support area,condition)", + "filter": "choose(culture(dwarven),event)" + } + } + ] + }, + "40_21": { + "title": "Killing Blow", + "side": "free people", + "culture": "dwarven", + "cost": 2, + "type": "event", + "keyword": "skirmish", + "effects": { + "type": "event", + "effect": [ + { + "type": "modifyStrength", + "amount": 2, + "filter": "choose(dwarf)", + "memorize": "dwarf" + }, + { + "type": "condition", + "condition": { + "type": "canSpot", + "filter": "culture(dwarven),condition,hasStacked(any)" + }, + "effect": { + "type": "addKeyword", + "filter": "memory(dwarf)", + "keyword": "damage+1" + } + } + ] + } + }, + "40_22": { + "title": "Lethal Strike", + "side": "free people", + "culture": "dwarven", + "cost": 1, + "type": "event", + "keyword": "skirmish", + "effects": { + "type": "event", + "cost": { + "type": "exert", + "filter": "choose(dwarf)", + "memorize": "dwarf" + }, + "effect": [ + { + "type": "modifyStrength", + "filter": "memory(dwarf)", + "amount": 3 + }, + { + "type": "addKeyword", + "filter": "memory(dwarf)", + "keyword": "damage+1" + } + ] + } + }, + "40_23": { + "title": "Memories of Khazad-dum", + "side": "free people", + "culture": "dwarven", + "cost": 2, + "type": "condition", + "keyword": "support area", + "effects": [ + { + "type": "trigger", + "trigger": { + "type": "played", + "filter": "self" + }, + "effect": { + "type": "stackTopCardsOfDrawDeck", + "where": "self" + } + }, + { + "type": "activated", + "phase": "skirmish", + "cost": { + "type": "discardStackedCards", + "on": "self", + "filter": "choose(side(free people))" + }, + "effect": { + "type": "modifyStrength", + "filter": "choose(dwarf)", + "amount": 1 + } + } + ] + }, + "40_24": { + "title": "Miners of Mithril", + "side": "free people", + "culture": "dwarven", + "cost": 0, + "type": "event", + "keyword": "fellowship", + "effects": { + "type": "event", + "cost": { + "type": "stackCardsFromHand", + "where": "choose(culture(dwarven),support area,condition)", + "filter": "choose(side(free people))" + }, + "effect": { + "type": "drawCards" + } + } + }, "40_184": { "title": "Black Steed", "subtitle": "Bred to Serve", 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 5fe4b4de1..14c9a5520 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 @@ -28,6 +28,7 @@ public class EffectFieldProcessor implements FieldProcessor { effectProcessors.put("archerytotal", new ArcheryTotal()); effectProcessors.put("opponentmaynotdiscard", new OpponentMayNotDiscard()); effectProcessors.put("modifyowncost", new ModifyOwnCost()); + effectProcessors.put("canttakemorewoundsthan", new CantTakeMoreWoundsThan()); } @Override 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 ad5fd7736..44dd8a326 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 @@ -13,7 +13,7 @@ public class EffectAppenderFactory { private Map effectAppenderProducers = new HashMap<>(); public EffectAppenderFactory() { - effectAppenderProducers.put("stacktopcardofdrawdeck", new StackTopCardOfDrawDeck()); + effectAppenderProducers.put("stacktopcardsofdrawdeck", new StackTopCardsOfDrawDeck()); effectAppenderProducers.put("discard", new DiscardFromPlay()); effectAppenderProducers.put("preventdiscard", new PreventCardEffectAppender()); effectAppenderProducers.put("exert", new Exert()); @@ -42,6 +42,7 @@ public class EffectAppenderFactory { effectAppenderProducers.put("drawcards", new DrawCards()); effectAppenderProducers.put("removeburdens", new RemoveBurdens()); effectAppenderProducers.put("stackcardsfromhand", new StackCardsFromHand()); + effectAppenderProducers.put("stackcardsfromdiscard", new StackCardsFromDiscard()); effectAppenderProducers.put("putcardsfromdiscardintohand", new PutCardsFromDiscardIntoHand()); } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/StackCardsFromDiscard.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/StackCardsFromDiscard.java new file mode 100644 index 000000000..4d08b4665 --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/StackCardsFromDiscard.java @@ -0,0 +1,57 @@ +package com.gempukku.lotro.cards.build.field.effect.appender; + +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.game.state.LotroGame; +import com.gempukku.lotro.logic.actions.CostToEffectAction; +import com.gempukku.lotro.logic.effects.StackCardFromDiscardEffect; +import com.gempukku.lotro.logic.timing.Effect; +import com.gempukku.lotro.logic.timing.EffectResult; +import org.json.simple.JSONObject; + +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +public class StackCardsFromDiscard implements EffectAppenderProducer { + @Override + public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(effectObject, "filter", "where", "count"); + + final String filter = FieldUtils.getString(effectObject.get("filter"), "filter", "choose(any)"); + final String where = FieldUtils.getString(effectObject.get("where"), "where"); + final ValueSource valueSource = ValueResolver.resolveEvaluator(effectObject.get("count"), 1, environment); + + MultiEffectAppender result = new MultiEffectAppender(); + + result.addEffectAppender( + CardResolver.resolveCard(where, "_temp1", "owner", "Choose card to stack on", environment)); + result.addEffectAppender( + CardResolver.resolveCardsInDiscard(filter, valueSource, "_temp2", "owner", "Choose cards to stack", environment)); + result.addEffectAppender( + new DelayedAppender() { + @Override + protected List createEffects(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { + final PhysicalCard card = action.getCardFromMemory("_temp1"); + final Collection cardsInHand = action.getCardsFromMemory("_temp2"); + + List result = new LinkedList<>(); + for (PhysicalCard physicalCard : cardsInHand) { + result.add(new StackCardFromDiscardEffect(physicalCard, card)); + } + + return result; + } + }); + + return result; + } + +} diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/StackTopCardOfDrawDeck.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/StackTopCardsOfDrawDeck.java similarity index 97% rename from gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/StackTopCardOfDrawDeck.java rename to gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/StackTopCardsOfDrawDeck.java index 8cf151798..ebd244a93 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/StackTopCardOfDrawDeck.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/StackTopCardsOfDrawDeck.java @@ -15,7 +15,7 @@ import com.gempukku.lotro.logic.timing.Effect; import com.gempukku.lotro.logic.timing.EffectResult; import org.json.simple.JSONObject; -public class StackTopCardOfDrawDeck implements EffectAppenderProducer { +public class StackTopCardsOfDrawDeck implements EffectAppenderProducer { @Override public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { FieldUtils.validateAllowedFields(effectObject, "deck", "where", "count"); diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/CantTakeMoreWoundsThan.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/CantTakeMoreWoundsThan.java new file mode 100644 index 000000000..0373c7cfe --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/CantTakeMoreWoundsThan.java @@ -0,0 +1,36 @@ +package com.gempukku.lotro.cards.build.field.effect.modifier; + +import com.gempukku.lotro.cards.build.*; +import com.gempukku.lotro.cards.build.field.EffectProcessor; +import com.gempukku.lotro.cards.build.field.FieldUtils; +import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver; +import com.gempukku.lotro.common.Phase; +import com.gempukku.lotro.logic.modifiers.CantTakeMoreThanXWoundsModifier; +import com.gempukku.lotro.logic.modifiers.evaluator.Evaluator; +import org.json.simple.JSONObject; + +public class CantTakeMoreWoundsThan implements EffectProcessor { + @Override + public void processEffect(JSONObject value, BuiltLotroCardBlueprint blueprint, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(value, "filter", "phase", "condition", "amount"); + + final ValueSource valueSource = ValueResolver.resolveEvaluator(value.get("amount"), 1, environment); + final JSONObject[] conditionArray = FieldUtils.getObjectArray(value.get("condition"), "condition"); + final String filter = FieldUtils.getString(value.get("filter"), "filter", "self"); + final Phase phase = FieldUtils.getEnum(Phase.class, value.get("phase"), "phase"); + + final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter); + final Requirement[] requirements = environment.getRequirementFactory().getRequirements(conditionArray, environment); + + blueprint.appendInPlayModifier( + (game, self) -> { + final Evaluator evaluator = valueSource.getEvaluator(null, null, game, self, null, null); + return new CantTakeMoreThanXWoundsModifier(self, phase, + valueSource.getEvaluator(null, null, game, self, null, null) + .evaluateExpression(game, self), + new RequirementCondition(requirements, null, self, null, null), + filterableSource.getFilterable(null, game, self, null, null)); + }); + + } +}