Converted All Life Flees and wrote unit tests for it, before realizing it's not actually broken, it's just bad.

This commit is contained in:
Christian 'ketura' McCarty
2022-08-02 17:09:43 -05:00
parent 8522c10831
commit 9ca35cee95
4 changed files with 245 additions and 81 deletions

View File

@@ -0,0 +1,40 @@
{
"18_132": {
"title": "All Life Flees",
"subtitle": "Duplicitous Lieutenant",
"side": "shadow",
"culture": "Wraith",
"cost": 2,
"type": "event",
"keyword": "Shadow",
"condition": {
"type": "canSpot",
"filter": "nazgul"
},
"effects": {
"type": "event",
"cost": {
"type": "chooseAndRemoveTwilight",
"memorize": "X"
},
"effect": {
"type": "choice",
"texts": [
"Discard a follower from play with a twilight cost of {X}",
"Play a {wraith} minion from your draw deck with a twilight cost of {X}"
],
"effects": [
{
"type": "discard",
"filter": "choose(follower,minTwilight(memory(X)),maxTwilight(memory(X)))"
},
{
"type": "playCardFromDrawDeck",
"filter": "choose(culture(wraith),minion,minTwilight(memory(X)),maxTwilight(memory(X)))"
},
]
}
}
},
}

View File

@@ -1,80 +0,0 @@
package com.gempukku.lotro.cards.set18.wraith;
import com.gempukku.lotro.common.*;
import com.gempukku.lotro.filters.Filters;
import com.gempukku.lotro.game.PhysicalCard;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.actions.PlayEventAction;
import com.gempukku.lotro.logic.cardtype.AbstractEvent;
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
import com.gempukku.lotro.logic.decisions.IntegerAwaitingDecision;
import com.gempukku.lotro.logic.effects.ChoiceEffect;
import com.gempukku.lotro.logic.effects.PlayoutDecisionEffect;
import com.gempukku.lotro.logic.effects.RemoveTwilightEffect;
import com.gempukku.lotro.logic.effects.choose.ChooseAndDiscardCardsFromPlayEffect;
import com.gempukku.lotro.logic.effects.choose.ChooseAndPlayCardFromDeckEffect;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.PlayConditions;
import com.gempukku.lotro.logic.timing.UnrespondableEffect;
import java.util.LinkedList;
import java.util.List;
/**
* Set: Treachery & Deceit
* Side: Shadow
* Culture: Wraith
* Twilight Cost: 2
* Type: Event • Shadow
* Game Text: To play, spot a Nazgul. Remove (X) to choose one: discard a follower from play that has a twilight
* cost of X; or play from deck a [WRAITH] minion that has a twilight cost of X.
*/
public class Card18_132 extends AbstractEvent {
public Card18_132() {
super(Side.SHADOW, 2, Culture.WRAITH, "All Life Flees", Phase.SHADOW);
}
@Override
public boolean checkPlayRequirements(LotroGame game, PhysicalCard self) {
return PlayConditions.canSpot(game, Race.NAZGUL);
}
@Override
public PlayEventAction getPlayEventCardAction(final String playerId, LotroGame game, PhysicalCard self) {
final PlayEventAction action = new PlayEventAction(self);
action.appendCost(
new UnrespondableEffect() {
@Override
protected void doPlayEffect(LotroGame game) {
action.appendCost(
new PlayoutDecisionEffect(playerId,
new IntegerAwaitingDecision(1, "Choose X", 0, game.getGameState().getTwilightPool()) {
@Override
public void decisionMade(String result) throws DecisionResultInvalidException {
final int twilight = getValidatedResult(result);
action.appendCost(
new RemoveTwilightEffect(twilight));
List<Effect> possibleEffects = new LinkedList<Effect>();
possibleEffects.add(
new ChooseAndDiscardCardsFromPlayEffect(action, playerId, 1, 1, CardType.FOLLOWER, Filters.printedTwilightCost(twilight)) {
@Override
public String getText(LotroGame game) {
return "Discard follower with twilight cost " + twilight;
}
});
possibleEffects.add(
new ChooseAndPlayCardFromDeckEffect(playerId, Culture.WRAITH, CardType.MINION, Filters.printedTwilightCost(twilight)) {
@Override
public String getText(LotroGame game) {
return "Play WRAITH minion with twilight cost " + twilight + " from deck";
}
});
action.appendEffect(
new ChoiceEffect(action, playerId, possibleEffects));
}
}));
}
});
return action;
}
}

