From c838a950b67554881817de8b20b93a4c69a2ffed Mon Sep 17 00:00:00 2001 From: Christian 'ketura' McCarty Date: Sun, 4 Jun 2023 12:37:19 -0500 Subject: [PATCH] Hand of Sauron errata + tests --- .../pc/errata/set03/set03-Sauron-errata.hjson | 91 +++++++++ .../errata/set03/Card_03_090_ErrataTests.java | 180 ++++++++++++++++++ 2 files changed, 271 insertions(+) create mode 100644 gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set03/Card_03_090_ErrataTests.java diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set03/set03-Sauron-errata.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set03/set03-Sauron-errata.hjson index 47abce261..52f1d75e8 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set03/set03-Sauron-errata.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set03/set03-Sauron-errata.hjson @@ -249,6 +249,97 @@ } } + 73_90: { + cardInfo: { + //Either a full URL, or a subpath for the PC image server + imagePath: errata/LOTR-EN03E090.2_card.jpg + //If this is true, then all gameplay-related info outside this cardInfo definition + // will be ignored and the java class loaded instead. + javaClass: false + //This instructs the blueprint generator to insert this card as an alt of the listed + // parent blueprint. Can of course be ommitted if not an errata or promo. + parent: 3_90 + //This is the tree path to use within the alts structure on the parent. + // Can of course be ommitted if parent is null. + parentPath: errata/pc + //Versioning differentiates releases within a particular alt path, such as PC errata + // version 1 vs version 2. PC version 2 will not conflict with, say, Decipher version 2. + //Top-level cards should always be version 0. + version: 2 + collInfo: 3C90 + rarity: C + setNum: "3" + cardNum: 90 + // Standard, Masterwork, Tengwar, FullArt, etc. Top-level cards are always Standard. + style: Standard + } + title: Hand of Sauron + unique: false + side: Shadow + culture: Sauron + twilight: 0 + type: Event + keyword: Maneuver + requires: { + type: canSpot + filter: unique,culture(sauron),minion,not(exhausted) + } + effects: { + type: event + cost: { + type: exert + filter: choose(unique,culture(sauron),minion,not(exhausted)) + }, + effect: [ + { + type: ChooseActiveCards + filter: choose(companion,not(ring-bearer)) + memorize: chosenComp + text: Choose a companion (except the Ring-bearer) to exert and have a borne possession discarded. + } + { + type: ChooseActiveCards + filter: choose(possession,AttachedTo(memory(chosenComp))) + memorize: chosenPoss + text: Choose a possession attached to that companion to discard. + } + + { + type: preventable + player: freeps + cost: { + type: DiscardCardAtRandomFromHand + hand: freeps + count: 1 + forced: false + } + text: Discard a card at random from hand to prevent exerting {chosenComp} and discarding {chosenPoss}? + effect:[ + { + type: Exert + filter: memory(chosenComp) + } + { + type: Discard + filter: memory(chosenPoss) + } + ] + } + ] + } + gametext: Exert a unique [sauron] minion to exert a companion (except the Ring-bearer) and discard a possession attached to that companion. The Free Peoples player may discard 1 card at random from their hand to prevent this. + lore: "'The power of the Ring could not be undone.'" + promotext: "" + alts: { + //These are just CardInfo objects + promos: { + } + //These are full card definitions, with redundant info that is the same as the original card ommitted + errata: { + } + } + } + 53_91: { cardInfo: { //Either a full URL, or a subpath for the PC image server diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set03/Card_03_090_ErrataTests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set03/Card_03_090_ErrataTests.java new file mode 100644 index 000000000..ac8858fca --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set03/Card_03_090_ErrataTests.java @@ -0,0 +1,180 @@ +package com.gempukku.lotro.cards.unofficial.pc.errata.set03; + +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_03_090_ErrataTests +{ + + protected GenericCardTestHelper GetScenario() throws CardNotFoundException, DecisionResultInvalidException { + return new GenericCardTestHelper( + new HashMap<>() + {{ + put("hand", "73_90"); + put("aragorn", "1_89"); + put("anduril", "7_79"); + put("pipe", "1_91"); + put("bow", "1_90"); + + put("warden", "1_259"); + put("orc", "1_266"); + + }}, + GenericCardTestHelper.FellowshipSites, + GenericCardTestHelper.FOTRFrodo, + GenericCardTestHelper.FOTRRing + ); + } + + @Test + public void HandofSauronStatsAndKeywordsAreCorrect() throws DecisionResultInvalidException, CardNotFoundException { + + /** + * Set: 3 + * Title: Hand of Sauron + * Unique: False + * Side: SHADOW + * Culture: Sauron + * Twilight Cost: 0 + * Type: event + * Subtype: Maneuver + * Game Text: Exert a unique [sauron] minion to exert a companion (except the Ring-bearer) and discard a possession attached to that companion. The Free Peoples player may discard 1 hand at random from their hand to prevent this. + */ + + //Pre-game setup + var scn = GetScenario(); + + var hand = scn.GetFreepsCard("hand"); + + assertFalse(hand.getBlueprint().isUnique()); + assertEquals(Side.SHADOW, hand.getBlueprint().getSide()); + assertEquals(Culture.SAURON, hand.getBlueprint().getCulture()); + assertEquals(CardType.EVENT, hand.getBlueprint().getCardType()); + assertTrue(scn.HasKeyword(hand, Keyword.MANEUVER)); + assertEquals(0, hand.getBlueprint().getTwilightCost()); + } + + @Test + public void HandWorksIfNotPrevented() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var aragorn = scn.GetFreepsCard("aragorn"); + var anduril = scn.GetFreepsCard("anduril"); + var bow = scn.GetFreepsCard("bow"); + var pipe = scn.GetFreepsCard("pipe"); + scn.FreepsMoveCharToTable(aragorn); + scn.AttachCardsTo(aragorn, anduril, bow, pipe); + scn.FreepsMoveCardToHand("warden", "orc"); + + var hand = scn.GetShadowCard("hand"); + var warden = scn.GetShadowCard("warden"); + var orc = scn.GetShadowCard("orc"); + scn.ShadowMoveCardToHand(hand); + scn.ShadowMoveCharToTable(warden, orc); + + scn.StartGame(); + scn.SkipToPhase(Phase.MANEUVER); + scn.FreepsPassCurrentPhaseAction(); + + assertTrue(scn.ShadowPlayAvailable(hand)); + assertEquals(0, scn.GetWoundsOn(warden)); + assertEquals(0, scn.GetWoundsOn(orc)); + assertEquals(0, scn.GetWoundsOn(aragorn)); + assertEquals(Zone.ATTACHED, anduril.getZone()); + assertSame(aragorn, anduril.getAttachedTo()); + assertEquals(Zone.ATTACHED, bow.getZone()); + assertSame(aragorn, bow.getAttachedTo()); + assertEquals(Zone.ATTACHED, pipe.getZone()); + assertSame(aragorn, pipe.getAttachedTo()); + assertEquals(2, scn.GetFreepsHandCount()); + assertEquals(0, scn.GetFreepsDiscardCount()); + + scn.ShadowPlayCard(hand); + assertEquals(1, scn.GetWoundsOn(warden)); + assertEquals(0, scn.GetWoundsOn(orc)); + //aragorn automatically chosen as the only non-RB companion to target + assertTrue(scn.ShadowDecisionAvailable("Choose a possession attached to that companion to discard")); + assertEquals(2, scn.GetShadowCardChoiceCount()); + scn.ShadowChooseCard(bow); + + //Freeps given option to prevent + assertTrue(scn.FreepsDecisionAvailable("Discard a card at random from hand to prevent exerting")); + scn.FreepsChooseNo(); + + assertEquals(1, scn.GetWoundsOn(aragorn)); + assertEquals(Zone.ATTACHED, anduril.getZone()); + assertSame(aragorn, anduril.getAttachedTo()); + assertEquals(Zone.DISCARD, bow.getZone()); + assertEquals(Zone.ATTACHED, pipe.getZone()); + assertSame(aragorn, pipe.getAttachedTo()); + assertEquals(2, scn.GetFreepsHandCount()); + assertEquals(1, scn.GetFreepsDiscardCount()); + } + + @Test + public void HandCanBePreventedByFreepsDiscardingFromHandAtRandom() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var aragorn = scn.GetFreepsCard("aragorn"); + var anduril = scn.GetFreepsCard("anduril"); + var bow = scn.GetFreepsCard("bow"); + var pipe = scn.GetFreepsCard("pipe"); + scn.FreepsMoveCharToTable(aragorn); + scn.AttachCardsTo(aragorn, anduril, bow, pipe); + scn.FreepsMoveCardToHand("warden", "orc"); + + var hand = scn.GetShadowCard("hand"); + var warden = scn.GetShadowCard("warden"); + var orc = scn.GetShadowCard("orc"); + scn.ShadowMoveCardToHand(hand); + scn.ShadowMoveCharToTable(warden, orc); + + scn.StartGame(); + scn.SkipToPhase(Phase.MANEUVER); + scn.FreepsPassCurrentPhaseAction(); + + assertTrue(scn.ShadowPlayAvailable(hand)); + assertEquals(0, scn.GetWoundsOn(warden)); + assertEquals(0, scn.GetWoundsOn(orc)); + assertEquals(0, scn.GetWoundsOn(aragorn)); + assertEquals(Zone.ATTACHED, anduril.getZone()); + assertSame(aragorn, anduril.getAttachedTo()); + assertEquals(Zone.ATTACHED, bow.getZone()); + assertSame(aragorn, bow.getAttachedTo()); + assertEquals(Zone.ATTACHED, pipe.getZone()); + assertSame(aragorn, pipe.getAttachedTo()); + assertEquals(2, scn.GetFreepsHandCount()); + assertEquals(0, scn.GetFreepsDiscardCount()); + + scn.ShadowPlayCard(hand); + assertEquals(1, scn.GetWoundsOn(warden)); + assertEquals(0, scn.GetWoundsOn(orc)); + //aragorn automatically chosen as the only non-RB companion to target + assertTrue(scn.ShadowDecisionAvailable("Choose a possession attached to that companion to discard")); + assertEquals(2, scn.GetShadowCardChoiceCount()); + scn.ShadowChooseCard(bow); + + //Freeps given option to prevent + assertTrue(scn.FreepsDecisionAvailable("Discard a card at random from hand to prevent exerting")); + scn.FreepsChooseYes(); + + assertEquals(0, scn.GetWoundsOn(aragorn)); + assertEquals(Zone.ATTACHED, anduril.getZone()); + assertSame(aragorn, anduril.getAttachedTo()); + assertEquals(Zone.ATTACHED, bow.getZone()); + assertSame(aragorn, bow.getAttachedTo()); + assertEquals(Zone.ATTACHED, pipe.getZone()); + assertSame(aragorn, pipe.getAttachedTo()); + assertEquals(1, scn.GetFreepsHandCount()); + assertEquals(1, scn.GetFreepsDiscardCount()); + } +}