Alteration to the CopyCard json functionality
- Added a trigger to CopyCard which automatically unapplies/reapplies the copier when the thing they copy is played - Added unit tests for Hobbit Farmer extensively checking each use case; in particular modifier sites vs ability sites - Various minor formatting fixes in other unit tests - Dare I say it? "These stupid site copy allies are finally fixed."
This commit is contained in:
@@ -2,9 +2,13 @@ package com.gempukku.lotro.cards.build.field;
|
||||
|
||||
import com.gempukku.lotro.cards.build.InvalidCardDefinitionException;
|
||||
import com.gempukku.lotro.common.Side;
|
||||
import org.hjson.JsonValue;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class FieldUtils {
|
||||
@@ -106,6 +110,13 @@ public class FieldUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private static final JSONParser parser = new JSONParser();
|
||||
public static JSONObject parseSubObject(String jsonString) throws ParseException {
|
||||
String json = JsonValue.readHjson(jsonString).toString();
|
||||
var subObject = (JSONObject) parser.parse(json);
|
||||
return subObject;
|
||||
}
|
||||
|
||||
private static boolean contains(String[] fields, String key) {
|
||||
for (String field : fields) {
|
||||
if (field.equals(key))
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.gempukku.lotro.cards.build.FilterableSource;
|
||||
import com.gempukku.lotro.cards.build.InvalidCardDefinitionException;
|
||||
import com.gempukku.lotro.cards.build.field.EffectProcessor;
|
||||
import com.gempukku.lotro.cards.build.field.FieldUtils;
|
||||
import com.gempukku.lotro.cards.build.field.effect.trigger.TriggerChecker;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
public class CopyCard implements EffectProcessor {
|
||||
@@ -15,8 +16,42 @@ public class CopyCard implements EffectProcessor {
|
||||
|
||||
final String filter = FieldUtils.getString(value.get("filter"), "filter");
|
||||
|
||||
final String autoRefreshTriggerString = """
|
||||
{
|
||||
type: trigger
|
||||
trigger: {
|
||||
type: played
|
||||
filter: """ + filter + """
|
||||
|
||||
}
|
||||
effect: {
|
||||
type: RefreshSelf
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment);
|
||||
|
||||
blueprint.appendCopiedFilter(filterableSource);
|
||||
|
||||
//Now we add an automatic trigger that unapplies/reapplies this card so that
|
||||
// modifiers etc do not get stuck.
|
||||
|
||||
try {
|
||||
var action = FieldUtils.parseSubObject(autoRefreshTriggerString);
|
||||
var trigger = (JSONObject) action.get("trigger");
|
||||
final var triggerChecker = environment
|
||||
.getTriggerCheckerFactory().getTriggerChecker(trigger, environment);
|
||||
|
||||
var triggerActionSource = new DefaultActionSource();
|
||||
triggerActionSource.addPlayRequirement(triggerChecker);
|
||||
EffectUtils.processRequirementsCostsAndEffects(action, environment, triggerActionSource);
|
||||
|
||||
blueprint.appendRequiredAfterTrigger(triggerActionSource);
|
||||
}
|
||||
catch(Exception ex) {
|
||||
throw new InvalidCardDefinitionException("CopyCard could not create auto refresh trigger.", ex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -111,6 +111,7 @@ public class EffectAppenderFactory {
|
||||
effectAppenderProducers.put("putstackedcardsintohand", new PutStackedCardsIntoHand());
|
||||
effectAppenderProducers.put("reconcilehand", new ReconcileHand());
|
||||
effectAppenderProducers.put("reducearcherytotal", new ReduceArcheryTotal());
|
||||
effectAppenderProducers.put("refreshself", new RefreshSelf());
|
||||
effectAppenderProducers.put("reinforcetokens", new ReinforceTokens());
|
||||
effectAppenderProducers.put("removeburdens", new RemoveBurdens());
|
||||
effectAppenderProducers.put("removecardsindiscardfromgame", new RemoveCardsInDiscardFromGame());
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
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.field.FieldUtils;
|
||||
import com.gempukku.lotro.cards.build.field.effect.EffectAppender;
|
||||
import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer;
|
||||
import com.gempukku.lotro.game.state.LotroGame;
|
||||
import com.gempukku.lotro.logic.actions.CostToEffectAction;
|
||||
import com.gempukku.lotro.logic.effects.PutOnTheOneRingEffect;
|
||||
import com.gempukku.lotro.logic.timing.Effect;
|
||||
import com.gempukku.lotro.logic.timing.PlayConditions;
|
||||
import com.gempukku.lotro.logic.timing.UnrespondableEffect;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
public class RefreshSelf implements EffectAppenderProducer {
|
||||
@Override
|
||||
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
|
||||
FieldUtils.validateAllowedFields(effectObject);
|
||||
|
||||
//This is intended to be used with cards using CopyCard, such as Hobbit Farmer.
|
||||
// This very well might have side-effects including removing modifiers applied this turn.
|
||||
return new DelayedAppender() {
|
||||
@Override
|
||||
protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext ac) {
|
||||
return new UnrespondableEffect() {
|
||||
@Override
|
||||
protected void doPlayEffect(LotroGame game) {
|
||||
ac.getGame().getGameState().reapplyAffectingForCard(ac.getGame(), ac.getSource());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -637,6 +637,16 @@ public class GenericCardTestHelper extends AbstractAtTest {
|
||||
SkipToPhase(Phase.ASSIGNMENT);
|
||||
PassCurrentPhaseActions();
|
||||
}
|
||||
public void SkipToMovementDecision() throws DecisionResultInvalidException {
|
||||
SkipToPhase(Phase.REGROUP);
|
||||
PassCurrentPhaseActions();
|
||||
if(ShadowDecisionAvailable("reconcile")) {
|
||||
ShadowDeclineReconciliation();
|
||||
}
|
||||
while(ShadowDecisionAvailable("discard down")) {
|
||||
ShadowChooseCard((PhysicalCardImpl) GetShadowHand().get(0));
|
||||
}
|
||||
}
|
||||
public void SkipToPhase(Phase target) throws DecisionResultInvalidException {
|
||||
for(int attempts = 1; attempts <= 20; attempts++)
|
||||
{
|
||||
@@ -1040,7 +1050,7 @@ public class GenericCardTestHelper extends AbstractAtTest {
|
||||
{
|
||||
ShadowDeclineReconciliation();
|
||||
}
|
||||
if(ShadowDecisionAvailable("discard down"))
|
||||
while(ShadowDecisionAvailable("discard down"))
|
||||
{
|
||||
ShadowChooseCard((PhysicalCardImpl) GetShadowHand().get(0));
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package com.gempukku.lotro.cards.official.set01;
|
||||
|
||||
import com.gempukku.lotro.cards.GenericCardTestHelper;
|
||||
import com.gempukku.lotro.common.Phase;
|
||||
import com.gempukku.lotro.common.SitesBlock;
|
||||
import com.gempukku.lotro.common.*;
|
||||
import com.gempukku.lotro.game.CardNotFoundException;
|
||||
import com.gempukku.lotro.game.PhysicalCardImpl;
|
||||
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
|
||||
@@ -72,6 +71,10 @@ public class Card_01_040_Tests
|
||||
PhysicalCardImpl elrond = scn.GetFreepsCard("elrond");
|
||||
|
||||
assertTrue(elrond.getBlueprint().isUnique());
|
||||
assertEquals(Side.FREE_PEOPLE, elrond.getBlueprint().getSide());
|
||||
assertEquals(Culture.ELVEN, elrond.getBlueprint().getCulture());
|
||||
assertEquals(CardType.ALLY, elrond.getBlueprint().getCardType());
|
||||
assertEquals(Race.ELF, elrond.getBlueprint().getRace());
|
||||
assertEquals(4, elrond.getBlueprint().getTwilightCost());
|
||||
assertEquals(8, elrond.getBlueprint().getStrength());
|
||||
assertEquals(4, elrond.getBlueprint().getVitality());
|
||||
|
||||
@@ -0,0 +1,347 @@
|
||||
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.DecisionResultInvalidException;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class Card_01_295_Tests
|
||||
{
|
||||
|
||||
protected GenericCardTestHelper GetScenario() throws CardNotFoundException, DecisionResultInvalidException {
|
||||
return new GenericCardTestHelper(
|
||||
new HashMap<>()
|
||||
{{
|
||||
put("farmer", "1_295");
|
||||
put("farmer2", "1_295");
|
||||
put("merry", "4_310");
|
||||
put("pippin", "4_314");
|
||||
|
||||
}},
|
||||
new HashMap<>() {{
|
||||
put("site1", "1_321");
|
||||
put("site2", "1_327");
|
||||
put("site3", "1_337");
|
||||
put("site4", "1_343");
|
||||
put("site5", "1_349");
|
||||
put("site6", "1_350");
|
||||
put("site7", "1_353");
|
||||
put("site8", "1_356");
|
||||
put("site9", "1_360");
|
||||
}},
|
||||
GenericCardTestHelper.FOTRFrodo,
|
||||
GenericCardTestHelper.RulingRing
|
||||
);
|
||||
}
|
||||
|
||||
protected GenericCardTestHelper GetDiscountScenario() throws CardNotFoundException, DecisionResultInvalidException {
|
||||
return new GenericCardTestHelper(
|
||||
new HashMap<>()
|
||||
{{
|
||||
put("farmer", "1_295");
|
||||
put("farmer2", "1_295");
|
||||
put("merry", "4_310");
|
||||
put("pippin", "4_314");
|
||||
put("sam", "1_311");
|
||||
}},
|
||||
new HashMap<>() {{
|
||||
put("site1", "1_323");
|
||||
put("site2", "1_327");
|
||||
put("site3", "1_337");
|
||||
put("site4", "1_343");
|
||||
put("site5", "1_349");
|
||||
put("site6", "1_350");
|
||||
put("site7", "1_353");
|
||||
put("site8", "1_356");
|
||||
put("site9", "1_360");
|
||||
}},
|
||||
GenericCardTestHelper.FOTRFrodo,
|
||||
GenericCardTestHelper.RulingRing
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void FarmerStatsAndKeywordsAreCorrect() throws DecisionResultInvalidException, CardNotFoundException {
|
||||
|
||||
/**
|
||||
* Set: 1
|
||||
* Title: Hobbit Farmer
|
||||
* Unique: false
|
||||
* Side: Free Peoples
|
||||
* Culture: Shire
|
||||
* Twilight Cost: 1
|
||||
* Type: Ally
|
||||
* Race: Hobbit
|
||||
* Game Text: While you can spot your site 1, this ally has the game text of that site.
|
||||
* Fellowship: Exert this ally and spot your opponent's site 1 to replace it with your site 1.
|
||||
*/
|
||||
|
||||
//Pre-game setup
|
||||
var scn = GetScenario();
|
||||
|
||||
var farmer = scn.GetFreepsCard("farmer");
|
||||
|
||||
assertFalse(farmer.getBlueprint().isUnique());
|
||||
assertEquals(Side.FREE_PEOPLE, farmer.getBlueprint().getSide());
|
||||
assertEquals(Culture.SHIRE, farmer.getBlueprint().getCulture());
|
||||
assertEquals(CardType.ALLY, farmer.getBlueprint().getCardType());
|
||||
assertEquals(Race.HOBBIT, farmer.getBlueprint().getRace());
|
||||
assertEquals(1, farmer.getBlueprint().getTwilightCost());
|
||||
assertEquals(2, farmer.getBlueprint().getStrength());
|
||||
assertEquals(2, farmer.getBlueprint().getVitality());
|
||||
assertEquals(1, farmer.getBlueprint().getAllyHomeSiteNumbers()[0]);
|
||||
assertEquals(SitesBlock.FELLOWSHIP, farmer.getBlueprint().getAllyHomeSiteBlock());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void FarmerCopiesAbilitiesOnOwnSite1ButNotOpponentSite1() throws DecisionResultInvalidException, CardNotFoundException {
|
||||
//Pre-game setup
|
||||
var scn = GetScenario();
|
||||
|
||||
//Player 1 version of the Farmer will test copying one's own site
|
||||
var freepsFarmer = scn.GetFreepsCard("farmer");
|
||||
var merry = scn.GetFreepsCard("merry");
|
||||
var pippin = scn.GetFreepsCard("pippin");
|
||||
scn.FreepsMoveCardToSupportArea(freepsFarmer);
|
||||
scn.AddWoundsToChar(freepsFarmer, 1); // To ensure the exert ability isn't available
|
||||
scn.FreepsMoveCardsToTopOfDeck(merry, pippin);
|
||||
|
||||
//Player 2 version of the Farmer will test copying the enemy site
|
||||
var evilFarmer = scn.GetShadowCard("farmer");
|
||||
var evilMerry = scn.GetShadowCard("merry");
|
||||
var evilPippin = scn.GetShadowCard("pippin");
|
||||
scn.ShadowMoveCardToSupportArea(evilFarmer);
|
||||
scn.AddWoundsToChar(evilFarmer, 1); // To ensure the exert ability isn't available
|
||||
|
||||
scn.StartGame();
|
||||
|
||||
assertTrue(scn.FreepsActionAvailable("Farmer Maggot's Fields"));
|
||||
assertTrue(scn.FreepsActionAvailable("Use Hobbit Farmer"));
|
||||
|
||||
scn.SkipToMovementDecision();
|
||||
scn.ShadowMoveCardsToTopOfDeck(evilMerry, evilPippin);
|
||||
scn.FreepsChooseToStay();
|
||||
|
||||
assertEquals(Phase.FELLOWSHIP, scn.GetCurrentPhase());
|
||||
assertEquals(1, scn.GetVitality(evilFarmer));
|
||||
|
||||
//Since the site is player 1's, player 2 should not have access to it via Hobbit Farmer, only natively
|
||||
assertTrue(scn.ShadowActionAvailable("Farmer Maggot's Fields"));
|
||||
assertFalse(scn.ShadowActionAvailable("Use Hobbit Farmer"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void FarmerCopiesModifiersOnOwnSite1ButNotOpponentSite1() throws DecisionResultInvalidException, CardNotFoundException {
|
||||
//Pre-game setup
|
||||
var scn = GetDiscountScenario();
|
||||
|
||||
//Player 1 version of the Farmer will test copying one's own site
|
||||
var freepsFarmer = scn.GetFreepsCard("farmer");
|
||||
var sam = scn.GetFreepsCard("sam");
|
||||
scn.FreepsMoveCardToSupportArea(freepsFarmer);
|
||||
scn.FreepsMoveCardToHand(sam);
|
||||
|
||||
//Player 2 version of the Farmer will test copying the enemy site
|
||||
var evilFarmer = scn.GetShadowCard("farmer");
|
||||
var evilSam = scn.GetShadowCard("sam");
|
||||
scn.ShadowMoveCardToSupportArea(evilFarmer);
|
||||
scn.ShadowMoveCardToHand(evilSam);
|
||||
|
||||
scn.StartGame();
|
||||
|
||||
assertEquals(2, sam.getBlueprint().getTwilightCost());
|
||||
assertEquals(0, scn.GetTwilight());
|
||||
scn.FreepsPlayCard(sam);
|
||||
//Both the Green Hill Country and Hobbit Farmer should have stacked to make Sam -2.
|
||||
assertEquals(0, scn.GetTwilight());
|
||||
|
||||
scn.SkipToMovementDecision();
|
||||
scn.FreepsChooseToStay();
|
||||
|
||||
assertEquals(Phase.FELLOWSHIP, scn.GetCurrentPhase());
|
||||
|
||||
//Since the site is player 1's, player 2 should not have access to it via Hobbit Farmer, only natively
|
||||
assertEquals(2, evilSam.getBlueprint().getTwilightCost());
|
||||
assertEquals(0, scn.GetTwilight());
|
||||
scn.ShadowPlayCard(evilSam);
|
||||
assertEquals(1, scn.GetTwilight());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void FarmerAbilityExertsToReplaceOpponentsSite1() throws DecisionResultInvalidException, CardNotFoundException {
|
||||
//Pre-game setup
|
||||
var scn = GetScenario();
|
||||
|
||||
var opponentSite1 = scn.GetCurrentSite();
|
||||
scn.FreepsMoveCardToSupportArea("farmer");
|
||||
|
||||
//Player 2 version of the Farmer will test replacing
|
||||
var evilFarmer = scn.GetShadowCard("farmer");
|
||||
var evilMerry = scn.GetShadowCard("merry");
|
||||
var evilPippin = scn.GetShadowCard("pippin");
|
||||
var site1 = scn.GetShadowSite("site1");
|
||||
|
||||
scn.ShadowMoveCardToSupportArea(evilFarmer);
|
||||
|
||||
scn.StartGame();
|
||||
|
||||
assertFalse(scn.FreepsDecisionAvailable("Use Hobbit Farmer"));
|
||||
|
||||
scn.SkipToMovementDecision();
|
||||
scn.ShadowMoveCardsToTopOfDeck(evilMerry, evilPippin);
|
||||
scn.FreepsChooseToStay();
|
||||
|
||||
assertEquals(Phase.FELLOWSHIP, scn.GetCurrentPhase());
|
||||
|
||||
assertSame(opponentSite1, scn.GetCurrentSite());
|
||||
assertEquals(Zone.ADVENTURE_DECK, site1.getZone());
|
||||
assertTrue(scn.ShadowActionAvailable(evilFarmer));
|
||||
assertEquals(2, scn.GetVitality(evilFarmer));
|
||||
|
||||
scn.ShadowUseCardAction(evilFarmer);
|
||||
|
||||
assertSame(site1, scn.GetCurrentSite());
|
||||
assertEquals(Zone.ADVENTURE_DECK, opponentSite1.getZone());
|
||||
assertEquals(1, scn.GetVitality(evilFarmer));
|
||||
|
||||
//Now that we have replaced the site, the Hobbit Farmer should now automatically be copying it.
|
||||
assertTrue(scn.ShadowActionAvailable("Farmer Maggot's Fields"));
|
||||
assertTrue(scn.ShadowActionAvailable("Use Hobbit Farmer"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void FarmerImmediatelyCopiesAbilitiesAfterReplacingDownThePath() throws DecisionResultInvalidException, CardNotFoundException {
|
||||
//Pre-game setup
|
||||
var scn = GetScenario();
|
||||
|
||||
var opponentSite1 = scn.GetCurrentSite();
|
||||
scn.FreepsMoveCardToSupportArea("farmer");
|
||||
|
||||
//Player 2 version of the Farmer will test replacing
|
||||
var evilFarmer = scn.GetShadowCard("farmer");
|
||||
var evilMerry = scn.GetShadowCard("merry");
|
||||
var evilPippin = scn.GetShadowCard("pippin");
|
||||
var site1 = scn.GetShadowSite("site1");
|
||||
|
||||
scn.ShadowMoveCardToSupportArea(evilFarmer);
|
||||
|
||||
scn.StartGame();
|
||||
|
||||
assertFalse(scn.FreepsDecisionAvailable("Use Hobbit Farmer"));
|
||||
|
||||
//Getting everyone far away from site 1
|
||||
scn.SkipToSite(3);
|
||||
|
||||
scn.SkipToMovementDecision();
|
||||
scn.ShadowMoveCardsToTopOfDeck(evilMerry, evilPippin);
|
||||
scn.FreepsChooseToStay();
|
||||
scn.FreepsDeclineReconciliation();
|
||||
|
||||
assertEquals(Phase.FELLOWSHIP, scn.GetCurrentPhase());
|
||||
|
||||
assertEquals(Zone.ADVENTURE_PATH, opponentSite1.getZone());
|
||||
assertEquals(Zone.ADVENTURE_DECK, site1.getZone());
|
||||
assertTrue(scn.ShadowActionAvailable(evilFarmer));
|
||||
assertEquals(2, scn.GetVitality(evilFarmer));
|
||||
|
||||
scn.ShadowUseCardAction(evilFarmer);
|
||||
|
||||
assertEquals(Zone.ADVENTURE_PATH, site1.getZone());
|
||||
assertEquals(Zone.ADVENTURE_DECK, opponentSite1.getZone());
|
||||
assertEquals(1, scn.GetVitality(evilFarmer));
|
||||
|
||||
//Now that we have replaced the site, the Hobbit Farmer should now automatically be copying it.
|
||||
assertTrue(scn.ShadowActionAvailable("Use Hobbit Farmer"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void FarmerCopiesModifiersDownThePath() throws DecisionResultInvalidException, CardNotFoundException {
|
||||
//Pre-game setup
|
||||
var scn = GetDiscountScenario();
|
||||
|
||||
var farmer = scn.GetFreepsCard("farmer");
|
||||
var merry = scn.GetFreepsCard("merry");
|
||||
var pippin = scn.GetFreepsCard("pippin");
|
||||
var site1 = scn.GetCurrentSite();
|
||||
scn.FreepsMoveCardToSupportArea("farmer");
|
||||
scn.FreepsMoveCardToHand(merry, pippin);
|
||||
|
||||
var opponentSite1 = scn.GetShadowSite("site1");
|
||||
|
||||
scn.StartGame();
|
||||
|
||||
//Ensuring Green Hill Country's -1 twilight discount is working natively.
|
||||
assertEquals(1, pippin.getBlueprint().getTwilightCost());
|
||||
assertEquals(0, scn.GetTwilight());
|
||||
scn.FreepsPlayCard(pippin);
|
||||
assertEquals(0, scn.GetTwilight());
|
||||
|
||||
//Getting everyone far away from site 1
|
||||
scn.SkipToSite(3);
|
||||
|
||||
assertEquals(Phase.FELLOWSHIP, scn.GetCurrentPhase());
|
||||
|
||||
assertEquals(Zone.ADVENTURE_DECK, opponentSite1.getZone());
|
||||
assertEquals(Zone.ADVENTURE_PATH, site1.getZone());
|
||||
|
||||
//We've never replaced the site, but the Hobbit Farmer should still automatically be copying the twilight discount.
|
||||
assertEquals(1, merry.getBlueprint().getTwilightCost());
|
||||
assertEquals(0, scn.GetTwilight());
|
||||
scn.FreepsPlayCard(merry);
|
||||
assertEquals(0, scn.GetTwilight());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void FarmerImmediatelyCopiesModifiersAfterReplacingDownThePath() throws DecisionResultInvalidException, CardNotFoundException {
|
||||
//Pre-game setup
|
||||
var scn = GetDiscountScenario();
|
||||
|
||||
var opponentSite1 = scn.GetCurrentSite();
|
||||
scn.FreepsMoveCardToSupportArea("farmer");
|
||||
|
||||
//Player 2 version of the Farmer will test replacing
|
||||
var evilFarmer = scn.GetShadowCard("farmer");
|
||||
var evilMerry = scn.GetShadowCard("merry");
|
||||
var site1 = scn.GetShadowSite("site1");
|
||||
|
||||
scn.ShadowMoveCardToSupportArea(evilFarmer);
|
||||
|
||||
scn.StartGame();
|
||||
|
||||
assertFalse(scn.FreepsDecisionAvailable("Use Hobbit Farmer"));
|
||||
|
||||
//Getting everyone far away from site 1
|
||||
scn.SkipToSite(3);
|
||||
|
||||
scn.SkipToMovementDecision();
|
||||
scn.FreepsChooseToStay();
|
||||
scn.FreepsDeclineReconciliation();
|
||||
|
||||
assertEquals(Phase.FELLOWSHIP, scn.GetCurrentPhase());
|
||||
|
||||
assertEquals(Zone.ADVENTURE_PATH, opponentSite1.getZone());
|
||||
assertEquals(Zone.ADVENTURE_DECK, site1.getZone());
|
||||
assertTrue(scn.ShadowActionAvailable(evilFarmer));
|
||||
assertEquals(2, scn.GetVitality(evilFarmer));
|
||||
|
||||
scn.ShadowUseCardAction(evilFarmer);
|
||||
|
||||
assertEquals(Zone.ADVENTURE_PATH, site1.getZone());
|
||||
assertEquals(Zone.ADVENTURE_DECK, opponentSite1.getZone());
|
||||
assertEquals(1, scn.GetVitality(evilFarmer));
|
||||
|
||||
//Now that we have replaced the site, the Hobbit Farmer should now automatically be copying the twilight discount.
|
||||
assertEquals(1, evilMerry.getBlueprint().getTwilightCost());
|
||||
assertEquals(0, scn.GetTwilight());
|
||||
scn.ShadowPlayCard(evilMerry);
|
||||
assertEquals(0, scn.GetTwilight());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,6 +27,7 @@ public class Card_03_068_ErrataTests
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void SarumanStatsAndKeywordsAreCorrect() throws DecisionResultInvalidException, CardNotFoundException {
|
||||
|
||||
/**
|
||||
@@ -59,7 +60,7 @@ public class Card_03_068_ErrataTests
|
||||
assertEquals(4, saruman.getBlueprint().getTwilightCost());
|
||||
assertEquals(8, saruman.getBlueprint().getStrength());
|
||||
assertEquals(4, saruman.getBlueprint().getVitality());
|
||||
assertEquals(4, saruman.getBlueprint().getSiteNumber()); // Change this to getAllyHomeSiteNumbers for allies
|
||||
assertEquals(4, saruman.getBlueprint().getSiteNumber());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -45,7 +45,9 @@ public class Card_03_090_ErrataTests
|
||||
* Twilight Cost: 0
|
||||
* Type: event
|
||||
* Subtype: Maneuver
|
||||
* Game Text: Exert a unique [sauron] minion to exert a companion (except the Ring-bearer) and discard a possession attached to that companion. The Free Peoples player may discard 1 hand at random from their hand to prevent this.
|
||||
* Game Text: Exert a unique [sauron] minion to exert a companion (except the Ring-bearer) and
|
||||
* discard a possession attached to that companion. The Free Peoples player may discard 1
|
||||
* card at random from their hand to prevent this.
|
||||
*/
|
||||
|
||||
//Pre-game setup
|
||||
|
||||
@@ -65,7 +65,9 @@ public class Card_03_103_ErrataTests
|
||||
* Twilight Cost: 0
|
||||
* Type: event
|
||||
* Subtype:
|
||||
* Game Text: <b>Maneuver:</b> Spot a [sauron] minion to wound Galadriel 3 times. The Free Peoples player may discard 2 Elves to prevent this. If Galadriel is Ring-bound, 2 burdens may be added instead.
|
||||
* Game Text: <b>Maneuver:</b> Spot a [sauron] minion to wound Galadriel 3 times.
|
||||
* The Free Peoples player may discard 2 Elves to prevent this. If Galadriel is
|
||||
* Ring-bound, 2 burdens may be added instead.
|
||||
*/
|
||||
|
||||
//Pre-game setup
|
||||
|
||||
Reference in New Issue
Block a user