View File

@@ -72,7 +72,7 @@ public class PlayCardFromDrawDeck implements EffectAppenderProducer {
final CostToEffectAction playCardAction = PlayUtils.getPlayCardAction(actionContext.getGame(), cardsToPlay.iterator().next(), costModifier, onFilterable, false);
return new StackActionEffect(playCardAction);
} else {
return null; //Fix Wizard is Never Late by changing this to a DoNothingEffect?
return null;
}
}

View File

@@ -0,0 +1,204 @@
package com.gempukku.lotro.cards.official.set18;
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.DecisionResultInvalidException;
import org.junit.Test;
import java.util.HashMap;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class Card_18_132_Tests
{
protected GenericCardTestHelper GetScenario() throws CardNotFoundException, DecisionResultInvalidException {
return new GenericCardTestHelper(
new HashMap<String, String>()
{{
put("flees", "18_132");
put("nazgul", "1_232");
put("orc", "7_196");
put("orc2", "7_192"); //2 cost to ensure that it trips the choice
put("cantea", "1_230");
put("twk", "1_237");
put("follower0", "18_47");
put("follower1", "18_17");
put("follower2", "15_26");
put("follower3", "18_7");
}}
);
}
@Test
public void AllLifeFleesStatsAndKeywordsAreCorrect() throws DecisionResultInvalidException, CardNotFoundException {
/**
* Set: 18
* Title: All Life Flees
* Side: Shadow
* Culture: Wraith
* Twilight Cost: 2
* Type: Event
* Subtype: Shadow
* Game Text: To play, spot a Nazgul.
* Remove (X) to choose one: discard a follower from play that has a twilight cost of X, or play from deck a
* [RINGWRAITH] minion that has a twilight cost of X.
*/
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
PhysicalCardImpl flees = scn.GetFreepsCard("flees");
assertFalse(flees.getBlueprint().isUnique());
assertEquals(Side.SHADOW, flees.getBlueprint().getSide());
assertEquals(Culture.WRAITH, flees.getBlueprint().getCulture());
assertEquals(CardType.EVENT, flees.getBlueprint().getCardType());
//assertEquals(Race.CREATURE, flees.getBlueprint().getRace());
assertTrue(scn.HasKeyword(flees, Keyword.SHADOW)); // test for keywords as needed
assertEquals(2, flees.getBlueprint().getTwilightCost());
//assertEquals(, flees.getBlueprint().getStrength());
//assertEquals(, flees.getBlueprint().getVitality());
//assertEquals(, flees.getBlueprint().getResistance());
//assertEquals(Signet., flees.getBlueprint().getSignet());
//assertEquals(, flees.getBlueprint().getSiteNumber()); // Change this to getAllyHomeSiteNumbers for allies
}
@Test
public void RequiresNazgulToPlay() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
PhysicalCardImpl flees = scn.GetShadowCard("flees");
PhysicalCardImpl nazgul = scn.GetShadowCard("nazgul");
scn.ShadowMoveCardToHand(flees, nazgul);
scn.StartGame();
scn.SetTwilight(10);
scn.FreepsPassCurrentPhaseAction();
assertFalse(scn.ShadowCardPlayAvailable(flees));
scn.ShadowPlayCard(nazgul);
assertTrue(scn.ShadowCardPlayAvailable(flees));
}
@Test
public void CanDiscardFollowerCostingX() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
PhysicalCardImpl flees = scn.GetShadowCard("flees");
PhysicalCardImpl nazgul = scn.GetShadowCard("nazgul");
PhysicalCardImpl orc = scn.GetShadowCard("orc");
PhysicalCardImpl cantea = scn.GetShadowCard("cantea");
scn.ShadowMoveCardToHand(flees);
scn.ShadowMoveCharToTable(nazgul);
PhysicalCardImpl follower0 = scn.GetFreepsCard("follower0");
PhysicalCardImpl follower1 = scn.GetFreepsCard("follower1");
PhysicalCardImpl follower2 = scn.GetFreepsCard("follower2");
PhysicalCardImpl follower3 = scn.GetFreepsCard("follower3");
scn.FreepsMoveCardToSupportArea(follower0, follower1, follower2, follower3);
scn.StartGame();
scn.SetTwilight(10);
scn.FreepsPassCurrentPhaseAction();
assertEquals(Zone.SUPPORT, follower2.getZone());
assertEquals(12, scn.GetTwilight()); // 10 initial, +2 from moving
scn.ShadowPlayCard(flees);
assertEquals(10, scn.GetTwilight());
scn.ShadowChoose("2");
assertEquals(8, scn.GetTwilight());
assertTrue(scn.ShadowDecisionAvailable("Choose action to perform"));
assertEquals(2, scn.ShadowGetMultipleChoices().size());
scn.ShadowChooseMultipleChoiceOption("Discard a follower");
assertEquals(Zone.DISCARD, follower2.getZone());
}
@Test
public void CanDiscardFollowerCosting0() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
PhysicalCardImpl flees = scn.GetShadowCard("flees");
PhysicalCardImpl nazgul = scn.GetShadowCard("nazgul");
scn.ShadowMoveCardToHand(flees);
scn.ShadowMoveCharToTable(nazgul);
PhysicalCardImpl follower0 = scn.GetFreepsCard("follower0");
PhysicalCardImpl follower1 = scn.GetFreepsCard("follower1");
PhysicalCardImpl follower2 = scn.GetFreepsCard("follower2");
PhysicalCardImpl follower3 = scn.GetFreepsCard("follower3");
scn.FreepsMoveCardToSupportArea(follower0, follower1, follower2, follower3);
scn.StartGame();
scn.SetTwilight(10);
scn.FreepsPassCurrentPhaseAction();
assertEquals(Zone.SUPPORT, follower0.getZone());
assertEquals(12, scn.GetTwilight()); // 10 initial, +2 from moving
scn.ShadowPlayCard(flees);
assertEquals(10, scn.GetTwilight());
scn.ShadowChoose("0");
assertEquals(10, scn.GetTwilight());
assertEquals(Zone.DISCARD, follower0.getZone());
}
@Test
public void CanPlayWraithMinionFromDrawDeck() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
PhysicalCardImpl flees = scn.GetShadowCard("flees");
PhysicalCardImpl nazgul = scn.GetShadowCard("nazgul");
PhysicalCardImpl orc = scn.GetShadowCard("orc");
PhysicalCardImpl cantea = scn.GetShadowCard("cantea");
PhysicalCardImpl twk = scn.GetShadowCard("twk");
scn.ShadowMoveCardToHand(flees);
scn.ShadowMoveCharToTable(nazgul);
scn.StartGame();
scn.SetTwilight(20);
scn.FreepsPassCurrentPhaseAction();
assertEquals(22, scn.GetTwilight()); // 20 initial, +2 from moving
scn.ShadowPlayCard(flees);
assertEquals(20, scn.GetTwilight());
assertEquals(5, orc.getBlueprint().getTwilightCost());
assertEquals(5, cantea.getBlueprint().getTwilightCost());
assertEquals(Zone.DECK, orc.getZone());
assertEquals(Zone.DECK, cantea.getZone());
scn.ShadowChoose("5");
assertEquals(2, scn.ShadowGetCardChoices().size()); // orc + cantea, but not TWK
scn.ShadowChooseCardBPFromSelection(orc);
assertEquals(Zone.SHADOW_CHARACTERS, orc.getZone());
}
}