Fixing FOTR Nertea (and errata) continuing to ask the user for each potential minion.

This commit is contained in:
Christian 'ketura' McCarty
2023-11-13 21:42:47 -06:00
parent 40b9da1af7
commit fac01fcb60
11 changed files with 572 additions and 87 deletions

View File

@@ -982,22 +982,61 @@
type: played
filter: self
}
effect: {
type: repeat
amount: {
type: forEachYouCanSpot
filter: companion
over: 4
effect: [
{
type: MemorizeValue
memory: choice
value: yes
}
effect: {
type: optional
text: Would you like to play a minion from your discard?
{
type: conditional
requires: [
{
type: CanSpot
filter: companion
count: 5
}
{
type: PlayableFromDiscard
filter: minion
}
]
effect: {
type: playCardFromDiscard
filter: choose(minion)
type: Repeat
amount: {
type: forEachYouCanSpot
filter: companion
over: 4
}
effect: {
type: conditional
requires: [
{
type: MemoryIs
memory: choice
value: yes
}
{
type: HasCardInDiscard
filter: playable,minion
}
]
effect: [
{
type: chooseYesOrNo
player: you
text: Would you like to play a minion from your discard pile?
memorize: choice
}
{
type: playCardFromDiscard
filter: choose(minion)
}
]
}
}
}
}
]
}
}
1_235: {

View File

@@ -40,24 +40,63 @@
type: played
filter: self
}
effect: {
type: repeat
amount: {
type: forEachYouCanSpot
filter: companion
over: 4
effect: [
{
type: MemorizeValue
memory: choice
value: yes
}
effect: {
type: optional
text: Would you like to play a unique WRAITH minion from your discard?
{
type: conditional
requires: [
{
type: CanSpot
filter: companion
count: 5
}
{
type: PlayableFromDiscard
filter: unique,culture(wraith),minion
}
]
effect: {
type: playCardFromDiscard
filter: choose(unique,culture(wraith),minion)
type: Repeat
amount: {
type: forEachYouCanSpot
filter: companion
over: 4
}
effect: {
type: conditional
requires: [
{
type: MemoryIs
memory: choice
value: yes
}
{
type: HasCardInDiscard
filter: playable,unique,culture(wraith),minion
}
]
effect: [
{
type: chooseYesOrNo
player: you
text: Would you like to play a unique WRAITH minion from your discard?
memorize: choice
}
{
type: playCardFromDiscard
filter: choose(unique,culture(wraith),minion)
}
]
}
}
}
}
]
}
gametext: When you play Ulaire Nertea, for each companion over 4, you may play a unique [Wraith] minion from your discard pile.
gametext: When you play Úlairë Nertëa, for each companion over 4, you may play a unique [Wraith] minion from your discard pile.
lore: Some accepted Sauron's gift for glory and a notion of great deeds.
promotext: ""
alts: {

View File

@@ -79,6 +79,7 @@ public class EffectAppenderFactory {
effectAppenderProducers.put("memorize", new MemorizeActive());
effectAppenderProducers.put("memorizenumber", new MemorizeNumber());
effectAppenderProducers.put("memorizestacked", new MemorizeStacked());
effectAppenderProducers.put("memorizevalue", new MemorizeValue());
effectAppenderProducers.put("modifyarcherytotal", new ModifyArcheryTotal());
effectAppenderProducers.put("modifysitenumber", new ModifySiteNumber());
effectAppenderProducers.put("modifystrength", new ModifyStrength());

View File

@@ -0,0 +1,42 @@
package com.gempukku.lotro.cards.build.field.effect.appender;
import com.gempukku.lotro.cards.build.ActionContext;
import com.gempukku.lotro.cards.build.CardGenerationEnvironment;
import com.gempukku.lotro.cards.build.InvalidCardDefinitionException;
import com.gempukku.lotro.cards.build.ValueSource;
import com.gempukku.lotro.cards.build.field.FieldUtils;
import com.gempukku.lotro.cards.build.field.effect.EffectAppender;
import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer;
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.actions.CostToEffectAction;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.UnrespondableEffect;
import org.json.simple.JSONObject;
public class MemorizeValue implements EffectAppenderProducer {
@Override
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(effectObject, "value", "memory");
final String value = FieldUtils.getString(effectObject.get("value"), "value");
final String memory = FieldUtils.getString(effectObject.get("memory"), "memory");
if (memory == null)
throw new InvalidCardDefinitionException("Memory is required for a MemorizeValue effect.");
return new DelayedAppender() {
@Override
protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) {
return new UnrespondableEffect() {
@Override
protected void doPlayEffect(LotroGame game) {
actionContext.setValueToMemory(memory, value);
}
};
}
};
}
}

View File

@@ -14,15 +14,17 @@ import com.gempukku.lotro.logic.effects.StackActionEffect;
import com.gempukku.lotro.logic.timing.Effect;
import org.json.simple.JSONObject;
import java.util.Arrays;
public class Repeat implements EffectAppenderProducer {
@Override
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(effectObject, "amount", "effect");
final ValueSource amountSource = ValueResolver.resolveEvaluator(effectObject.get("amount"), environment);
final JSONObject effect = (JSONObject) effectObject.get("effect");
final JSONObject[] effectArray = FieldUtils.getObjectArray(effectObject.get("effect"), "effect");
final EffectAppender effectAppender = environment.getEffectAppenderFactory().getEffectAppender(effect, environment);
final EffectAppender[] effectAppenders = environment.getEffectAppenderFactory().getEffectAppenders(effectArray, environment);
return new DelayedAppender() {
@Override
@@ -30,8 +32,10 @@ public class Repeat implements EffectAppenderProducer {
final int count = amountSource.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
if (count > 0) {
SubAction subAction = new SubAction(action);
for (int i = 0; i < count; i++)
effectAppender.appendEffect(cost, subAction, actionContext);
for (int i = 0; i < count; i++) {
for (EffectAppender effectAppender : effectAppenders)
effectAppender.appendEffect(false, subAction, actionContext);
}
return new StackActionEffect(subAction);
} else {
return null;
@@ -40,12 +44,18 @@ public class Repeat implements EffectAppenderProducer {
@Override
public boolean isPlayableInFull(ActionContext actionContext) {
return effectAppender.isPlayableInFull(actionContext);
for (EffectAppender effectAppender : effectAppenders) {
if (effectAppender.isPlayabilityCheckedForEffect()
&& !effectAppender.isPlayableInFull(actionContext))
return false;
}
return true;
}
@Override
public boolean isPlayabilityCheckedForEffect() {
return effectAppender.isPlayabilityCheckedForEffect();
return Arrays.stream(effectAppenders).anyMatch(EffectAppender::isPlayabilityCheckedForEffect);
}
};
}

View File

@@ -0,0 +1,26 @@
package com.gempukku.lotro.cards.build.field.effect.requirement;
import com.gempukku.lotro.cards.build.*;
import com.gempukku.lotro.cards.build.field.FieldUtils;
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.PlayerResolver;
import com.gempukku.lotro.common.Filterable;
import com.gempukku.lotro.logic.timing.PlayConditions;
import org.json.simple.JSONObject;
public class PlayableFromDiscard implements RequirementProducer {
@Override
public Requirement getPlayRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(object, "player", "filter");
final String player = FieldUtils.getString(object.get("player"), "player", "you");
final String filter = FieldUtils.getString(object.get("filter"), "filter", "any");
final PlayerSource playerSource = PlayerResolver.resolvePlayer(player, environment);
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment);
return (actionContext) -> {
final Filterable filterable = filterableSource.getFilterable(actionContext);
return PlayConditions.canPlayFromDiscard(playerSource.getPlayer(actionContext), actionContext.getGame(), filterable);
};
}
}

View File

@@ -50,6 +50,7 @@ public class RequirementFactory {
requirementProducers.put("movecountminimum", new MoveCountMinimum());
requirementProducers.put("perphaselimit", new PerPhaseLimit());
requirementProducers.put("perturnlimit", new PerTurnLimit());
requirementProducers.put("playablefromdiscard", new PlayableFromDiscard());
requirementProducers.put("phase", new PhaseRequirement());
requirementProducers.put("playedcardthisphase", new PlayedCardThisPhase());
requirementProducers.put("ringisactive", new RingIsActive());

View File

@@ -18,9 +18,9 @@ import java.util.*;
import static org.junit.Assert.fail;
public abstract class AbstractAtTest {
protected static LotroCardBlueprintLibrary _cardLibrary;
protected static LotroFormatLibrary _formatLibrary;
protected static ProductLibrary _productLibrary;
public static LotroCardBlueprintLibrary _cardLibrary;
public static LotroFormatLibrary _formatLibrary;
public static ProductLibrary _productLibrary;
private final int cardId = 100;
static {
@@ -29,20 +29,20 @@ public abstract class AbstractAtTest {
_productLibrary = new ProductLibrary(_cardLibrary);
}
protected DefaultLotroGame _game;
protected DefaultUserFeedback _userFeedback;
public DefaultLotroGame _game;
public DefaultUserFeedback _userFeedback;
public static final String P1 = "player1";
public static final String P2 = "player2";
protected PhysicalCardImpl createCard(String owner, String blueprintId) throws CardNotFoundException {
public PhysicalCardImpl createCard(String owner, String blueprintId) throws CardNotFoundException {
return (PhysicalCardImpl) _game.getGameState().createPhysicalCard(owner, _cardLibrary, blueprintId);
}
protected void initializeSimplestGame() throws DecisionResultInvalidException {
public void initializeSimplestGame() throws DecisionResultInvalidException {
this.initializeSimplestGame(null);
}
protected void initializeSimplestGame(Map<String, Collection<String>> additionalCardsInDeck) throws DecisionResultInvalidException {
public void initializeSimplestGame(Map<String, Collection<String>> additionalCardsInDeck) throws DecisionResultInvalidException {
Map<String, LotroDeck> decks = new HashMap<>();
addPlayerDeck(P1, decks, additionalCardsInDeck);
addPlayerDeck(P2, decks, additionalCardsInDeck);
@@ -50,11 +50,11 @@ public abstract class AbstractAtTest {
initializeGameWithDecks(decks);
}
protected void initializeGameWithDecks(Map<String, LotroDeck> decks) throws DecisionResultInvalidException {
public void initializeGameWithDecks(Map<String, LotroDeck> decks) throws DecisionResultInvalidException {
initializeGameWithDecks(decks, "multipath");
}
protected void initializeGameWithDecks(Map<String, LotroDeck> decks, String formatName) throws DecisionResultInvalidException {
public void initializeGameWithDecks(Map<String, LotroDeck> decks, String formatName) throws DecisionResultInvalidException {
_userFeedback = new DefaultUserFeedback();
LotroFormatLibrary formatLibrary = new LotroFormatLibrary(new DefaultAdventureLibrary(), _cardLibrary);
@@ -72,13 +72,13 @@ public abstract class AbstractAtTest {
playerDecided(P1, "0");
}
protected void skipMulligans() throws DecisionResultInvalidException {
public void skipMulligans() throws DecisionResultInvalidException {
// Mulligans
playerDecided(P1, "0");
playerDecided(P2, "0");
}
protected void validateContents(String[] array1, String[] array2) {
public void validateContents(String[] array1, String[] array2) {
if (array1.length != array2.length)
fail("Array sizes differ");
List<String> values = new ArrayList<>(Arrays.asList(array1));
@@ -88,14 +88,14 @@ public abstract class AbstractAtTest {
}
}
protected String[] toCardIdArray(PhysicalCard... cards) {
public String[] toCardIdArray(PhysicalCard... cards) {
String[] result = new String[cards.length];
for (int i = 0; i < cards.length; i++)
result[i] = String.valueOf(cards[i].getCardId());
return result;
}
protected String getArbitraryCardId(AwaitingDecision awaitingDecision, String blueprintId) {
public String getArbitraryCardId(AwaitingDecision awaitingDecision, String blueprintId) {
String[] blueprints = (String[]) awaitingDecision.getDecisionParameters().get("blueprintId");
for (int i = 0; i < blueprints.length; i++)
if (blueprints[i].equals(blueprintId))
@@ -103,7 +103,7 @@ public abstract class AbstractAtTest {
return null;
}
protected String getCardActionId(AwaitingDecision awaitingDecision, String actionTextStart) {
public String getCardActionId(AwaitingDecision awaitingDecision, String actionTextStart) {
String[] actionTexts = (String[]) awaitingDecision.getDecisionParameters().get("actionText");
for (int i = 0; i < actionTexts.length; i++)
if (actionTexts[i].startsWith(actionTextStart))
@@ -111,11 +111,11 @@ public abstract class AbstractAtTest {
return null;
}
protected String getCardActionId(String playerId, String actionTextStart) {
public String getCardActionId(String playerId, String actionTextStart) {
return getCardActionId(_userFeedback.getAwaitingDecision(playerId), actionTextStart);
}
protected String getCardActionIdContains(AwaitingDecision awaitingDecision, String actionTextContains) {
public String getCardActionIdContains(AwaitingDecision awaitingDecision, String actionTextContains) {
String[] actionTexts = (String[]) awaitingDecision.getDecisionParameters().get("actionText");
for (int i = 0; i < actionTexts.length; i++)
if (actionTexts[i].contains(actionTextContains))
@@ -123,7 +123,7 @@ public abstract class AbstractAtTest {
return null;
}
protected String getMultipleDecisionIndex(AwaitingDecision awaitingDecision, String result) {
public String getMultipleDecisionIndex(AwaitingDecision awaitingDecision, String result) {
String[] actionTexts = (String[]) awaitingDecision.getDecisionParameters().get("results");
for (int i = 0; i < actionTexts.length; i++)
if (actionTexts[i].equals(result))
@@ -131,7 +131,7 @@ public abstract class AbstractAtTest {
return null;
}
protected void addPlayerDeck(String player, Map<String, LotroDeck> decks, Map<String, Collection<String>> additionalCardsInDeck) {
public void addPlayerDeck(String player, Map<String, LotroDeck> decks, Map<String, Collection<String>> additionalCardsInDeck) {
LotroDeck deck = createSimplestDeck();
if (additionalCardsInDeck != null) {
Collection<String> extraCards = additionalCardsInDeck.get(player);
@@ -142,11 +142,11 @@ public abstract class AbstractAtTest {
decks.put(player, deck);
}
protected void moveCardToZone(PhysicalCardImpl card, Zone zone) {
public void moveCardToZone(PhysicalCardImpl card, Zone zone) {
_game.getGameState().addCardToZone(_game, card, zone);
}
protected void playerDecided(String player, String answer) throws DecisionResultInvalidException {
public void playerDecided(String player, String answer) throws DecisionResultInvalidException {
AwaitingDecision decision = _userFeedback.getAwaitingDecision(player);
_userFeedback.participantDecided(player);
try {
@@ -158,20 +158,20 @@ public abstract class AbstractAtTest {
_game.carryOutPendingActionsUntilDecisionNeeded();
}
protected void carryOutEffectInPhaseActionByPlayer(String playerId, Effect effect) throws DecisionResultInvalidException {
public void carryOutEffectInPhaseActionByPlayer(String playerId, Effect effect) throws DecisionResultInvalidException {
SystemQueueAction action = new SystemQueueAction();
action.appendEffect(effect);
carryOutEffectInPhaseActionByPlayer(playerId, action);
}
protected void carryOutEffectInPhaseActionByPlayer(String playerId, Action action) throws DecisionResultInvalidException {
public void carryOutEffectInPhaseActionByPlayer(String playerId, Action action) throws DecisionResultInvalidException {
CardActionSelectionDecision awaitingDecision = (CardActionSelectionDecision) _userFeedback.getAwaitingDecision(playerId);
awaitingDecision.addAction(action);
playerDecided(playerId, "0");
}
protected LotroDeck createSimplestDeck() {
public LotroDeck createSimplestDeck() {
LotroDeck lotroDeck = new LotroDeck("Some deck");
// 10_121,1_2
lotroDeck.setRingBearer("10_121");

View File

@@ -117,38 +117,39 @@ public class PlayCardFromDiscardAtTest extends AbstractAtTest {
assertEquals(Zone.SHADOW_CHARACTERS, goblinSneakInDiscard.getZone());
}
@Test
public void ulaireNerteaCantPlayMinionsOnGreatRiver() throws Exception {
initializeSimplestGame();
for (int i=0; i<4; i++) {
final PhysicalCardImpl greatRiver = createCard(P1, "1_306");
_game.getGameState().addCardToZone(_game, greatRiver, Zone.FREE_CHARACTERS);
}
skipMulligans();
final PhysicalCardImpl greatRiver = createCard(P2, "3_118");
greatRiver.setSiteNumber(2);
_game.getGameState().addCardToZone(_game, greatRiver, Zone.ADVENTURE_PATH);
final PhysicalCardImpl ulaireNertea = createCard(P2, "1_234");
_game.getGameState().addCardToZone(_game, ulaireNertea, Zone.HAND);
final PhysicalCardImpl goblinRunner = createCard(P2, "1_178");
_game.getGameState().addCardToZone(_game, goblinRunner, Zone.DISCARD);
_game.getGameState().setTwilight(20);
// Fellowship phase
playerDecided(P1, "");
assertEquals(greatRiver, _game.getGameState().getCurrentSite());
playerDecided(P2, getCardActionId(P2, "Play Úlairë Nertëa"));
assertFalse(_userFeedback.getAwaitingDecision(P2).getDecisionType() == AwaitingDecisionType.MULTIPLE_CHOICE);
}
//Migrated to the Ulaire Nertea tests in cards/official/set01/Card_01_234_Tests
// @Test
// public void ulaireNerteaCantPlayMinionsOnGreatRiver() throws Exception {
// initializeSimplestGame();
//
// for (int i=0; i<4; i++) {
// final PhysicalCardImpl greatRiver = createCard(P1, "1_306");
// _game.getGameState().addCardToZone(_game, greatRiver, Zone.FREE_CHARACTERS);
// }
//
// skipMulligans();
//
// final PhysicalCardImpl greatRiver = createCard(P2, "3_118");
// greatRiver.setSiteNumber(2);
// _game.getGameState().addCardToZone(_game, greatRiver, Zone.ADVENTURE_PATH);
//
// final PhysicalCardImpl ulaireNertea = createCard(P2, "1_234");
// _game.getGameState().addCardToZone(_game, ulaireNertea, Zone.HAND);
//
// final PhysicalCardImpl goblinRunner = createCard(P2, "1_178");
// _game.getGameState().addCardToZone(_game, goblinRunner, Zone.DISCARD);
//
// _game.getGameState().setTwilight(20);
//
// // Fellowship phase
// playerDecided(P1, "");
//
// assertEquals(greatRiver, _game.getGameState().getCurrentSite());
//
// playerDecided(P2, getCardActionId(P2, "Play Úlairë Nertëa"));
//
// assertFalse(_userFeedback.getAwaitingDecision(P2).getDecisionType() == AwaitingDecisionType.MULTIPLE_CHOICE);
// }
@Test
public void azogCantPlayTrollFromDiscardInRivendell() throws Exception {

View File

@@ -0,0 +1,238 @@
package com.gempukku.lotro.cards.official.set01;
import com.gempukku.lotro.cards.GenericCardTestHelper;
import com.gempukku.lotro.common.*;
import com.gempukku.lotro.game.CardNotFoundException;
import com.gempukku.lotro.game.PhysicalCardImpl;
import com.gempukku.lotro.logic.decisions.AwaitingDecisionType;
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
import org.junit.Test;
import java.util.HashMap;
import static org.junit.Assert.*;
public class Card_01_234_Tests
{
protected GenericCardTestHelper GetScenario() throws CardNotFoundException, DecisionResultInvalidException {
return new GenericCardTestHelper(
new HashMap<>()
{{
put("comp2", "1_53");
put("comp3", "1_53");
put("comp4", "1_53");
put("comp5", "1_53");
put("comp6", "1_53");
put("nertea", "1_234");
put("runner", "1_178");
put("twk", "2_85");
put("attea", "1_229");
put("rit", "101_40");
}},
GenericCardTestHelper.FellowshipSites,
GenericCardTestHelper.FOTRFrodo,
GenericCardTestHelper.RulingRing
);
}
@Test
public void UlaireNerteaStatsAndKeywordsAreCorrect() throws DecisionResultInvalidException, CardNotFoundException {
/**
* Set: 1
* Title: *Ulaire Nertea, Messenger of Dol Guldur
* Side: Free Peoples
* Culture: Ringwraith
* Twilight Cost: 4
* Type: minion
* Subtype: Nazgul
* Strength: 9
* Vitality: 2
* Site Number: 3
* Game Text: When you play Úlairë Nertëa, for each companion over 4, you may play 1 minion from your discard pile.
*/
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
PhysicalCardImpl nertea = scn.GetFreepsCard("nertea");
assertTrue(nertea.getBlueprint().isUnique());
assertEquals(Side.SHADOW, nertea.getBlueprint().getSide());
assertEquals(Culture.WRAITH, nertea.getBlueprint().getCulture());
assertEquals(CardType.MINION, nertea.getBlueprint().getCardType());
assertEquals(Race.NAZGUL, nertea.getBlueprint().getRace());
assertEquals(4, nertea.getBlueprint().getTwilightCost());
assertEquals(9, nertea.getBlueprint().getStrength());
assertEquals(2, nertea.getBlueprint().getVitality());
assertEquals(3, nertea.getBlueprint().getSiteNumber());
}
@Test
public void NerteaDoesNotTriggerWith4Companions() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
scn.FreepsMoveCharToTable("comp2", "comp3", "comp4");
PhysicalCardImpl nertea = scn.GetShadowCard("nertea");
scn.ShadowMoveCardToHand(nertea);
scn.StartGame();
scn.SetTwilight(20);
scn.FreepsPassCurrentPhaseAction();
scn.ShadowPlayCard(nertea);
assertFalse(scn.ShadowHasOptionalTriggerAvailable());
}
@Test
public void NerteaPlays1MinionIf5Companions() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
scn.FreepsMoveCharToTable("comp2", "comp3", "comp4", "comp5");
PhysicalCardImpl twk = scn.GetShadowCard("twk");
PhysicalCardImpl attea = scn.GetShadowCard("attea");
PhysicalCardImpl nertea = scn.GetShadowCard("nertea");
scn.ShadowMoveCardToDiscard("runner", "rit", "twk", "attea");
scn.ShadowMoveCardToDiscard(twk);
scn.ShadowMoveCardToHand(nertea);
scn.StartGame();
scn.SetTwilight(30);
scn.FreepsPassCurrentPhaseAction();
scn.ShadowPlayCard(nertea);
assertTrue(scn.ShadowDecisionAvailable("play a minion"));
scn.ShadowChooseYes();
//twk, attea, rit, and runner
assertEquals(4, scn.GetShadowCardChoiceCount());
assertEquals(Zone.DISCARD, twk.getZone());
scn.ShadowChooseCardBPFromSelection(twk);
assertEquals(Zone.SHADOW_CHARACTERS, twk.getZone());
assertFalse(scn.ShadowDecisionAvailable("play a minion"));
}
@Test
public void NerteaPlays2MinionsIf6Companions() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
scn.FreepsMoveCharToTable("comp2", "comp3", "comp4", "comp5", "comp6");
PhysicalCardImpl twk = scn.GetShadowCard("twk");
PhysicalCardImpl attea = scn.GetShadowCard("attea");
PhysicalCardImpl nertea = scn.GetShadowCard("nertea");
PhysicalCardImpl runner = scn.GetShadowCard("runner");
scn.ShadowMoveCardToDiscard("rit", "twk", "attea");
scn.ShadowMoveCardToDiscard(twk, runner);
scn.ShadowMoveCardToHand(nertea);
scn.StartGame();
scn.SetTwilight(30);
scn.FreepsPassCurrentPhaseAction();
scn.ShadowPlayCard(nertea);
assertTrue(scn.ShadowDecisionAvailable("play a minion"));
scn.ShadowChooseYes();
//twk, attea, rit, and runner
assertEquals(4, scn.GetShadowCardChoiceCount());
assertEquals(Zone.DISCARD, twk.getZone());
scn.ShadowChooseCardBPFromSelection(twk);
assertEquals(Zone.SHADOW_CHARACTERS, twk.getZone());
assertTrue(scn.ShadowDecisionAvailable("play a minion"));
scn.ShadowChooseYes();
assertEquals(Zone.DISCARD, runner.getZone());
scn.ShadowChooseCardBPFromSelection(runner);
assertEquals(Zone.SHADOW_CHARACTERS, runner.getZone());
assertFalse(scn.ShadowDecisionAvailable("play a minion"));
}
@Test
public void CancelingNerteaAfterFirstMinionDoesntAskAgain() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
scn.FreepsMoveCharToTable("comp2", "comp3", "comp4", "comp5", "comp6");
PhysicalCardImpl twk = scn.GetShadowCard("twk");
PhysicalCardImpl attea = scn.GetShadowCard("attea");
PhysicalCardImpl nertea = scn.GetShadowCard("nertea");
PhysicalCardImpl runner = scn.GetShadowCard("runner");
scn.ShadowMoveCardToDiscard("rit", "twk", "attea");
scn.ShadowMoveCardToDiscard(twk, runner);
scn.ShadowMoveCardToHand(nertea);
scn.StartGame();
scn.SetTwilight(30);
scn.FreepsPassCurrentPhaseAction();
scn.ShadowPlayCard(nertea);
assertTrue(scn.ShadowDecisionAvailable("play a minion"));
scn.ShadowChooseNo();
assertFalse(scn.ShadowDecisionAvailable("play a minion"));
}
@Test
public void NerteaDoesNotPromptIfNoMinionsInDiscardPile() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
scn.FreepsMoveCharToTable("comp2", "comp3", "comp4", "comp5", "comp6");
PhysicalCardImpl nertea = scn.GetShadowCard("nertea");
scn.ShadowMoveCardToHand("rit", "twk", "attea", "runner");
scn.ShadowMoveCardToHand(nertea);
scn.StartGame();
scn.SetTwilight(30);
scn.FreepsPassCurrentPhaseAction();
scn.ShadowPlayCard(nertea);
assertFalse(scn.ShadowDecisionAvailable("play a minion"));
}
//Imported from the at tests
@Test
public void ulaireNerteaCantPlayMinionsOnGreatRiver() throws Exception {
var scn = GetScenario();
var _game = scn._game;
for (int i=0; i<4; i++) {
final PhysicalCardImpl pippin = scn.createCard(scn.P1, "1_306");
_game.getGameState().addCardToZone(_game, pippin, Zone.FREE_CHARACTERS);
}
scn.skipMulligans();
final PhysicalCardImpl greatRiver = scn.createCard(scn.P2, "3_118");
greatRiver.setSiteNumber(2);
_game.getGameState().addCardToZone(_game, greatRiver, Zone.ADVENTURE_PATH);
final PhysicalCardImpl ulaireNertea = scn.createCard(scn.P2, "1_234");
_game.getGameState().addCardToZone(_game, ulaireNertea, Zone.HAND);
final PhysicalCardImpl goblinRunner = scn.createCard(scn.P2, "1_178");
_game.getGameState().addCardToZone(_game, goblinRunner, Zone.DISCARD);
_game.getGameState().setTwilight(20);
// Fellowship phase
scn.playerDecided(scn.P1, "");
assertEquals(greatRiver, _game.getGameState().getCurrentSite());
scn.playerDecided(scn.P2, scn.getCardActionId(scn.P2, "Play Úlairë Nertëa"));
assertFalse(scn._userFeedback.getAwaitingDecision(scn.P2).getDecisionType() == AwaitingDecisionType.MULTIPLE_CHOICE);
}
}

View File

@@ -4,6 +4,7 @@ import com.gempukku.lotro.cards.GenericCardTestHelper;
import com.gempukku.lotro.common.*;
import com.gempukku.lotro.game.CardNotFoundException;
import com.gempukku.lotro.game.PhysicalCardImpl;
import com.gempukku.lotro.logic.decisions.AwaitingDecisionType;
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
import org.junit.Test;
@@ -152,4 +153,91 @@ public class Card_01_234_ErrataTests
assertFalse(scn.ShadowDecisionAvailable("play a unique WRAITH minion"));
}
@Test
public void CancelingNerteaAfterFirstMinionDoesntAskAgain() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
scn.FreepsMoveCharToTable("comp2", "comp3", "comp4", "comp5", "comp6");
PhysicalCardImpl twk = scn.GetShadowCard("twk");
PhysicalCardImpl attea = scn.GetShadowCard("attea");
PhysicalCardImpl nertea = scn.GetShadowCard("nertea");
PhysicalCardImpl runner = scn.GetShadowCard("runner");
scn.ShadowMoveCardToDiscard("rit", "twk", "attea");
scn.ShadowMoveCardToDiscard(twk, runner);
scn.ShadowMoveCardToHand(nertea);
scn.StartGame();
scn.SetTwilight(30);
scn.FreepsPassCurrentPhaseAction();
scn.ShadowPlayCard(nertea);
assertTrue(scn.ShadowDecisionAvailable("play a unique WRAITH minion"));
scn.ShadowChooseNo();
assertFalse(scn.ShadowDecisionAvailable("play a unique WRAITH minion"));
}
@Test
public void NerteaDoesNotPromptIfNoUniqueRingwraithMinionsInDiscardPile() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
scn.FreepsMoveCharToTable("comp2", "comp3", "comp4", "comp5", "comp6");
PhysicalCardImpl nertea = scn.GetShadowCard("nertea");
scn.ShadowMoveCardToHand("twk", "attea");
scn.ShadowMoveCardToDiscard("rit", "runner");
scn.ShadowMoveCardToHand(nertea);
scn.StartGame();
scn.SetTwilight(30);
scn.FreepsPassCurrentPhaseAction();
scn.ShadowPlayCard(nertea);
assertFalse(scn.ShadowDecisionAvailable("play a unique WRAITH minion"));
}
//Imported from the at tests
@Test
public void ulaireNerteaCantPlayMinionsOnGreatRiver() throws Exception {
var scn = GetScenario();
var _game = scn._game;
for (int i=0; i<4; i++) {
final PhysicalCardImpl pippin = scn.createCard(scn.P1, "1_306");
_game.getGameState().addCardToZone(_game, pippin, Zone.FREE_CHARACTERS);
}
scn.skipMulligans();
final PhysicalCardImpl greatRiver = scn.createCard(scn.P2, "3_118");
greatRiver.setSiteNumber(2);
_game.getGameState().addCardToZone(_game, greatRiver, Zone.ADVENTURE_PATH);
final PhysicalCardImpl ulaireNertea = scn.createCard(scn.P2, "1_234");
_game.getGameState().addCardToZone(_game, ulaireNertea, Zone.HAND);
final PhysicalCardImpl goblinRunner = scn.createCard(scn.P2, "1_178");
_game.getGameState().addCardToZone(_game, goblinRunner, Zone.DISCARD);
final PhysicalCardImpl ringwraithInTwilight = scn.createCard(scn.P2, "101_40");
_game.getGameState().addCardToZone(_game, ringwraithInTwilight, Zone.DISCARD);
final PhysicalCardImpl witchKing = scn.createCard(scn.P2, "2_85");
_game.getGameState().addCardToZone(_game, witchKing, Zone.DISCARD);
_game.getGameState().setTwilight(20);
// Fellowship phase
scn.playerDecided(scn.P1, "");
assertEquals(greatRiver, _game.getGameState().getCurrentSite());
scn.playerDecided(scn.P2, scn.getCardActionId(scn.P2, "Play Úlairë Nertëa"));
assertFalse(scn._userFeedback.getAwaitingDecision(scn.P2).getDecisionType() == AwaitingDecisionType.MULTIPLE_CHOICE);
}
}