Fixing FOTR Nertea (and errata) continuing to ask the user for each potential minion.
This commit is contained in:
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user