From f12987277bc6e92efe48483cc84bb5af093776f9 Mon Sep 17 00:00:00 2001 From: Christian 'ketura' McCarty Date: Sun, 4 Jun 2023 17:46:24 -0500 Subject: [PATCH] morgul destroyer errata + tests --- .../lotro/cards/GenericCardTestHelper.java | 49 ++++- .../errata/set07/Card_07_190_ErrataTests.java | 169 ++++++++++++++++++ 2 files changed, 214 insertions(+), 4 deletions(-) create mode 100644 gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set07/Card_07_190_ErrataTests.java diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/GenericCardTestHelper.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/GenericCardTestHelper.java index 65b3726e8..328ee2096 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/GenericCardTestHelper.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/GenericCardTestHelper.java @@ -621,7 +621,39 @@ public class GenericCardTestHelper extends AbstractAtTest { if(current == target) break; - PassCurrentPhaseActions(); + if(current == Phase.FELLOWSHIP) { + FreepsPassCurrentPhaseAction(); + } + else if(current == Phase.SHADOW) { + ShadowPassCurrentPhaseAction(); + } + else { + PassCurrentPhaseActions(); + } + + if(attempts == 20) + { + throw new DecisionResultInvalidException("Could not arrive at target '" + target + "' after 20 attempts!"); + } + } + } + + public void SkipToPhaseInverted(Phase target) throws DecisionResultInvalidException { + for(int attempts = 1; attempts <= 20; attempts++) + { + Phase current = _game.getGameState().getCurrentPhase(); + if(current == target) + break; + + if(current == Phase.FELLOWSHIP) { + ShadowPassCurrentPhaseAction(); + } + else if(current == Phase.SHADOW) { + FreepsPassCurrentPhaseAction(); + } + else { + PassCurrentPhaseActions(); + } if(attempts == 20) { @@ -864,6 +896,7 @@ public class GenericCardTestHelper extends AbstractAtTest { public void FreepsChooseToMove() throws DecisionResultInvalidException { playerDecided(P1, "0"); } public void FreepsChooseToStay() throws DecisionResultInvalidException { playerDecided(P1, "1"); } + public void ShadowChooseToStay() throws DecisionResultInvalidException { playerDecided(P2, "1"); } public boolean FreepsHasOptionalTriggerAvailable() { return FreepsDecisionAvailable("Optional"); } public boolean ShadowHasOptionalTriggerAvailable() { return ShadowDecisionAvailable("Optional"); } @@ -977,7 +1010,10 @@ public class GenericCardTestHelper extends AbstractAtTest { { ShadowChooseCard((PhysicalCardImpl) GetShadowHand().get(0)); } - FreepsChooseToStay(); + if(FreepsDecisionAvailable("another move")) + { + FreepsChooseToStay(); + } if(FreepsDecisionAvailable("reconcile")) { FreepsDeclineReconciliation(); @@ -988,7 +1024,8 @@ public class GenericCardTestHelper extends AbstractAtTest { } //Shadow player - SkipToPhase(Phase.REGROUP); + SkipToPhaseInverted(Phase.REGROUP); + ShadowPassCurrentPhaseAction(); // actually freeps with the swap FreepsPassCurrentPhaseAction(); // actually shadow with the swap if(FreepsDecisionAvailable("reconcile")) { @@ -998,7 +1035,10 @@ public class GenericCardTestHelper extends AbstractAtTest { { FreepsChooseCard((PhysicalCardImpl) GetFreepsHand().get(0)); } - ShadowChoose("1"); // Choose to stay + if(ShadowDecisionAvailable("another move")) + { + ShadowChoose("1"); // Choose to stay + } if(ShadowDecisionAvailable("reconcile")) { ShadowDeclineReconciliation(); @@ -1007,6 +1047,7 @@ public class GenericCardTestHelper extends AbstractAtTest { { ShadowChooseCard((PhysicalCardImpl) GetShadowHand().get(0)); } + Assert.assertTrue(GetCurrentPhase() == Phase.BETWEEN_TURNS || GetCurrentPhase() == Phase.FELLOWSHIP); } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set07/Card_07_190_ErrataTests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set07/Card_07_190_ErrataTests.java new file mode 100644 index 000000000..9689d869b --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set07/Card_07_190_ErrataTests.java @@ -0,0 +1,169 @@ +package com.gempukku.lotro.cards.unofficial.pc.errata.set07; + +import com.gempukku.lotro.cards.GenericCardTestHelper; +import com.gempukku.lotro.common.*; +import com.gempukku.lotro.game.CardNotFoundException; +import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; +import org.junit.Test; + +import java.util.HashMap; + +import static org.junit.Assert.*; + +public class Card_07_190_ErrataTests +{ + + protected GenericCardTestHelper GetScenario() throws CardNotFoundException, DecisionResultInvalidException { + return new GenericCardTestHelper( + new HashMap<>() + {{ + put("destroyer", "77_190"); + put("destroyer2", "77_190"); + put("nazgul", "1_229"); + }}, + GenericCardTestHelper.FellowshipSites, + GenericCardTestHelper.FOTRFrodo, + GenericCardTestHelper.FOTRRing + ); + } + + @Test + public void MorgulDestroyerStatsAndKeywordsAreCorrect() throws DecisionResultInvalidException, CardNotFoundException { + + /** + * Set: 7 + * Title: Morgul Destroyer + * Unique: False + * Side: SHADOW + * Culture: Wraith + * Twilight Cost: 3 + * Type: minion + * Subtype: Orc + * Strength: 6 + * Vitality: 2 + * Site Number: 4 + * Game Text: When you play this minion, you may spot a Nazgûl to add a threat. The + * Free Peoples player may make you wound a companion to prevent this.
Skirmish: Remove a threat to make this minion strength +4. + */ + + //Pre-game setup + var scn = GetScenario(); + + var destroyer = scn.GetFreepsCard("destroyer"); + + assertFalse(destroyer.getBlueprint().isUnique()); + assertEquals(Side.SHADOW, destroyer.getBlueprint().getSide()); + assertEquals(Culture.WRAITH, destroyer.getBlueprint().getCulture()); + assertEquals(CardType.MINION, destroyer.getBlueprint().getCardType()); + assertEquals(Race.ORC, destroyer.getBlueprint().getRace()); + assertEquals(3, destroyer.getBlueprint().getTwilightCost()); + assertEquals(6, destroyer.getBlueprint().getStrength()); + assertEquals(2, destroyer.getBlueprint().getVitality()); + assertEquals(4, destroyer.getBlueprint().getSiteNumber()); + } + + @Test + public void PlayingDestroyerWithNoNazgulDoesNothing() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var destroyer = scn.GetShadowCard("destroyer"); + scn.ShadowMoveCardToHand(destroyer); + + scn.StartGame(); + scn.SetTwilight(20); + scn.FreepsPassCurrentPhaseAction(); + + assertEquals(0, scn.GetThreats()); + assertTrue(scn.ShadowPlayAvailable(destroyer)); + scn.ShadowPlayCard(destroyer); + assertEquals(0, scn.GetThreats()); + assertFalse(scn.ShadowHasOptionalTriggerAvailable()); + } + + @Test + public void PlayingDestroyerWithNazgulAddsAThreatIfNotPrevented() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var destroyer = scn.GetShadowCard("destroyer"); + var nazgul = scn.GetShadowCard("nazgul"); + scn.ShadowMoveCardToHand(destroyer); + scn.ShadowMoveCharToTable(nazgul); + + scn.StartGame(); + scn.SetTwilight(20); + scn.FreepsPassCurrentPhaseAction(); + + assertEquals(0, scn.GetThreats()); + assertTrue(scn.ShadowPlayAvailable(destroyer)); + scn.ShadowPlayCard(destroyer); + + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + scn.ShadowDecisionAvailable("Would you like to spot a Nazgul to add 1 threat?"); + scn.ShadowAcceptOptionalTrigger(); + + assertTrue(scn.FreepsDecisionAvailable("Make the Shadow player wound a companion to prevent adding a threat?")); + scn.FreepsChooseNo(); + + assertEquals(1, scn.GetThreats()); + } + + @Test + public void DestroyerAddingAThreatCanBePreventedByFreepsLettingShadowWoundSomeone() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var frodo = scn.GetRingBearer(); + + var destroyer = scn.GetShadowCard("destroyer"); + var nazgul = scn.GetShadowCard("nazgul"); + scn.ShadowMoveCardToHand(destroyer); + scn.ShadowMoveCharToTable(nazgul); + + scn.StartGame(); + scn.SetTwilight(20); + scn.FreepsPassCurrentPhaseAction(); + + assertEquals(0, scn.GetThreats()); + assertTrue(scn.ShadowPlayAvailable(destroyer)); + scn.ShadowPlayCard(destroyer); + + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + scn.ShadowAcceptOptionalTrigger(); + + assertEquals(0, scn.GetWoundsOn(frodo)); + assertTrue(scn.FreepsDecisionAvailable("Make the Shadow player wound a companion to prevent adding a threat?")); + scn.FreepsChooseYes(); + + //Wound automatically applied since there's only one choice + assertEquals(1, scn.GetWoundsOn(frodo)); + assertEquals(0, scn.GetThreats()); + } + + @Test + public void DestroyerSkirmishActionRemovesAThreatToPump4() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var frodo = scn.GetRingBearer(); + + var destroyer = scn.GetShadowCard("destroyer"); + scn.ShadowMoveCharToTable(destroyer); + + scn.StartGame(); + scn.AddThreats(2); + scn.SkipToAssignments(); + + scn.FreepsAssignToMinions(frodo, destroyer); + scn.FreepsResolveSkirmish(frodo); + + scn.FreepsPassCurrentPhaseAction(); + assertTrue(scn.ShadowActionAvailable(destroyer)); + assertEquals(2, scn.GetThreats()); + assertEquals(6, scn.GetStrength(destroyer)); + scn.ShadowUseCardAction(destroyer); + assertEquals(1, scn.GetThreats()); + assertEquals(10, scn.GetStrength(destroyer)); + } +}