From c21c31a596b244b456e565f777acce19d49f2778 Mon Sep 17 00:00:00 2001 From: Marcin Sciesinski Date: Thu, 17 Oct 2024 16:06:22 +0700 Subject: [PATCH] Added more ATs --- .../cards/official/set17/set17-Uruk-hai.hjson | 2 +- .../effect/modifier/AddKeywordFromCards.java | 2 +- .../effect/modifier/RemoveAllKeywords.java | 5 +- ...tTakeWoundsFromLosingSkirmishModifier.java | 2 +- .../lotro/logic/modifiers/ModifiersLogic.java | 16 +- .../com/gempukku/lotro/at/AbstractAtTest.java | 19 + .../gempukku/lotro/at/ModifiersAtTest.java | 380 ++++++++++++++++++ 7 files changed, 416 insertions(+), 10 deletions(-) create mode 100644 gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/ModifiersAtTest.java diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set17/set17-Uruk-hai.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set17/set17-Uruk-hai.hjson index 2de62825a..7868ec72f 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set17/set17-Uruk-hai.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set17/set17-Uruk-hai.hjson @@ -539,7 +539,7 @@ filter: self,assignedToSkirmish(any) } filter: site,zone(adventure path) - from: site,youControl + from: siteYouControl } } ] diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/AddKeywordFromCards.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/AddKeywordFromCards.java index d98bed9dd..c4b5ec019 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/AddKeywordFromCards.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/AddKeywordFromCards.java @@ -13,7 +13,7 @@ public class AddKeywordFromCards implements ModifierSourceProducer { final String filter = FieldUtils.getString(object.get("filter"), "filter"); final JSONObject[] conditionArray = FieldUtils.getObjectArray(object.get("requires"), "requires"); - final String from = FieldUtils.getString(object.get("filter"), "filter"); + final String from = FieldUtils.getString(object.get("from"), "from"); boolean terrainOnly = FieldUtils.getBoolean(object.get("terrain"), "terrain", false); final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment); diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/RemoveAllKeywords.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/RemoveAllKeywords.java index 57f7708e0..3e234394f 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/RemoveAllKeywords.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/RemoveAllKeywords.java @@ -2,7 +2,6 @@ package com.gempukku.lotro.cards.build.field.effect.modifier; import com.gempukku.lotro.cards.build.*; import com.gempukku.lotro.cards.build.field.FieldUtils; -import com.gempukku.lotro.common.Keyword; import com.gempukku.lotro.logic.modifiers.LoseAllKeywordsModifier; import com.gempukku.lotro.logic.modifiers.Modifier; import org.json.simple.JSONObject; @@ -10,13 +9,11 @@ import org.json.simple.JSONObject; public class RemoveAllKeywords implements ModifierSourceProducer { @Override public ModifierSource getModifierSource(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { - FieldUtils.validateAllowedFields(object, "filter", "requires", "keyword"); + FieldUtils.validateAllowedFields(object, "filter", "requires"); final JSONObject[] conditionArray = FieldUtils.getObjectArray(object.get("requires"), "requires"); final String filter = FieldUtils.getString(object.get("filter"), "filter"); - Keyword keyword = FieldUtils.getEnum(Keyword.class, object.get("keyword"), "keyword"); - final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment); final Requirement[] requirements = environment.getRequirementFactory().getRequirements(conditionArray, environment); diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/modifiers/CantTakeWoundsFromLosingSkirmishModifier.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/modifiers/CantTakeWoundsFromLosingSkirmishModifier.java index e6989becc..dedb69735 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/modifiers/CantTakeWoundsFromLosingSkirmishModifier.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/modifiers/CantTakeWoundsFromLosingSkirmishModifier.java @@ -11,6 +11,6 @@ public class CantTakeWoundsFromLosingSkirmishModifier extends AbstractModifier { @Override public boolean canTakeWoundsFromLosingSkirmish(LotroGame game, PhysicalCard physicalCard) { - return true; + return false; } } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/modifiers/ModifiersLogic.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/modifiers/ModifiersLogic.java index 6ecf056a1..b25507faf 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/modifiers/ModifiersLogic.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/modifiers/ModifiersLogic.java @@ -307,9 +307,19 @@ public class ModifiersLogic implements ModifiersEnvironment, ModifiersQuerying { return true; for (Modifier modifier : getKeywordModifiersAffectingCard(game, ModifierEffect.GIVE_KEYWORD_MODIFIER, keyword, physicalCard)) { - if (appliesKeywordModifier(game, physicalCard, modifier.getSource(), keyword)) - if (modifier.hasKeyword(game, physicalCard, keyword)) - return true; + if (appliesKeywordModifier(game, physicalCard, modifier.getSource(), keyword)) { + if (!_skipSet.contains(modifier)) { + _skipSet.add(modifier); + try { + if (modifier.hasKeyword(game, physicalCard, keyword)) + return true; + } finally { + _skipSet.remove(modifier); + } + } else { + return false; + } + } } return false; } finally { diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/AbstractAtTest.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/AbstractAtTest.java index e001e7541..b958e8a72 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/AbstractAtTest.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/AbstractAtTest.java @@ -7,6 +7,7 @@ import com.gempukku.lotro.logic.actions.SystemQueueAction; import com.gempukku.lotro.logic.decisions.AwaitingDecision; import com.gempukku.lotro.logic.decisions.CardActionSelectionDecision; import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; +import com.gempukku.lotro.logic.modifiers.Modifier; import com.gempukku.lotro.logic.timing.Action; import com.gempukku.lotro.logic.timing.DefaultLotroGame; import com.gempukku.lotro.logic.timing.Effect; @@ -47,6 +48,18 @@ public abstract class AbstractAtTest { return RuleUtils.calculateArcheryTotal(_game, side); } + public boolean hasKeyword(PhysicalCard card, Keyword keyword) { + return _game.getModifiersQuerying().hasKeyword(_game, card, keyword); + } + + public boolean hasSignet(PhysicalCard card, Signet signet) { + return _game.getModifiersQuerying().hasSignet(_game, card, signet); + } + + public void addModifier(Modifier modifier) { + _game.getModifiersEnvironment().addAlwaysOnModifier(modifier); + } + public PhysicalCard getRingBearer(String player) { return _game.getGameState().getRingBearer(player); } @@ -66,6 +79,12 @@ public abstract class AbstractAtTest { return card; } + public PhysicalCard stackOn(PhysicalCard card, PhysicalCard toCard) { + addToZone(card, Zone.STACKED); + ((PhysicalCardImpl) card).stackOn((PhysicalCardImpl) toCard); + return card; + } + public PhysicalCard putOnTopOfDeck(PhysicalCard card) { _game.getGameState().putCardOnTopOfDeck(card); return card; diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/ModifiersAtTest.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/ModifiersAtTest.java new file mode 100644 index 000000000..1d742bfe7 --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/ModifiersAtTest.java @@ -0,0 +1,380 @@ +package com.gempukku.lotro.at; + +import com.gempukku.lotro.cards.build.DefaultActionContext; +import com.gempukku.lotro.cards.build.LotroCardBlueprintBuilder; +import com.gempukku.lotro.cards.build.ModifierSource; +import com.gempukku.lotro.cards.build.field.effect.modifier.*; +import com.gempukku.lotro.common.*; +import com.gempukku.lotro.filters.Filters; +import com.gempukku.lotro.game.PhysicalCard; +import com.gempukku.lotro.logic.GameUtils; +import com.gempukku.lotro.logic.timing.PlayConditions; +import org.json.simple.JSONObject; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class ModifiersAtTest extends AbstractAtTest { + private LotroCardBlueprintBuilder lotroCardBlueprintBuilder = new LotroCardBlueprintBuilder(); + + @Test + public void addKeywordFromCards() throws Exception { + initializeSimplestGame(); + + PhysicalCard gimli = addToZone(createCard(P1, "5_7"), Zone.FREE_CHARACTERS); + PhysicalCard ringBearer = getRingBearer(P1); + + passUntil(Phase.FELLOWSHIP); + + JSONObject obj = new JSONObject(); + obj.put("filter", "ringBearer"); + obj.put("from", "companion,dwarf"); + + ModifierSource modifierSource = new AddKeywordFromCards().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + + assertFalse(hasKeyword(ringBearer, Keyword.DAMAGE)); + addModifier(modifierSource.getModifier(actionContext)); + assertTrue(hasKeyword(ringBearer, Keyword.DAMAGE)); + } + + @Test + public void addSignet() throws Exception { + initializeSimplestGame(); + + PhysicalCard gimli = addToZone(createCard(P1, "5_7"), Zone.FREE_CHARACTERS); + + passUntil(Phase.FELLOWSHIP); + + JSONObject obj = new JSONObject(); + obj.put("filter", "companion,dwarf"); + obj.put("signet", "Frodo"); + + ModifierSource modifierSource = new AddSignet().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + + assertFalse(hasSignet(gimli, Signet.FRODO)); + addModifier(modifierSource.getModifier(actionContext)); + assertTrue(hasSignet(gimli, Signet.FRODO)); + } + + @Test + public void allyCanParticipateInArcheryFire() throws Exception { + initializeSimplestGame(); + + PhysicalCard theGaffer = addToZone(createCard(P1, "1_291"), Zone.SUPPORT); + + passUntil(Phase.FELLOWSHIP); + + JSONObject obj = new JSONObject(); + obj.put("filter", "ally,hobbit"); + + ModifierSource modifierSource = new AllyCanParticipateInArcheryFire().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + + assertFalse(_game.getModifiersQuerying().isAllyAllowedToParticipateInArcheryFire(_game, theGaffer)); + addModifier(modifierSource.getModifier(actionContext)); + assertTrue(_game.getModifiersQuerying().isAllyAllowedToParticipateInArcheryFire(_game, theGaffer)); + } + + @Test + public void allyCanParticipateInSkirmishes() throws Exception { + initializeSimplestGame(); + + PhysicalCard theGaffer = addToZone(createCard(P1, "1_291"), Zone.SUPPORT); + + passUntil(Phase.FELLOWSHIP); + + JSONObject obj = new JSONObject(); + obj.put("filter", "ally,hobbit"); + + ModifierSource modifierSource = new AllyCanParticipateInSkirmishes().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + + assertFalse(_game.getModifiersQuerying().isAllyAllowedToParticipateInSkirmishes(_game, Side.FREE_PEOPLE, theGaffer)); + addModifier(modifierSource.getModifier(actionContext)); + assertTrue(_game.getModifiersQuerying().isAllyAllowedToParticipateInSkirmishes(_game, Side.FREE_PEOPLE, theGaffer)); + } + + @Test + public void canPlayStackedCards() throws Exception { + initializeSimplestGame(); + + PhysicalCard sindriDwarvenLord = addToZone(createCard(P1, "9_10"), Zone.FREE_CHARACTERS); + PhysicalCard greatestKingdomOfOurPeople = addToZone(createCard(P1, "1_16"), Zone.SUPPORT); + PhysicalCard cleavingBlow = stackOn(createCard(P1, "1_5"), greatestKingdomOfOurPeople); + PhysicalCard goblinRunner = addToZone(createCard(P2, "1_178"), Zone.SHADOW_CHARACTERS); + + passUntil(Phase.ASSIGNMENT); + pass(P1); + pass(P2); + playerDecided(P1, sindriDwarvenLord.getCardId() + " " + goblinRunner.getCardId()); + selectCard(P1, sindriDwarvenLord); + hasCardAction(P1, cleavingBlow); + } + + @Test + public void cantBeOverwhelmed() throws Exception { + initializeSimplestGame(); + + PhysicalCard gimli = addToZone(createCard(P1, "5_7"), Zone.FREE_CHARACTERS); + + passUntil(Phase.FELLOWSHIP); + + JSONObject obj = new JSONObject(); + obj.put("filter", "companion,dwarf"); + + ModifierSource modifierSource = new CantBeOverwhelmed().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + + assertEquals(2, _game.getModifiersQuerying().getOverwhelmMultiplier(_game, gimli)); + addModifier(modifierSource.getModifier(actionContext)); + assertEquals(10000, _game.getModifiersQuerying().getOverwhelmMultiplier(_game, gimli)); + } + + @Test + public void cantPlayCardsOn() throws Exception { + initializeSimplestGame(); + + PhysicalCard hobbitSword = addToZone(createCard(P1, "1_299"), Zone.HAND); + + JSONObject obj = new JSONObject(); + obj.put("filter", "possession"); + obj.put("on", "ringBearer"); + + ModifierSource modifierSource = new CantPlayCardsOn().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + + addModifier(modifierSource.getModifier(actionContext)); + + passUntil(Phase.FELLOWSHIP); + assertNull(getCardActionId(P1, hobbitSword)); + } + + @Test + public void cantPlayPhaseEvents() throws Exception { + initializeSimplestGame(); + + PhysicalCard elfSong = addToZone(createCard(P1, "1_39"), Zone.HAND); + PhysicalCard elrond = addToZone(createCard(P1, "1_40"), Zone.FREE_CHARACTERS); + + JSONObject obj = new JSONObject(); + obj.put("phase", "fellowship"); + + ModifierSource modifierSource = new CantPlayPhaseEvents().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + + addModifier(modifierSource.getModifier(actionContext)); + + passUntil(Phase.FELLOWSHIP); + assertNull(getCardActionId(P1, elfSong)); + } + + @Test + public void cantPlaySite() throws Exception { + initializeSimplestGame(); + + JSONObject obj = new JSONObject(); + obj.put("player", "fp"); + + ModifierSource modifierSource = new CantPlaySite().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + + passUntil(Phase.FELLOWSHIP); + + assertTrue(_game.getModifiersQuerying().canPlaySite(_game, P1)); + addModifier(modifierSource.getModifier(actionContext)); + assertFalse(_game.getModifiersQuerying().canPlaySite(_game, P1)); + } + + @Test + public void cantRemoveThreats() throws Exception { + initializeSimplestGame(); + + PhysicalCard ringBearer = getRingBearer(P1); + + JSONObject obj = new JSONObject(); + obj.put("filter", "ringBearer"); + + ModifierSource modifierSource = new CantRemoveThreats().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + + passUntil(Phase.FELLOWSHIP); + + assertTrue(_game.getModifiersQuerying().canRemoveThreat(_game, ringBearer)); + addModifier(modifierSource.getModifier(actionContext)); + assertFalse(_game.getModifiersQuerying().canRemoveThreat(_game, ringBearer)); + } + + @Test + public void cantTakeArcheryWounds() throws Exception { + initializeSimplestGame(); + + PhysicalCard haradrimMarksman = addToZone(createCard(P2, "8_60"), Zone.SHADOW_CHARACTERS); + PhysicalCard ringBearer = getRingBearer(P1); + + passUntil(Phase.ARCHERY); + assertTrue(_game.getModifiersQuerying().canTakeArcheryWound(_game, ringBearer)); + addToZone(createCard(P2, "8_49"), Zone.SHADOW_CHARACTERS); + assertFalse(_game.getModifiersQuerying().canTakeArcheryWound(_game, ringBearer)); + } + + @Test + public void cantTakeWoundsFromLosingSkirmish() throws Exception { + initializeSimplestGame(); + + PhysicalCard ringBearer = getRingBearer(P1); + + JSONObject obj = new JSONObject(); + obj.put("filter", "ringBearer"); + + ModifierSource modifierSource = new CantTakeWoundsFromLosingSkirmish().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + + passUntil(Phase.FELLOWSHIP); + + assertTrue(_game.getModifiersQuerying().canTakeWoundsFromLosingSkirmish(_game, ringBearer)); + addModifier(modifierSource.getModifier(actionContext)); + assertFalse(_game.getModifiersQuerying().canTakeWoundsFromLosingSkirmish(_game, ringBearer)); + } + + @Test + public void cantUseSpecialAbilities() throws Exception { + initializeSimplestGame(); + + PhysicalCard elrond = addToZone(createCard(P1, "1_40"), Zone.FREE_CHARACTERS); + + JSONObject obj = new JSONObject(); + obj.put("phase", "fellowship"); + obj.put("filter", "elf"); + + ModifierSource modifierSource = new CantUseSpecialAbilities().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + addModifier(modifierSource.getModifier(actionContext)); + + passUntil(Phase.FELLOWSHIP); + assertNull(getCardActionId(P1, elrond)); + } + + @Test + public void disableGameText() throws Exception { + initializeSimplestGame(); + + PhysicalCard elrond = addToZone(createCard(P1, "1_40"), Zone.FREE_CHARACTERS); + + JSONObject obj = new JSONObject(); + obj.put("filter", "elf"); + + ModifierSource modifierSource = new DisableGameText().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + addModifier(modifierSource.getModifier(actionContext)); + + passUntil(Phase.FELLOWSHIP); + assertNull(getCardActionId(P1, elrond)); + } + + @Test + public void doesNotAddToArcheryTotal() throws Exception { + initializeSimplestGame(); + + PhysicalCard goblinMarksman = addToZone(createCard(P2, "1_176"), Zone.SHADOW_CHARACTERS); + + JSONObject obj = new JSONObject(); + obj.put("filter", "minion"); + + ModifierSource modifierSource = new DoesNotAddToArcheryTotal().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + + passUntil(Phase.ARCHERY); + assertEquals(1, getArcheryTotal(Side.SHADOW)); + addModifier(modifierSource.getModifier(actionContext)); + assertEquals(0, getArcheryTotal(Side.SHADOW)); + } + + @Test + public void fpCultureSpot() throws Exception { + initializeSimplestGame(); + + JSONObject obj = new JSONObject(); + obj.put("amount", 1); + + ModifierSource modifierSource = new FPCultureSpot().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + + passUntil(Phase.FELLOWSHIP); + assertEquals(1, GameUtils.getSpottableFPCulturesCount(_game, P1)); + addModifier(modifierSource.getModifier(actionContext)); + assertEquals(2, GameUtils.getSpottableFPCulturesCount(_game, P1)); + } + + @Test + public void modifyInitiativeHandSize() throws Exception { + initializeSimplestGame(); + + JSONObject obj = new JSONObject(); + obj.put("amount", -4); + + ModifierSource modifierSource = new ModifyInitiativeHandSize().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + + passUntil(Phase.FELLOWSHIP); + assertFalse(PlayConditions.hasInitiative(_game, Side.FREE_PEOPLE)); + addModifier(modifierSource.getModifier(actionContext)); + assertTrue(PlayConditions.hasInitiative(_game, Side.FREE_PEOPLE)); + } + + @Test + public void modifyVitality() throws Exception { + initializeSimplestGame(); + + PhysicalCard ringBearer = getRingBearer(P1); + + JSONObject obj = new JSONObject(); + obj.put("filter", "ringBearer"); + obj.put("amount", 1); + + ModifierSource modifierSource = new ModifyVitality().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + + passUntil(Phase.FELLOWSHIP); + assertEquals(4, _game.getModifiersQuerying().getVitality(_game, ringBearer)); + addModifier(modifierSource.getModifier(actionContext)); + assertEquals(5, _game.getModifiersQuerying().getVitality(_game, ringBearer)); + } + + @Test + public void removeAllKeywords() throws Exception { + initializeSimplestGame(); + + PhysicalCard gimli = addToZone(createCard(P1, "5_7"), Zone.FREE_CHARACTERS); + + JSONObject obj = new JSONObject(); + obj.put("filter", "dwarf,companion"); + + ModifierSource modifierSource = new RemoveAllKeywords().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + + passUntil(Phase.FELLOWSHIP); + assertTrue(hasKeyword(gimli, Keyword.DAMAGE)); + addModifier(modifierSource.getModifier(actionContext)); + assertFalse(hasKeyword(gimli, Keyword.DAMAGE)); + } + + @Test + public void unhastyCompanionCanParticipateInSkirmishes() throws Exception { + initializeSimplestGame(); + + PhysicalCard birchseed = addToZone(createCard(P1, "5_15"), Zone.FREE_CHARACTERS); + + JSONObject obj = new JSONObject(); + obj.put("filter", "ent"); + + ModifierSource modifierSource = new UnhastyCompanionCanParticipateInSkirmishes().getModifierSource(obj, lotroCardBlueprintBuilder); + DefaultActionContext actionContext = new DefaultActionContext(P1, _game, null, null, null); + + passUntil(Phase.FELLOWSHIP); + assertFalse(Filters.assignableToSkirmish(Side.FREE_PEOPLE, false, false).accepts(_game, birchseed)); + addModifier(modifierSource.getModifier(actionContext)); + assertTrue(Filters.assignableToSkirmish(Side.FREE_PEOPLE, false, false).accepts(_game, birchseed)); + } +}