From e1df113e319f32c272043e96a6b6362054a80e7f Mon Sep 17 00:00:00 2001 From: "marcin.sciesinski" Date: Fri, 30 Aug 2019 10:12:07 -0700 Subject: [PATCH] Fixed issue with effects being created out of order --- .../effect/appender/DelayedAppender.java | 19 +++++++----- .../build/field/effect/appender/Exert.java | 2 +- .../appender/PutStackedCardsIntoHand.java | 2 +- .../build/field/effect/appender/Wound.java | 2 +- .../appender/resolver/CardResolver.java | 22 +++++++------- .../com/gempukku/lotro/at/NewCardsAtTest.java | 30 +++++++++++++++++++ 6 files changed, 56 insertions(+), 21 deletions(-) diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DelayedAppender.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DelayedAppender.java index ed9e9b24c..ede5193b5 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DelayedAppender.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DelayedAppender.java @@ -9,6 +9,7 @@ import com.gempukku.lotro.logic.timing.EffectResult; import com.gempukku.lotro.logic.timing.UnrespondableEffect; import java.util.Collections; +import java.util.List; public abstract class DelayedAppender implements EffectAppender { private String text; @@ -27,9 +28,11 @@ public abstract class DelayedAppender implements EffectAppender { new UnrespondableEffect() { @Override protected void doPlayEffect(LotroGame game) { - for (Effect effect : createEffects(action, playerId, game, self, effectResult, effect)) { - action.appendCost(effect); - } + // Need to insert them, but in the reverse order + final List effects = createEffects(action, playerId, game, self, effectResult, effect); + final Effect[] effectsArray = effects.toArray(new Effect[0]); + for (int i = effectsArray.length - 1; i >= 0; i--) + action.insertCost(effectsArray[i]); } @Override @@ -45,9 +48,11 @@ public abstract class DelayedAppender implements EffectAppender { new UnrespondableEffect() { @Override protected void doPlayEffect(LotroGame game) { - for (Effect effect : createEffects(action, playerId, game, self, effectResult, effect)) { - action.appendEffect(effect); - } + // Need to insert them, but in the reverse order + final List effects = createEffects(action, playerId, game, self, effectResult, effect); + final Effect[] effectsArray = effects.toArray(new Effect[0]); + for (int i = effectsArray.length - 1; i >= 0; i--) + action.insertEffect(effectsArray[i]); } @Override @@ -61,7 +66,7 @@ public abstract class DelayedAppender implements EffectAppender { throw new UnsupportedOperationException("One of createEffect or createEffects has to be overwritten"); } - protected Iterable createEffects(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { + protected List createEffects(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { return Collections.singletonList(createEffect(action, playerId, game, self, effectResult, effect)); } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Exert.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Exert.java index 82a3da264..cfeb11326 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Exert.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Exert.java @@ -41,7 +41,7 @@ public class Exert implements EffectAppenderProducer { result.addEffectAppender( new DelayedAppender() { @Override - protected Iterable createEffects(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { + protected List createEffects(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { final Collection cardsFromMemory = action.getCardsFromMemory(memory); List result = new LinkedList<>(); diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutStackedCardsIntoHand.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutStackedCardsIntoHand.java index 515b8f739..fcbaf5158 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutStackedCardsIntoHand.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutStackedCardsIntoHand.java @@ -37,7 +37,7 @@ public class PutStackedCardsIntoHand implements EffectAppenderProducer { result.addEffectAppender( new DelayedAppender() { @Override - protected Iterable createEffects(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { + protected List createEffects(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { final Collection cardsToPutToHand = action.getCardsFromMemory("_temp"); List result = new LinkedList<>(); for (PhysicalCard physicalCard : cardsToPutToHand) diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Wound.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Wound.java index 76872dcaa..7456727f3 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Wound.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Wound.java @@ -40,7 +40,7 @@ public class Wound implements EffectAppenderProducer { result.addEffectAppender( new DelayedAppender() { @Override - protected Iterable createEffects(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { + protected List createEffects(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { final Collection cardsFromMemory = action.getCardsFromMemory(memory); List result = new LinkedList<>(); for (int i = 0; i < times; i++) 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 530e61d5f..3626403b7 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 @@ -2,7 +2,7 @@ package com.gempukku.lotro.cards.build.field.effect.appender.resolver; import com.gempukku.lotro.cards.build.*; import com.gempukku.lotro.cards.build.field.effect.EffectAppender; -import com.gempukku.lotro.cards.build.field.effect.appender.AbstractEffectAppender; +import com.gempukku.lotro.cards.build.field.effect.appender.DelayedAppender; import com.gempukku.lotro.common.Filterable; import com.gempukku.lotro.filters.Filters; import com.gempukku.lotro.game.PhysicalCard; @@ -27,7 +27,7 @@ public class CardResolver { String memory, String choicePlayer, String choiceText, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { if (type.startsWith("memory(") && type.endsWith(")")) { String sourceMemory = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); - return new AbstractEffectAppender() { + return new DelayedAppender() { @Override public boolean isPlayableInFull(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { return true; @@ -47,7 +47,7 @@ public class CardResolver { final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter); final PlayerSource playerSource = PlayerResolver.resolvePlayer(choicePlayer, environment); - return new AbstractEffectAppender() { + return new DelayedAppender() { @Override public boolean isPlayableInFull(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { final int min = countSource.getMinimum(null, playerId, game, self, effectResult, effect); @@ -87,7 +87,7 @@ public class CardResolver { public static EffectAppender resolveCardsInHand(String type, ValueSource countSource, String memory, String choicePlayer, String choiceText, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { if (type.startsWith("memory(") && type.endsWith(")")) { String sourceMemory = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); - return new AbstractEffectAppender() { + return new DelayedAppender() { @Override public boolean isPlayableInFull(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { return true; @@ -107,7 +107,7 @@ public class CardResolver { final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter); final PlayerSource playerSource = PlayerResolver.resolvePlayer(choicePlayer, environment); - return new AbstractEffectAppender() { + return new DelayedAppender() { @Override public boolean isPlayableInFull(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { int min = countSource.getMinimum(null, playerId, game, self, effectResult, effect); @@ -143,7 +143,7 @@ public class CardResolver { final PlayerSource playerSource = PlayerResolver.resolvePlayer(choicePlayer, environment); String sourceMemory = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); - return new AbstractEffectAppender() { + return new DelayedAppender() { @Override public boolean isPlayableInFull(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { if (additionalFilter != null) { @@ -170,7 +170,7 @@ public class CardResolver { final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter); final PlayerSource playerSource = PlayerResolver.resolvePlayer(choicePlayer, environment); - return new AbstractEffectAppender() { + return new DelayedAppender() { @Override public boolean isPlayableInFull(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { int min = countSource.getMinimum(null, playerId, game, self, effectResult, effect); @@ -217,7 +217,7 @@ public class CardResolver { public static EffectAppender resolveCards(String type, FilterableSource additionalFilter, ValueSource countSource, String memory, String choicePlayer, String choiceText, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { if (type.equals("self")) { - return new AbstractEffectAppender() { + return new DelayedAppender() { @Override public boolean isPlayableInFull(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { if (additionalFilter != null) @@ -237,7 +237,7 @@ public class CardResolver { }; } else if (type.startsWith("memory(") && type.endsWith(")")) { String sourceMemory = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); - return new AbstractEffectAppender() { + return new DelayedAppender() { @Override public boolean isPlayableInFull(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { if (additionalFilter != null) { @@ -264,7 +264,7 @@ public class CardResolver { } else if (type.startsWith("all(") && type.endsWith(")")) { final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter); - return new AbstractEffectAppender() { + return new DelayedAppender() { @Override protected Effect createEffect(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { return new UnrespondableEffect() { @@ -285,7 +285,7 @@ public class CardResolver { final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter); final PlayerSource playerSource = PlayerResolver.resolvePlayer(choicePlayer, environment); - return new AbstractEffectAppender() { + return new DelayedAppender() { @Override public boolean isPlayableInFull(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { int min = countSource.getMinimum(null, playerId, game, self, effectResult, effect); diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/NewCardsAtTest.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/NewCardsAtTest.java index c1248072c..364a48863 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/NewCardsAtTest.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/NewCardsAtTest.java @@ -51,4 +51,34 @@ public class NewCardsAtTest extends AbstractAtTest { assertEquals(0, ((String[]) _userFeedback.getAwaitingDecision(P1).getDecisionParameters().get("actionId")).length); } + + @Test + public void reduceArcheryTotal() throws DecisionResultInvalidException, CardNotFoundException { + initializeSimplestGame(); + + PhysicalCardImpl legolas = new PhysicalCardImpl(100, "40_52", P1, _library.getLotroCardBlueprint("40_52")); + PhysicalCardImpl arrowsOfLight = new PhysicalCardImpl(100, "40_33", P1, _library.getLotroCardBlueprint("40_33")); + PhysicalCardImpl inquisitor = new PhysicalCardImpl(100, "1_268", P2, _library.getLotroCardBlueprint("1_268")); + + _game.getGameState().addCardToZone(_game, inquisitor, Zone.SHADOW_CHARACTERS); + + _game.getGameState().addCardToZone(_game, legolas, Zone.FREE_CHARACTERS); + _game.getGameState().addCardToZone(_game, arrowsOfLight, Zone.HAND); + + skipMulligans(); + + // Pass in fellowship + playerDecided(P1, ""); + + // Pass in shadow + playerDecided(P2, ""); + + // Pass in maneuver + playerDecided(P1, ""); + playerDecided(P2, ""); + + // Play ArrowsOfLight + playerDecided(P1, "0"); + playerDecided(P1, "0"); + } }