diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set01/set1-wraith.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set01/set1-wraith.hjson index ad86a8d6d..8cd31787a 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set01/set1-wraith.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set01/set1-wraith.hjson @@ -976,10 +976,22 @@ site: 3 effects: { type: trigger + optional: true trigger: { type: played filter: self } + requires: [ + { + type: CanSpot + filter: companion + count: 5 + } + { + type: PlayableFromDiscard + filter: minion + } + ] effect: [ { type: MemorizeInfo @@ -987,61 +999,47 @@ info: yes } { - type: If - check: [ - { - type: CanSpot - filter: companion - count: 5 - } - { - type: PlayableFromDiscard - filter: minion - } - ] - true: { - type: Repeat - times: { - type: forEachYouCanSpot - filter: companion - over: 4 - } - effect: { - type: If - check: [ - { - type: MemoryIs - memory: choice - value: yes - } - { - type: HasCardInDiscard - filter: playable,minion - } - ] - true: [ - { - type: chooseYesOrNo - player: you - text: Would you like to play a minion from your discard? - memorize: choice - } - { - type: if - check: [ - { - type: MemoryIs - memory: choice - value: yes - } - ] - true: { - type: playCardFromDiscard - select: choose(minion) + type: Repeat + times: { + type: forEachYouCanSpot + filter: companion + over: 4 + } + effect: { + type: if + check: [ + { + type: MemoryIs + memory: choice + value: yes + } + { + type: HasCardInDiscard + filter: playable,minion + } + ] + true: [ + { + type: chooseYesOrNo + player: you + text: Would you like to play a minion from your discard? + memorize: choice + } + { + type: if + check: [ + { + type: MemoryIs + memory: choice + value: yes } + ] + true: { + type: playCardFromDiscard + select: choose(minion) } - ] - } + } + ] } } ] diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set01/set01-Ringwraith-errata.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set01/set01-Ringwraith-errata.hjson index 05b277cef..60fc6e260 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set01/set01-Ringwraith-errata.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set01/set01-Ringwraith-errata.hjson @@ -26,10 +26,22 @@ site: 3 effects: { type: trigger + optional: true trigger: { type: played filter: self } + requires: [ + { + type: CanSpot + filter: companion + count: 5 + } + { + type: PlayableFromDiscard + filter: minion + } + ] effect: [ { type: MemorizeInfo @@ -37,61 +49,47 @@ info: yes } { - type: If - check: [ - { - type: CanSpot - filter: companion - count: 5 - } - { - type: PlayableFromDiscard - filter: unique,culture(wraith),minion - } - ] - true: { - type: Repeat - times: { - type: forEachYouCanSpot - filter: companion - over: 4 - } - effect: { - type: If - check: [ - { - type: MemoryIs - memory: choice - value: yes - } - { - type: HasCardInDiscard - filter: playable,unique,culture(wraith),minion - } - ] - true: [ - { - type: chooseYesOrNo - player: you - text: Would you like to play a unique WRAITH minion from your discard? - memorize: choice - } - { - type: if - check: [ - { - type: MemoryIs - memory: choice - value: yes - } - ] - true: { - type: playCardFromDiscard - select: choose(unique,culture(wraith),minion) + type: Repeat + times: { + type: forEachYouCanSpot + filter: companion + over: 4 + } + effect: { + type: if + check: [ + { + type: MemoryIs + memory: choice + value: yes + } + { + type: HasCardInDiscard + filter: playable,unique,culture(wraith),minion + } + ] + true: [ + { + type: chooseYesOrNo + player: you + text: Would you like to play a unique WRAITH minion from your discard? + memorize: choice + } + { + type: if + check: [ + { + type: MemoryIs + memory: choice + value: yes } + ] + true: { + type: playCardFromDiscard + select: choose(unique,culture(wraith),minion) } - ] - } + } + ] } } ] diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/filters/Filters.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/filters/Filters.java index 6dbc1082b..7a5c92887 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/filters/Filters.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/filters/Filters.java @@ -243,7 +243,13 @@ public class Filters { || game.getModifiersQuerying().isUnhastyCompanionAllowedToParticipateInSkirmishes(game, physicalCard)), Filters.and( CardType.MINION, - (Filter) (game, physicalCard) -> (!game.getGameState().isFierceSkirmishes()) || game.getModifiersQuerying().hasKeyword(game, physicalCard, Keyword.FIERCE))); + Filters.notAssignedToSkirmish, + new Filter() { + @Override + public boolean accepts(LotroGame game, PhysicalCard physicalCard) { + return (game.getGameState().getCurrentPhase() != Phase.ASSIGNMENT || !game.getGameState().isFierceSkirmishes()) || game.getModifiersQuerying().hasKeyword(game, physicalCard, Keyword.FIERCE); + } + })); return Filters.and( assignableFilter, diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/tournament/Tournament.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/tournament/Tournament.java index 3e0009063..290b0062a 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/tournament/Tournament.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/tournament/Tournament.java @@ -132,7 +132,7 @@ public interface Tournament { return new SwissPairingMechanism(PairingType.SWISS_3.name(), 3); } case WC_SWISS -> { - return new ChampionshipSwissPairingMechanism(PairingType.WC_SWISS.name(), 8); + return new ChampionshipSwissPairingMechanism(PairingType.WC_SWISS.name(), 10); } } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/IndividualCardAtTest.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/IndividualCardAtTest.java index 94127dc7f..13b15d9c2 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/IndividualCardAtTest.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/IndividualCardAtTest.java @@ -515,90 +515,6 @@ public class IndividualCardAtTest extends AbstractAtTest { assertEquals(1, _game.getGameState().getTokenCount(corsairWarGalley, Token.RAIDER)); } - @Test - public void returnToItsMaster() throws DecisionResultInvalidException, CardNotFoundException { - LotroDeck p1Deck = createSimplestDeck(); - p1Deck.setRing("4_1"); - LotroDeck p2Deck = createSimplestDeck(); - - Map decks = new HashMap<>(); - decks.put(P1, p1Deck); - decks.put(P2, p2Deck); - - initializeGameWithDecks(decks); - - skipMulligans(); - - PhysicalCardImpl returnToItsMaster = new PhysicalCardImpl(102, "1_224", P2, _cardLibrary.getLotroCardBlueprint("1_224")); - _game.getGameState().addCardToZone(_game, returnToItsMaster, Zone.HAND); - - PhysicalCardImpl nelya = new PhysicalCardImpl(102, "1_233", P2, _cardLibrary.getLotroCardBlueprint("1_233")); - _game.getGameState().addCardToZone(_game, nelya, Zone.SHADOW_CHARACTERS); - - PhysicalCardImpl hobbitSword = new PhysicalCardImpl(102, "1_299", P1, _cardLibrary.getLotroCardBlueprint("1_299")); - _game.getGameState().attachCard(_game, hobbitSword, _game.getGameState().getRingBearer(P1)); - - // End fellowship - playerDecided(P1, ""); - - // End shadow - playerDecided(P2, ""); - - // End maneuvers phase - playerDecided(P1, ""); - playerDecided(P2, ""); - - // End archery phase - playerDecided(P1, ""); - playerDecided(P2, ""); - - // End assignment phase - playerDecided(P1, ""); - playerDecided(P2, ""); - - // Assign - playerDecided(P1, _game.getGameState().getRingBearer(P1).getCardId() + " " + nelya.getCardId()); - - // Choose skirmish to resolve - playerDecided(P1, "" + _game.getGameState().getRingBearer(P1).getCardId()); - - // Skirmish phase - AwaitingDecision skirmishAction = _userFeedback.getAwaitingDecision(P1); - playerDecided(P1, getCardActionId(skirmishAction, "Use The One")); - - assertTrue(_game.getGameState().isWearingRing()); - - // End skirmish phase - playerDecided(P2, ""); - playerDecided(P1, ""); - - // Don't use Return to Its Master - playerDecided(P2, ""); - - // End assignment phase - playerDecided(P1, ""); - playerDecided(P2, ""); - - // Assign - playerDecided(P1, _game.getGameState().getRingBearer(P1).getCardId() + " " + nelya.getCardId()); - - // Choose skirmish to resolve - playerDecided(P1, "" + _game.getGameState().getRingBearer(P1).getCardId()); - - // End fierce skirmish phase - playerDecided(P1, ""); - playerDecided(P2, ""); - - AwaitingDecision playeReturnDecision = _userFeedback.getAwaitingDecision(P2); - playerDecided(P2, getCardActionId(playeReturnDecision, "Play Return")); - - // Choose skirmish to resolve - playerDecided(P1, "" + _game.getGameState().getRingBearer(P1).getCardId()); - - assertEquals(_game.getGameState().getRingBearer(P1), _game.getGameState().getSkirmish().getFellowshipCharacter()); - assertEquals(1, _game.getGameState().getSkirmish().getShadowCharacters().size()); - assertEquals(nelya, _game.getGameState().getSkirmish().getShadowCharacters().iterator().next()); - } @Test public void moreYetToComeWorks() throws DecisionResultInvalidException, CardNotFoundException { 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 a7512ddb5..675e4964e 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 @@ -284,6 +284,12 @@ public class GenericCardTestHelper extends AbstractAtTest { public List ShadowGetBPChoices() { return GetADParamAsList(P2, "blueprintId"); } public List FreepsGetMultipleChoices() { return GetADParamAsList(P1, "results"); } public List ShadowGetMultipleChoices() { return GetADParamAsList(P2, "results"); } + + public List FreepsGetFreepsAssignmentTargets() { return GetADParamAsList(P1, "freeCharacters"); } + public List FreepsGetShadowAssignmentTargets() { return GetADParamAsList(P1, "minions"); } + + public List ShadowGetFreepsAssignmentTargets() { return GetADParamAsList(P2, "freeCharacters"); } + public List ShadowGetShadowAssignmentTargets() { return GetADParamAsList(P2, "minions"); } public List FreepsGetADParamAsList(String paramName) { return GetADParamAsList(P1, paramName); } public List ShadowGetADParamAsList(String paramName) { return GetADParamAsList(P2, paramName); } public List GetADParamAsList(String playerID, String paramName) { return Arrays.asList(GetAwaitingDecisionParam(playerID, paramName)); } @@ -670,6 +676,11 @@ public class GenericCardTestHelper extends AbstractAtTest { SkipToPhase(Phase.ASSIGNMENT); PassCurrentPhaseActions(); } + + public void SkipToShadowAssignments() throws DecisionResultInvalidException { + SkipToAssignments(); + FreepsDeclineAssignments(); + } public void SkipToMovementDecision() throws DecisionResultInvalidException { SkipToPhase(Phase.REGROUP); PassCurrentPhaseActions(); @@ -829,6 +840,11 @@ public class GenericCardTestHelper extends AbstractAtTest { public int GetFreepsCardChoiceCount() { return FreepsGetCardChoices().size(); } public int GetShadowCardChoiceCount() { return ShadowGetCardChoices().size(); } + public int FreepsGetFreepsAssignmentTargetCount() { return FreepsGetFreepsAssignmentTargets().size(); } + public int FreepsGetShadowAssignmentTargetCount() { return FreepsGetShadowAssignmentTargets().size(); } + public int ShadowGetFreepsAssignmentTargetCount() { return ShadowGetFreepsAssignmentTargets().size(); } + public int ShadowGetShadowAssignmentTargetCount() { return ShadowGetShadowAssignmentTargets().size(); } + public void FreepsChooseCardBPFromSelection(PhysicalCardImpl...cards) throws DecisionResultInvalidException { ChooseCardBPFromSelection(P1, cards);} public void ShadowChooseCardBPFromSelection(PhysicalCardImpl...cards) throws DecisionResultInvalidException { ChooseCardBPFromSelection(P2, cards);} diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card_01_224_Tests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card_01_224_Tests.java index daa5134b2..d451dceff 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card_01_224_Tests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card_01_224_Tests.java @@ -1,75 +1,201 @@ package com.gempukku.lotro.cards.official.set01; import com.gempukku.lotro.cards.GenericCardTestHelper; -import com.gempukku.lotro.common.CardType; -import com.gempukku.lotro.common.Culture; -import com.gempukku.lotro.common.Side; -import com.gempukku.lotro.common.Timeword; +import com.gempukku.lotro.common.*; import com.gempukku.lotro.game.CardNotFoundException; +import com.gempukku.lotro.game.PhysicalCardImpl; +import com.gempukku.lotro.logic.decisions.AwaitingDecision; import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; +import com.gempukku.lotro.logic.vo.LotroDeck; import org.junit.Test; import java.util.HashMap; +import java.util.Map; import static org.junit.Assert.*; public class Card_01_224_Tests { - protected GenericCardTestHelper GetScenario() throws CardNotFoundException, DecisionResultInvalidException { - return new GenericCardTestHelper( - new HashMap<>() - {{ - put("card", "1_224"); - // put other cards in here as needed for the test case - }}, - GenericCardTestHelper.FellowshipSites, - GenericCardTestHelper.FOTRFrodo, - GenericCardTestHelper.RulingRing - ); - } + protected GenericCardTestHelper GetScenario() throws CardNotFoundException, DecisionResultInvalidException { + return new GenericCardTestHelper( + new HashMap<>() + {{ + put("rtim", "1_224"); + put("enquea", "2_83"); + put("twk", "1_237"); - @Test - public void ReturntoItsMasterStatsAndKeywordsAreCorrect() throws DecisionResultInvalidException, CardNotFoundException { + put("guard", "1_7"); + }}, + GenericCardTestHelper.FellowshipSites, + GenericCardTestHelper.FOTRFrodo, + GenericCardTestHelper.ATARRing + ); + } - /** - * Set: 1 - * Name: Return to Its Master - * Unique: False - * Side: Shadow - * Culture: Wraith - * Twilight Cost: 0 - * Type: Event - * Subtype: - * Game Text: Response: If the Ring-bearer wears The One Ring at the end of a skirmish phase, cancel all remaining assignments and assign a Nazgûl to skirmish the Ring-bearer; The One Ring's game text does not apply during this skirmish. - */ + @Test + public void ReturntoItsMasterStatsAndKeywordsAreCorrect() throws DecisionResultInvalidException, CardNotFoundException { - var scn = GetScenario(); + /** + * Set: 1 + * Name: Return to Its Master + * Unique: False + * Side: Shadow + * Culture: Wraith + * Twilight Cost: 0 + * Type: Event + * Subtype: + * Game Text: Response: If the Ring-bearer wears The One Ring at the end of a skirmish phase, cancel all remaining assignments and assign a Nazgûl to skirmish the Ring-bearer; The One Ring's game text does not apply during this skirmish. + */ - var card = scn.GetFreepsCard("card"); + var scn = GetScenario(); - assertEquals("Return to Its Master", card.getBlueprint().getTitle()); - assertNull(card.getBlueprint().getSubtitle()); - assertFalse(card.getBlueprint().isUnique()); - assertEquals(Side.SHADOW, card.getBlueprint().getSide()); - assertEquals(Culture.WRAITH, card.getBlueprint().getCulture()); - assertEquals(CardType.EVENT, card.getBlueprint().getCardType()); + var card = scn.GetFreepsCard("rtim"); + + assertEquals("Return to Its Master", card.getBlueprint().getTitle()); + assertNull(card.getBlueprint().getSubtitle()); + assertFalse(card.getBlueprint().isUnique()); + assertEquals(Side.SHADOW, card.getBlueprint().getSide()); + assertEquals(Culture.WRAITH, card.getBlueprint().getCulture()); + assertEquals(CardType.EVENT, card.getBlueprint().getCardType()); assertTrue(scn.hasTimeword(card, Timeword.RESPONSE)); - assertEquals(0, card.getBlueprint().getTwilightCost()); - } + assertEquals(0, card.getBlueprint().getTwilightCost()); + } - // Uncomment any @Test markers below once this is ready to be used - //@Test - public void ReturntoItsMasterTest1() throws DecisionResultInvalidException, CardNotFoundException { - //Pre-game setup - var scn = GetScenario(); + @Test + public void ReturntoItsMasterPermitsAssigningOfNonFierceNazgulWhenUsedDuringFierceSkirmish() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); - scn.FreepsMoveCardToHand(card); + var rtim = scn.GetShadowCard("rtim"); + var enquea = scn.GetShadowCard("enquea"); + var twk = scn.GetShadowCard("twk"); + scn.ShadowMoveCardToHand(rtim); + scn.ShadowMoveCharToTable(enquea, twk); - scn.StartGame(); - scn.FreepsPlayCard(card); + var frodo = scn.GetRingBearer(); + var onering = scn.GetFreepsRing(); + var guard = scn.GetFreepsCard("guard"); + scn.FreepsMoveCharToTable(guard); + + scn.StartGame(); + + //Enquea is the twilight version, who is not fierce. He should still be a valid target + // when RTIM triggers during a fierce skirmish. + + scn.SkipToShadowAssignments(); + assertEquals(2, scn.ShadowGetShadowAssignmentTargetCount()); // both enquea and TWK + //We will skip the non-fierce skirmishes + scn.ShadowDeclineAssignments(); + + //Fierce skirmish assignment phase + scn.SkipToShadowAssignments(); + assertEquals(1, scn.ShadowGetShadowAssignmentTargetCount()); // TWK, but not enquea + scn.ShadowAssignToMinions(guard, twk); + scn.FreepsResolveSkirmish(guard); + + //Need the One Ring to be worn + scn.FreepsUseCardAction(onering); + scn.ShadowPassCurrentPhaseAction(); + scn.FreepsPassCurrentPhaseAction(); + + assertTrue(scn.ShadowPlayAvailable(rtim)); + scn.ShadowPlayCard(rtim); + + assertEquals(2, scn.GetShadowCardChoiceCount()); // both enquea and TWK + scn.ShadowChooseCard(enquea); + + assertEquals(Phase.SKIRMISH, scn.GetCurrentPhase()); + assertTrue(scn.IsCharAssigned(enquea)); + } + + + //Legacy AT test + @Test + public void returnToItsMaster() throws DecisionResultInvalidException, CardNotFoundException { + var scn = GetScenario(); + + var p1Deck = scn.createSimplestDeck(); + p1Deck.setRing("4_1"); + var p2Deck = scn.createSimplestDeck(); + + Map decks = new HashMap<>(); + decks.put(scn.P1, p1Deck); + decks.put(scn.P2, p2Deck); + + scn.initializeGameWithDecks(decks); + + scn.skipMulligans(); + + PhysicalCardImpl returnToItsMaster = new PhysicalCardImpl(102, "1_224", scn.P2, scn._cardLibrary.getLotroCardBlueprint("1_224")); + scn._game.getGameState().addCardToZone(scn._game, returnToItsMaster, Zone.HAND); + + PhysicalCardImpl nelya = new PhysicalCardImpl(102, "1_233", scn.P2, scn._cardLibrary.getLotroCardBlueprint("1_233")); + scn._game.getGameState().addCardToZone(scn._game, nelya, Zone.SHADOW_CHARACTERS); + + PhysicalCardImpl hobbitSword = new PhysicalCardImpl(102, "1_299", scn.P1, scn._cardLibrary.getLotroCardBlueprint("1_299")); + scn._game.getGameState().attachCard(scn._game, hobbitSword, scn._game.getGameState().getRingBearer(scn.P1)); + + // End fellowship + scn.playerDecided(scn.P1, ""); + + // End shadow + scn.playerDecided(scn.P2, ""); + + // End maneuvers phase + scn.playerDecided(scn.P1, ""); + scn.playerDecided(scn.P2, ""); + + // End archery phase + scn.playerDecided(scn.P1, ""); + scn.playerDecided(scn.P2, ""); + + // End assignment phase + scn.playerDecided(scn.P1, ""); + scn.playerDecided(scn.P2, ""); + + // Assign + scn.playerDecided(scn.P1, scn._game.getGameState().getRingBearer(scn.P1).getCardId() + " " + nelya.getCardId()); + + // Choose skirmish to resolve + scn.playerDecided(scn.P1, "" + scn._game.getGameState().getRingBearer(scn.P1).getCardId()); + + // Skirmish phase + AwaitingDecision skirmishAction = scn._userFeedback.getAwaitingDecision(scn.P1); + scn.playerDecided(scn.P1, scn.getCardActionId(skirmishAction, "Use The One")); + + assertTrue(scn._game.getGameState().isWearingRing()); + + // End skirmish phase + scn.playerDecided(scn.P2, ""); + scn.playerDecided(scn.P1, ""); + + // Don't use Return to Its Master + scn.playerDecided(scn.P2, ""); + + // End assignment phase + scn.playerDecided(scn.P1, ""); + scn.playerDecided(scn.P2, ""); + + // Assign + scn.playerDecided(scn.P1, scn._game.getGameState().getRingBearer(scn.P1).getCardId() + " " + nelya.getCardId()); + + // Choose skirmish to resolve + scn.playerDecided(scn.P1, "" + scn._game.getGameState().getRingBearer(scn.P1).getCardId()); + + // End fierce skirmish phase + scn.playerDecided(scn.P1, ""); + scn.playerDecided(scn.P2, ""); + + AwaitingDecision playeReturnDecision = scn._userFeedback.getAwaitingDecision(scn.P2); + scn.playerDecided(scn.P2, scn.getCardActionId(playeReturnDecision, "Play Return")); + + // Choose skirmish to resolve + scn.playerDecided(scn.P1, "" + scn._game.getGameState().getRingBearer(scn.P1).getCardId()); + + assertEquals(scn._game.getGameState().getRingBearer(scn.P1), scn._game.getGameState().getSkirmish().getFellowshipCharacter()); + assertEquals(1, scn._game.getGameState().getSkirmish().getShadowCharacters().size()); + assertEquals(nelya, scn._game.getGameState().getSkirmish().getShadowCharacters().iterator().next()); + } - assertEquals(0, scn.GetTwilight()); - } } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card_01_234_Tests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card_01_234_Tests.java index 60c429853..15624e2ac 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card_01_234_Tests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card_01_234_Tests.java @@ -110,6 +110,8 @@ public class Card_01_234_Tests scn.FreepsPassCurrentPhaseAction(); scn.ShadowPlayCard(nertea); + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + scn.ShadowAcceptOptionalTrigger(); assertTrue(scn.ShadowDecisionAvailable("play a minion")); scn.ShadowChooseYes(); //twk, attea, rit, and runner @@ -141,6 +143,8 @@ public class Card_01_234_Tests scn.FreepsPassCurrentPhaseAction(); scn.ShadowPlayCard(nertea); + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + scn.ShadowAcceptOptionalTrigger(); assertTrue(scn.ShadowDecisionAvailable("play a minion")); scn.ShadowChooseYes(); //twk, attea, rit, and runner @@ -178,6 +182,8 @@ public class Card_01_234_Tests scn.FreepsPassCurrentPhaseAction(); scn.ShadowPlayCard(nertea); + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + scn.ShadowAcceptOptionalTrigger(); assertTrue(scn.ShadowDecisionAvailable("play a minion")); scn.ShadowChooseNo(); @@ -203,6 +209,8 @@ public class Card_01_234_Tests scn.FreepsPassCurrentPhaseAction(); scn.ShadowPlayCard(nertea); + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + scn.ShadowAcceptOptionalTrigger(); assertTrue(scn.ShadowDecisionAvailable("play a minion")); scn.ShadowChooseYes(); assertEquals(4, scn.GetShadowCardChoiceCount()); diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card_01_338_Tests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card_01_338_Tests.java index 64fc524d7..0ce0132e4 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card_01_338_Tests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card_01_338_Tests.java @@ -13,91 +13,140 @@ import static org.junit.Assert.*; public class Card_01_338_Tests { - protected GenericCardTestHelper GetScenario() throws CardNotFoundException, DecisionResultInvalidException { - return new GenericCardTestHelper( - new HashMap<>() - {{ - put("twk", "1_237"); - put("lemenya", "1_232"); - // put other cards in here as needed for the test case - }}, - new HashMap<>() {{ - put("site1", "1_319"); - put("site2", "1_327"); - put("site3", "1_338"); - put("site4", "1_343"); - put("site5", "1_349"); - put("site6", "1_351"); - put("site7", "1_353"); - put("site8", "1_356"); - put("site9", "1_360"); - }}, - GenericCardTestHelper.FOTRFrodo, - GenericCardTestHelper.RulingRing - ); - } + protected GenericCardTestHelper GetScenario() throws CardNotFoundException, DecisionResultInvalidException { + return new GenericCardTestHelper( + new HashMap<>() + {{ + put("twk", "1_237"); + put("lemenya", "1_232"); + put("nertea", "1_234"); - @Test - public void FordofBruinenStatsAndKeywordsAreCorrect() throws DecisionResultInvalidException, CardNotFoundException { + put("guard1", "1_7"); + put("guard2", "1_7"); + put("guard3", "1_7"); + put("guard4", "1_7"); + }}, + new HashMap<>() {{ + put("site1", "1_319"); + put("site2", "1_327"); + put("site3", "1_338"); + put("site4", "1_343"); + put("site5", "1_349"); + put("site6", "1_351"); + put("site7", "1_353"); + put("site8", "1_356"); + put("site9", "1_360"); + }}, + GenericCardTestHelper.FOTRFrodo, + GenericCardTestHelper.RulingRing + ); + } - /** - * Set: 1 - * Name: Ford of Bruinen - * Unique: False - * Side: - * Culture: - * Shadow Number: 0 - * Type: Sanctuary - * Subtype: - * Site Number: 3 - * Game Text: River. Sanctuary. The twilight cost of the first Nazgûl played to Ford of Bruinen each turn is -5. - */ + @Test + public void FordofBruinenStatsAndKeywordsAreCorrect() throws DecisionResultInvalidException, CardNotFoundException { - var scn = GetScenario(); + /** + * Set: 1 + * Name: Ford of Bruinen + * Unique: False + * Side: + * Culture: + * Shadow Number: 0 + * Type: Sanctuary + * Subtype: + * Site Number: 3 + * Game Text: River. Sanctuary. The twilight cost of the first Nazgûl played to Ford of Bruinen each turn is -5. + */ - var card = scn.GetFreepsSite(3); + var scn = GetScenario(); - assertEquals("Ford of Bruinen", card.getBlueprint().getTitle()); - assertNull(card.getBlueprint().getSubtitle()); - assertFalse(card.getBlueprint().isUnique()); - assertEquals(CardType.SITE, card.getBlueprint().getCardType()); - assertTrue(scn.hasKeyword(card, Keyword.RIVER)); - assertTrue(scn.hasKeyword(card, Keyword.SANCTUARY)); - assertEquals(0, card.getBlueprint().getTwilightCost()); - assertEquals(3, card.getBlueprint().getSiteNumber()); - } + var card = scn.GetFreepsSite(3); - @Test - public void FordofBruinenOnlyDiscountsTheFirstNazgul() throws DecisionResultInvalidException, CardNotFoundException { - //Pre-game setup - var scn = GetScenario(); + assertEquals("Ford of Bruinen", card.getBlueprint().getTitle()); + assertNull(card.getBlueprint().getSubtitle()); + assertFalse(card.getBlueprint().isUnique()); + assertEquals(CardType.SITE, card.getBlueprint().getCardType()); + assertTrue(scn.hasKeyword(card, Keyword.RIVER)); + assertTrue(scn.hasKeyword(card, Keyword.SANCTUARY)); + assertEquals(0, card.getBlueprint().getTwilightCost()); + assertEquals(3, card.getBlueprint().getSiteNumber()); + } - var ford = scn.GetShadowSite(3); + @Test + public void FordofBruinenOnlyDiscountsTheFirstNazgul() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); - var twk = scn.GetShadowCard("twk"); - var lemenya = scn.GetShadowCard("lemenya"); - scn.ShadowMoveCardToHand(twk, lemenya); + var ford = scn.GetShadowSite(3); - scn.StartGame(); - //Start our test on 2 so that moving to 3 is the first thing we do - scn.SkipToSite(2); + var twk = scn.GetShadowCard("twk"); + var lemenya = scn.GetShadowCard("lemenya"); + scn.ShadowMoveCardToHand(twk, lemenya); - scn.SetTwilight(9); - scn.FreepsPassCurrentPhaseAction(); + scn.StartGame(); + //Start our test on 2 so that moving to 3 is the first thing we do + scn.SkipToSite(2); - assertEquals(ford, scn.GetCurrentSite()); + scn.SetTwilight(9); + scn.FreepsPassCurrentPhaseAction(); - //9 manual + 1 from the fellowship moving - assertEquals(10, scn.GetTwilight()); + assertEquals(ford, scn.GetCurrentSite()); - scn.ShadowPlayCard(twk); - //TWK costs 8 (no roaming), discounted by 5 to 3 total - //10 - 3 - assertEquals(7, scn.GetTwilight()); + //9 manual + 1 from the fellowship moving + assertEquals(10, scn.GetTwilight()); - scn.ShadowPlayCard(lemenya); - //Lemenya costs 4, should have no discount - //7 - 4 - assertEquals(3, scn.GetTwilight()); - } + scn.ShadowPlayCard(twk); + //TWK costs 8 (no roaming), discounted by 5 to 3 total + //10 - 3 + assertEquals(7, scn.GetTwilight()); + + scn.ShadowPlayCard(lemenya); + //Lemenya costs 4, should have no discount + //7 - 4 + assertEquals(3, scn.GetTwilight()); + } + + @Test + public void FordDiscountsNerteaButNotNerteasTrigger() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var ford = scn.GetShadowSite(3); + + var twk = scn.GetShadowCard("twk"); + var nertea = scn.GetShadowCard("nertea"); + scn.ShadowMoveCardToHand(nertea); + scn.ShadowMoveCardToDiscard(twk); + + scn.FreepsMoveCharToTable("guard1", "guard2", "guard3", "guard4"); + + scn.StartGame(); + //Start our test on 2 so that moving to 3 is the first thing we do + scn.SkipToSite(2); + + scn.SetTwilight(5); + scn.FreepsPassCurrentPhaseAction(); + + assertEquals(ford, scn.GetCurrentSite()); + + //5 manual + 5 from the fellowship moving + assertEquals(10, scn.GetTwilight()); + + scn.ShadowPlayCard(nertea); + //Nertea costs 4 (no roaming), discounted by 5 to 0 total + //10 - 0 + assertEquals(10, scn.GetTwilight()); + + //Nertea pulls a minion from discard, which should not get discounted + // as Nertea should have consumed the only discount + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + scn.ShadowAcceptOptionalTrigger(); + assertTrue(scn.ShadowDecisionAvailable("play a minion")); + scn.ShadowChooseYes(); + + scn.ShadowChooseCardBPFromSelection(twk); + //TWK costs 8, should not be discounted + //10 - 8 + assertEquals(2, scn.GetTwilight()); + } } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set01/Card_01_234_ErrataTests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set01/Card_01_234_ErrataTests.java index 128efe00c..501d2d6ce 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set01/Card_01_234_ErrataTests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set01/Card_01_234_ErrataTests.java @@ -108,6 +108,8 @@ public class Card_01_234_ErrataTests scn.FreepsPassCurrentPhaseAction(); scn.ShadowPlayCard(nertea); + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + scn.ShadowAcceptOptionalTrigger(); assertTrue(scn.ShadowDecisionAvailable("play a unique WRAITH minion")); scn.ShadowChooseYes(); //twk and attea, but not rit or runner @@ -138,6 +140,8 @@ public class Card_01_234_ErrataTests scn.FreepsPassCurrentPhaseAction(); scn.ShadowPlayCard(nertea); + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + scn.ShadowAcceptOptionalTrigger(); assertTrue(scn.ShadowDecisionAvailable("play a unique WRAITH minion")); scn.ShadowChooseYes(); //twk and attea, but not rit or runner @@ -174,6 +178,8 @@ public class Card_01_234_ErrataTests scn.FreepsPassCurrentPhaseAction(); scn.ShadowPlayCard(nertea); + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + scn.ShadowAcceptOptionalTrigger(); assertTrue(scn.ShadowDecisionAvailable("play a unique WRAITH minion")); scn.ShadowChooseNo(); @@ -199,6 +205,8 @@ public class Card_01_234_ErrataTests scn.FreepsPassCurrentPhaseAction(); scn.ShadowPlayCard(nertea); + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + scn.ShadowAcceptOptionalTrigger(); assertTrue(scn.ShadowDecisionAvailable("play a unique WRAITH minion")); scn.ShadowChooseYes(); //twk and attea, but not rit or runner