From 21dfcc3a0a2b836ef2f8764aea1bd702f9e2ba4d Mon Sep 17 00:00:00 2001 From: Christian 'ketura' McCarty Date: Wed, 28 Dec 2022 01:37:19 -0600 Subject: [PATCH] Fixed Cavern Entrance automatically exerting the site owner's character in the skirmish, and added extensive unit tests for this card. --- .../pc/errata/set11/set11-Sites-errata.hjson | 93 +++-- .../errata/set11/Card_11_232_ErrataTests.java | 355 ++++++++++++++++-- 2 files changed, 389 insertions(+), 59 deletions(-) diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set11/set11-Sites-errata.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set11/set11-Sites-errata.hjson index 00cd1f6f6..1e3a258d8 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set11/set11-Sites-errata.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set11/set11-Sites-errata.hjson @@ -94,37 +94,70 @@ type: Site block: Shadows direction: Left - effects: [ - { - type: trigger - trigger: { - type: startOfPhase - phase: skirmish - } - cost: { - type: exert - filter: choose(your,character,InSkirmish) - } - effect: [ - { - type: addmodifier - modifier: { - type: cantUseSpecialAbilities - filter: side(freeps) - } - until: end(skirmish) - } - { - type: addmodifier - modifier: { - type: cantUseSpecialAbilities - filter: side(shadow) - } - until: end(skirmish) - } - ] - } + keywords: [ + underground ] + effects: { + type: trigger + trigger: { + type: startOfPhase + phase: skirmish + } + effect: [ + { + type: ForEachPlayer + effect: [ + { + type: conditional + requires: { + type: CanSpot + filter: your,InSkirmish,character,not(exhausted) + } + effect: [ + { + type: chooseYesOrNo + text: Would you like to exert your skirmishing character to prevent all special abilities from being used this skirmish? + memorize: choice + } + { + type: conditional + requires: { + type: memoryIs + memory: choice + value: yes + } + effect: { + type: CostToEffect + cost: { + type: exert + filter: choose(your,character,InSkirmish) + } + effect: [ + { + type: addmodifier + modifier: { + type: cantUseSpecialAbilities + filter: side(freeps) + } + until: end(skirmish) + } + { + type: addmodifier + modifier: { + type: cantUseSpecialAbilities + filter: side(shadow) + } + until: end(skirmish) + } + ] + } + } + ] + } + ] + } + ] + } gametext: Underground. At the start of each skirmish, you may exert your character in that skirmish to prevent special abilities being used. lore: "" promotext: "" diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set11/Card_11_232_ErrataTests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set11/Card_11_232_ErrataTests.java index 7d564f155..18f900999 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set11/Card_11_232_ErrataTests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set11/Card_11_232_ErrataTests.java @@ -1,18 +1,18 @@ package com.gempukku.lotro.cards.unofficial.pc.errata.set11; import com.gempukku.lotro.cards.GenericCardTestHelper; -import com.gempukku.lotro.common.*; +import com.gempukku.lotro.common.CardType; +import com.gempukku.lotro.common.Keyword; +import com.gempukku.lotro.common.Phase; +import com.gempukku.lotro.common.SitesBlock; import com.gempukku.lotro.game.CardNotFoundException; import com.gempukku.lotro.game.PhysicalCardImpl; import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; -import com.gempukku.lotro.logic.modifiers.MoveLimitModifier; import org.junit.Test; import java.util.HashMap; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; public class Card_11_232_ErrataTests { @@ -21,18 +21,30 @@ public class Card_11_232_ErrataTests return new GenericCardTestHelper( new HashMap() {{ - put("card", "81_232"); - // put other cards in here as needed for the test case + put("gimli", "1_13"); + put("boromir", "1_97"); + + put("soldier1", "1_271"); + put("soldier2", "1_271"); + }}, + new HashMap<>() {{ + put("cavern", "81_232"); + put("site2", "11_237"); + put("site3", "11_237"); + put("site4", "11_237"); + put("site5", "11_237"); + put("site6", "11_237"); + put("site7", "11_237"); + put("site8", "11_237"); + put("site9", "11_237"); }}, - GenericCardTestHelper.FellowshipSites, GenericCardTestHelper.FOTRFrodo, - GenericCardTestHelper.FOTRRing + GenericCardTestHelper.ATARRing, + "open" ); } - // Uncomment both @Test markers below once this is ready to be used - - //@Test + @Test public void CavernEntranceStatsAndKeywordsAreCorrect() throws DecisionResultInvalidException, CardNotFoundException { /** @@ -49,34 +61,319 @@ public class Card_11_232_ErrataTests //Pre-game setup GenericCardTestHelper scn = GetScenario(); - PhysicalCardImpl card = scn.GetFreepsCard("card"); + PhysicalCardImpl card = scn.GetFreepsSite("Cavern Entrance"); assertFalse(card.getBlueprint().isUnique()); - //assertEquals(Side., card.getBlueprint().getSide()); - //assertEquals(Culture., card.getBlueprint().getCulture()); assertEquals(CardType.SITE, card.getBlueprint().getCardType()); - //assertEquals(Race.CREATURE, card.getBlueprint().getRace()); - assertTrue(scn.HasKeyword(card, Keyword.SUPPORT_AREA)); + assertTrue(scn.HasKeyword(card, Keyword.UNDERGROUND)); + assertEquals(SitesBlock.SHADOWS, card.getBlueprint().getSiteBlock()); assertEquals(1, card.getBlueprint().getTwilightCost()); - //assertEquals(, card.getBlueprint().getStrength()); - //assertEquals(, card.getBlueprint().getVitality()); - //assertEquals(, card.getBlueprint().getResistance()); - //assertEquals(Signet., card.getBlueprint().getSignet()); - //assertEquals(, card.getBlueprint().getSiteNumber()); // Change this to getAllyHomeSiteNumbers for allies - } - //@Test - public void CavernEntranceTest1() throws DecisionResultInvalidException, CardNotFoundException { + @Test + public void CavernEntranceDoesNotBlockIfBothDecline() throws DecisionResultInvalidException, CardNotFoundException { //Pre-game setup GenericCardTestHelper scn = GetScenario(); - PhysicalCardImpl card = scn.GetFreepsCard("card"); - scn.FreepsMoveCardToHand(card); + PhysicalCardImpl gimli = scn.GetFreepsCard("gimli"); + PhysicalCardImpl boromir = scn.GetFreepsCard("boromir"); + PhysicalCardImpl cavern = scn.GetShadowSite("Cavern Entrance"); + PhysicalCardImpl site1 = scn.GetFreepsSite("Ettenmoors"); + scn.FreepsMoveCharToTable(gimli, boromir); + + PhysicalCardImpl soldier1 = scn.GetShadowCard("soldier1"); + PhysicalCardImpl soldier2 = scn.GetShadowCard("soldier2"); + scn.ShadowMoveCharToTable(soldier1, soldier2); + + scn.FreepsChooseCardBPFromSelection(site1); + scn.SkipStartingFellowships(); scn.StartGame(); - scn.FreepsPlayCard(card); - assertEquals(1, scn.GetTwilight()); + scn.FreepsPassCurrentPhaseAction(); + scn.ShadowChooseCardBPFromSelection(cavern); + + scn.SkipToPhase(Phase.ASSIGNMENT); + scn.PassCurrentPhaseActions(); + + scn.FreepsAssignToMinions(gimli, soldier1); + scn.ShadowDeclineAssignments(); + scn.FreepsResolveSkirmish(gimli); + + assertTrue(scn.FreepsDecisionAvailable("prevent all special abilities")); + scn.FreepsChooseNo(); + assertTrue(scn.ShadowDecisionAvailable("prevent all special abilities")); + scn.ShadowChooseNo(); + assertTrue(scn.FreepsActionAvailable(gimli)); + assertTrue(scn.FreepsActionAvailable(boromir)); + scn.FreepsPassCurrentPhaseAction(); + assertTrue(scn.ShadowActionAvailable(soldier1)); + assertTrue(scn.ShadowActionAvailable(soldier2)); + } + + @Test + public void CavernEntranceDoesNotBlockOrOfferIfBothExhausted() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + GenericCardTestHelper scn = GetScenario(); + + PhysicalCardImpl gimli = scn.GetFreepsCard("gimli"); + PhysicalCardImpl boromir = scn.GetFreepsCard("boromir"); + PhysicalCardImpl cavern = scn.GetShadowSite("Cavern Entrance"); + PhysicalCardImpl site1 = scn.GetFreepsSite("Ettenmoors"); + scn.FreepsMoveCharToTable(gimli, boromir); + + PhysicalCardImpl soldier1 = scn.GetShadowCard("soldier1"); + PhysicalCardImpl soldier2 = scn.GetShadowCard("soldier2"); + scn.ShadowMoveCharToTable(soldier1, soldier2); + + scn.AddWoundsToChar(gimli, 2); + scn.AddWoundsToChar(soldier1, 1); + + scn.FreepsChooseCardBPFromSelection(site1); + scn.SkipStartingFellowships(); + + scn.StartGame(); + + scn.FreepsPassCurrentPhaseAction(); + scn.ShadowChooseCardBPFromSelection(cavern); + + scn.SkipToPhase(Phase.ASSIGNMENT); + scn.PassCurrentPhaseActions(); + + scn.FreepsAssignToMinions(gimli, soldier1); + scn.ShadowDeclineAssignments(); + scn.FreepsResolveSkirmish(gimli); + + assertFalse(scn.FreepsDecisionAvailable("prevent all special abilities")); + assertFalse(scn.ShadowDecisionAvailable("prevent all special abilities")); + assertFalse(scn.FreepsActionAvailable(gimli)); + assertTrue(scn.FreepsActionAvailable(boromir)); + scn.FreepsPassCurrentPhaseAction(); + assertTrue(scn.ShadowActionAvailable(soldier2)); + var choices = scn.ShadowGetCardChoices(); + assertEquals(1, choices.size()); // soldier2 but not soldier1 + assertEquals("" + soldier2.getCardId(), choices.get(0)); + assertTrue(scn.ShadowActionAvailable(soldier2)); + } + + @Test + public void CavernEntranceBlocksIfFreepsExhaustedButShadowAccepts() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + GenericCardTestHelper scn = GetScenario(); + + PhysicalCardImpl gimli = scn.GetFreepsCard("gimli"); + PhysicalCardImpl boromir = scn.GetFreepsCard("boromir"); + PhysicalCardImpl cavern = scn.GetShadowSite("Cavern Entrance"); + PhysicalCardImpl site1 = scn.GetFreepsSite("Ettenmoors"); + scn.FreepsMoveCharToTable(gimli, boromir); + + PhysicalCardImpl soldier1 = scn.GetShadowCard("soldier1"); + PhysicalCardImpl soldier2 = scn.GetShadowCard("soldier2"); + scn.ShadowMoveCharToTable(soldier1, soldier2); + + scn.AddWoundsToChar(gimli, 2); + + scn.FreepsChooseCardBPFromSelection(site1); + scn.SkipStartingFellowships(); + + scn.StartGame(); + + scn.FreepsPassCurrentPhaseAction(); + scn.ShadowChooseCardBPFromSelection(cavern); + + scn.SkipToPhase(Phase.ASSIGNMENT); + scn.PassCurrentPhaseActions(); + + scn.FreepsAssignToMinions(gimli, soldier1); + scn.ShadowDeclineAssignments(); + scn.FreepsResolveSkirmish(gimli); + + assertFalse(scn.FreepsDecisionAvailable("prevent all special abilities")); + assertTrue(scn.ShadowDecisionAvailable("prevent all special abilities")); + assertEquals(0, scn.GetWoundsOn(soldier1)); + scn.ShadowChooseYes(); + assertEquals(1, scn.GetWoundsOn(soldier1)); + assertEquals(2, scn.GetWoundsOn(gimli)); + assertFalse(scn.FreepsActionAvailable(gimli)); + assertFalse(scn.FreepsActionAvailable(boromir)); + scn.FreepsPassCurrentPhaseAction(); + assertFalse(scn.ShadowActionAvailable(soldier1)); + assertFalse(scn.ShadowActionAvailable(soldier2)); + } + + @Test + public void CavernEntranceBlocksIfShadowExhaustedButFreepsAccepts() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + GenericCardTestHelper scn = GetScenario(); + + PhysicalCardImpl gimli = scn.GetFreepsCard("gimli"); + PhysicalCardImpl boromir = scn.GetFreepsCard("boromir"); + PhysicalCardImpl cavern = scn.GetShadowSite("Cavern Entrance"); + PhysicalCardImpl site1 = scn.GetFreepsSite("Ettenmoors"); + scn.FreepsMoveCharToTable(gimli, boromir); + + PhysicalCardImpl soldier1 = scn.GetShadowCard("soldier1"); + PhysicalCardImpl soldier2 = scn.GetShadowCard("soldier2"); + scn.ShadowMoveCharToTable(soldier1, soldier2); + + scn.AddWoundsToChar(soldier1, 1); + + scn.FreepsChooseCardBPFromSelection(site1); + scn.SkipStartingFellowships(); + + scn.StartGame(); + + scn.FreepsPassCurrentPhaseAction(); + scn.ShadowChooseCardBPFromSelection(cavern); + + scn.SkipToPhase(Phase.ASSIGNMENT); + scn.PassCurrentPhaseActions(); + + scn.FreepsAssignToMinions(gimli, soldier1); + scn.ShadowDeclineAssignments(); + scn.FreepsResolveSkirmish(gimli); + + assertTrue(scn.FreepsDecisionAvailable("prevent all special abilities")); + assertEquals(0, scn.GetWoundsOn(gimli)); + scn.FreepsChooseYes(); + assertEquals(1, scn.GetWoundsOn(gimli)); + assertFalse(scn.ShadowDecisionAvailable("prevent all special abilities")); + assertEquals(1, scn.GetWoundsOn(soldier1)); + assertFalse(scn.FreepsActionAvailable(gimli)); + assertFalse(scn.FreepsActionAvailable(boromir)); + scn.FreepsPassCurrentPhaseAction(); + assertFalse(scn.ShadowActionAvailable(soldier1)); + assertFalse(scn.ShadowActionAvailable(soldier2)); + } + + @Test + public void CavernEntranceBlocksIfFreepsAcceptsButNotShadow() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + GenericCardTestHelper scn = GetScenario(); + + PhysicalCardImpl gimli = scn.GetFreepsCard("gimli"); + PhysicalCardImpl boromir = scn.GetFreepsCard("boromir"); + PhysicalCardImpl cavern = scn.GetShadowSite("Cavern Entrance"); + PhysicalCardImpl site1 = scn.GetFreepsSite("Ettenmoors"); + scn.FreepsMoveCharToTable(gimli, boromir); + + PhysicalCardImpl soldier1 = scn.GetShadowCard("soldier1"); + PhysicalCardImpl soldier2 = scn.GetShadowCard("soldier2"); + scn.ShadowMoveCharToTable(soldier1, soldier2); + + scn.FreepsChooseCardBPFromSelection(site1); + scn.SkipStartingFellowships(); + + scn.StartGame(); + + scn.FreepsPassCurrentPhaseAction(); + scn.ShadowChooseCardBPFromSelection(cavern); + + scn.SkipToPhase(Phase.ASSIGNMENT); + scn.PassCurrentPhaseActions(); + + scn.FreepsAssignToMinions(gimli, soldier1); + scn.ShadowDeclineAssignments(); + scn.FreepsResolveSkirmish(gimli); + + assertTrue(scn.FreepsDecisionAvailable("prevent all special abilities")); + assertEquals(0, scn.GetWoundsOn(gimli)); + scn.FreepsChooseYes(); + assertEquals(1, scn.GetWoundsOn(gimli)); + assertTrue(scn.ShadowDecisionAvailable("prevent all special abilities")); + scn.ShadowChooseNo(); + assertEquals(0, scn.GetWoundsOn(soldier1)); + assertFalse(scn.FreepsActionAvailable(gimli)); + assertFalse(scn.FreepsActionAvailable(boromir)); + scn.FreepsPassCurrentPhaseAction(); + assertFalse(scn.ShadowActionAvailable(soldier1)); + assertFalse(scn.ShadowActionAvailable(soldier2)); + } + + @Test + public void CavernEntranceBlocksIfShadowAcceptsButNotFreeps() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + GenericCardTestHelper scn = GetScenario(); + + PhysicalCardImpl gimli = scn.GetFreepsCard("gimli"); + PhysicalCardImpl boromir = scn.GetFreepsCard("boromir"); + PhysicalCardImpl cavern = scn.GetShadowSite("Cavern Entrance"); + PhysicalCardImpl site1 = scn.GetFreepsSite("Ettenmoors"); + scn.FreepsMoveCharToTable(gimli, boromir); + + PhysicalCardImpl soldier1 = scn.GetShadowCard("soldier1"); + PhysicalCardImpl soldier2 = scn.GetShadowCard("soldier2"); + scn.ShadowMoveCharToTable(soldier1, soldier2); + + scn.FreepsChooseCardBPFromSelection(site1); + scn.SkipStartingFellowships(); + + scn.StartGame(); + + scn.FreepsPassCurrentPhaseAction(); + scn.ShadowChooseCardBPFromSelection(cavern); + + scn.SkipToPhase(Phase.ASSIGNMENT); + scn.PassCurrentPhaseActions(); + + scn.FreepsAssignToMinions(gimli, soldier1); + scn.ShadowDeclineAssignments(); + scn.FreepsResolveSkirmish(gimli); + + assertTrue(scn.FreepsDecisionAvailable("prevent all special abilities")); + scn.FreepsChooseNo(); + assertTrue(scn.ShadowDecisionAvailable("prevent all special abilities")); + assertEquals(0, scn.GetWoundsOn(soldier1)); + scn.ShadowChooseYes(); + assertEquals(1, scn.GetWoundsOn(soldier1)); + assertEquals(0, scn.GetWoundsOn(gimli)); + assertFalse(scn.FreepsActionAvailable(gimli)); + assertFalse(scn.FreepsActionAvailable(boromir)); + scn.FreepsPassCurrentPhaseAction(); + assertFalse(scn.ShadowActionAvailable(soldier1)); + assertFalse(scn.ShadowActionAvailable(soldier2)); + } + + @Test + public void CavernEntranceStillOffersIfFreepsAccepts() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + GenericCardTestHelper scn = GetScenario(); + + PhysicalCardImpl gimli = scn.GetFreepsCard("gimli"); + PhysicalCardImpl boromir = scn.GetFreepsCard("boromir"); + PhysicalCardImpl cavern = scn.GetShadowSite("Cavern Entrance"); + PhysicalCardImpl site1 = scn.GetFreepsSite("Ettenmoors"); + scn.FreepsMoveCharToTable(gimli, boromir); + + PhysicalCardImpl soldier1 = scn.GetShadowCard("soldier1"); + PhysicalCardImpl soldier2 = scn.GetShadowCard("soldier2"); + scn.ShadowMoveCharToTable(soldier1, soldier2); + + scn.FreepsChooseCardBPFromSelection(site1); + scn.SkipStartingFellowships(); + + scn.StartGame(); + + scn.FreepsPassCurrentPhaseAction(); + scn.ShadowChooseCardBPFromSelection(cavern); + + scn.SkipToPhase(Phase.ASSIGNMENT); + scn.PassCurrentPhaseActions(); + + scn.FreepsAssignToMinions(gimli, soldier1); + scn.ShadowDeclineAssignments(); + scn.FreepsResolveSkirmish(gimli); + + assertTrue(scn.FreepsDecisionAvailable("prevent all special abilities")); + scn.FreepsChooseYes(); + assertTrue(scn.ShadowDecisionAvailable("prevent all special abilities")); + assertEquals(0, scn.GetWoundsOn(soldier1)); + scn.ShadowChooseYes(); + assertEquals(1, scn.GetWoundsOn(soldier1)); + assertFalse(scn.FreepsActionAvailable(gimli)); + assertFalse(scn.FreepsActionAvailable(boromir)); + scn.FreepsPassCurrentPhaseAction(); + assertFalse(scn.ShadowActionAvailable(soldier1)); + assertFalse(scn.ShadowActionAvailable(soldier2)); } }