Merge remote-tracking branch 'upstream/grand-card-rework' into grand-card-rework
# Conflicts: # gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/filters/Filters.java
This commit is contained in:
@@ -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)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String, LotroDeck> 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 {
|
||||
|
||||
@@ -284,6 +284,12 @@ public class GenericCardTestHelper extends AbstractAtTest {
|
||||
public List<String> ShadowGetBPChoices() { return GetADParamAsList(P2, "blueprintId"); }
|
||||
public List<String> FreepsGetMultipleChoices() { return GetADParamAsList(P1, "results"); }
|
||||
public List<String> ShadowGetMultipleChoices() { return GetADParamAsList(P2, "results"); }
|
||||
|
||||
public List<String> FreepsGetFreepsAssignmentTargets() { return GetADParamAsList(P1, "freeCharacters"); }
|
||||
public List<String> FreepsGetShadowAssignmentTargets() { return GetADParamAsList(P1, "minions"); }
|
||||
|
||||
public List<String> ShadowGetFreepsAssignmentTargets() { return GetADParamAsList(P2, "freeCharacters"); }
|
||||
public List<String> ShadowGetShadowAssignmentTargets() { return GetADParamAsList(P2, "minions"); }
|
||||
public List<String> FreepsGetADParamAsList(String paramName) { return GetADParamAsList(P1, paramName); }
|
||||
public List<String> ShadowGetADParamAsList(String paramName) { return GetADParamAsList(P2, paramName); }
|
||||
public List<String> 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);}
|
||||
|
||||
|
||||
@@ -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: <b>Response:</b> 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: <b>Response:</b> 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<String, LotroDeck> 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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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: <b>River</b>. <b>Sanctuary</b>. 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: <b>River</b>. <b>Sanctuary</b>. 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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user