Converted 3R17 to json. Updated 3R17 errata. Added support for reacting to "about to move to" actions.

This commit is contained in:
Christian 'ketura' McCarty
2022-08-17 04:30:04 -05:00
parent f15fbce0d1
commit b9034b07ad
12 changed files with 634 additions and 98 deletions

View File

@@ -31,4 +31,77 @@
}
}
}
3_17: {
cardInfo: {
//Either a full URL, or a subpath for the PC image server
imagePath: decipher/LOTR03017.jpg
//If this is true, then all gameplay-related info outside this cardInfo definition
// will be ignored and the java class loaded instead.
javaClass: false
//This instructs the blueprint generator to insert this card as an alt of the listed
// parent blueprint. Can of course be ommitted if not an errata or promo.
parent: null
//This is the tree path to use within the alts structure on the parent.
// Can of course be ommitted if parent is null.
parentPath: null
//Versioning differentiates releases within a particular alt path, such as PC errata
// version 1 vs version 2. PC version 2 will not conflict with, say, Decipher version 2.
//Top-level cards should always be version 0.
version: 0
collInfo: 3R17
rarity: R
setNum: "3"
cardNum: 17
// Standard, Masterwork, Tengwar, FullArt, etc. Top-level cards are always Standard.
style: Standard
}
title: Galadriel
subtitle: Lady of the Golden Wood
unique: true
culture: elven
twilight: 3
type: ally
allyHome: fellowship,6
race: elf
strength: 3
vitality: 3
effects: [
{
type: trigger
optional: true
trigger: {
type: startOfTurn
}
effect: {
type: heal
filter: choose(elf)
}
}
{
type: activated
phase: fellowship
cost: {
type: exert
filter: self
times: 1
}
effect: {
type: playNextSite
filter: forest
}
}
]
gametext: At the start of each of your turns, you may heal an Elf.<br><b>Fellowship:</b> Exert Galadriel to play the fellowship's next site if it is a forest (replacing opponent's site if necessary).
lore: "'There is in her and in this land no evil, unless a man bring it hither himself. Then let him beware!'"
promotext: ""
alts: {
//These are just CardInfo objects
promos: {
}
//These are full card definitions, with redundant info that is the same as the original card ommitted
errata: {
}
}
}
}

View File

@@ -47,22 +47,36 @@
trigger: {
type: startOfTurn
}
requires: {
type: canSpot
filter: Elf,wounded,not(name(Galadriel))
}
effect: {
type: heal
filter: choose(another,elf)
}
}
{
type: activated
phase: fellowship
type: trigger
optional: true
trigger: {
type: aboutToMoveTo
filter: not(your),siteHasSiteNumber
}
requires: {
type: phase
phase: fellowship
}
cost: {
type: exert
filter: self
times: 1
}
effect: {
type: playNextSite
type: playSite
filter: forest
number: {
type: currentSiteNumber
}
}
}
]

View File

@@ -216,7 +216,7 @@
effect: {
type: choice
texts: [
Stack a [Moria] item here.
Stack a [Moria] item from hand here.
Take a [Moria] card stacked here into hand.
]
effects: [

View File

@@ -1,60 +0,0 @@
package com.gempukku.lotro.cards.set3.elven;
import com.gempukku.lotro.common.*;
import com.gempukku.lotro.game.PhysicalCard;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.actions.ActivateCardAction;
import com.gempukku.lotro.logic.actions.OptionalTriggerAction;
import com.gempukku.lotro.logic.cardtype.AbstractAlly;
import com.gempukku.lotro.logic.effects.ChooseAndHealCharactersEffect;
import com.gempukku.lotro.logic.effects.PlaySiteEffect;
import com.gempukku.lotro.logic.effects.SelfExertEffect;
import com.gempukku.lotro.logic.timing.EffectResult;
import com.gempukku.lotro.logic.timing.PlayConditions;
import com.gempukku.lotro.logic.timing.TriggerConditions;
import java.util.Collections;
import java.util.List;
/**
* Set: Realms of Elf-lords
* Side: Free
* Culture: Elven
* Twilight Cost: 3
* Type: Ally • Home 6 • Elf
* Strength: 3
* Vitality: 3
* Site: 6
* Game Text: At the start of each of your turns, you may heal an Elf. Fellowship: Exert Galadriel to play
* the fellowship's next site if it is a forest (replacing opponent's site if necessary).
*/
public class Card3_017 extends AbstractAlly {
public Card3_017() {
super(3, SitesBlock.FELLOWSHIP, 6, 3, 3, Race.ELF, Culture.ELVEN, "Galadriel", "Lady of the Golden Wood", true);
}
@Override
public List<OptionalTriggerAction> getOptionalAfterTriggers(String playerId, LotroGame game, EffectResult effectResult, PhysicalCard self) {
if (TriggerConditions.startOfTurn(game, effectResult)) {
OptionalTriggerAction action = new OptionalTriggerAction(self);
action.appendEffect(
new ChooseAndHealCharactersEffect(action, playerId, 1, 1, Race.ELF));
return Collections.singletonList(action);
}
return null;
}
@Override
public List<? extends ActivateCardAction> getPhaseActionsInPlay(String playerId, LotroGame game, PhysicalCard self) {
if (PlayConditions.canUseFPCardDuringPhase(game, Phase.FELLOWSHIP, self)
&& PlayConditions.canExert(self, game, self)) {
ActivateCardAction action = new ActivateCardAction(self);
action.appendCost(
new SelfExertEffect(action, self));
action.appendEffect(
new PlaySiteEffect(action, playerId, null, game.getGameState().getCurrentSiteNumber() + 1, Keyword.FOREST));
return Collections.singletonList(action);
}
return null;
}
}

View File

@@ -0,0 +1,32 @@
package com.gempukku.lotro.cards.build.field.effect.trigger;
import com.gempukku.lotro.cards.build.ActionContext;
import com.gempukku.lotro.cards.build.CardGenerationEnvironment;
import com.gempukku.lotro.cards.build.FilterableSource;
import com.gempukku.lotro.cards.build.InvalidCardDefinitionException;
import com.gempukku.lotro.cards.build.field.FieldUtils;
import com.gempukku.lotro.logic.timing.TriggerConditions;
import org.json.simple.JSONObject;
public class AboutToMoveTo implements TriggerCheckerProducer {
@Override
public TriggerChecker getTriggerChecker(JSONObject value, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(value, "filter");
String filter = FieldUtils.getString(value.get("filter"), "filter", "any");
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment);
return new TriggerChecker() {
@Override
public boolean accepts(ActionContext actionContext) {
return TriggerConditions.isMovingTo(actionContext.getEffect(), actionContext.getGame(), filterableSource.getFilterable(actionContext));
}
@Override
public boolean isBefore() {
return true;
}
};
}
}

View File

@@ -16,6 +16,7 @@ public class TriggerCheckerFactory {
triggerCheckers.put("abouttodiscard", new AboutToDiscardFromPlay());
triggerCheckers.put("abouttoexert", new AboutToExert());
triggerCheckers.put("abouttoheal", new AboutToHeal());
triggerCheckers.put("abouttomoveto", new AboutToMoveTo());
triggerCheckers.put("abouttotakewound", new AboutToTakeWound());
triggerCheckers.put("activated", new ActivatedTriggerCheckerProducer());
triggerCheckers.put("addsburden", new AddsBurden());

View File

@@ -10,7 +10,8 @@ public interface Effect {
BEFORE_TAKE_CONTROL_OF_A_SITE,
BEFORE_SKIRMISH_RESOLVED,
BEFORE_THREAT_WOUNDS, BEFORE_TOIL,
BEFORE_DRAW_CARD
BEFORE_DRAW_CARD,
BEFORE_MOVE_FROM, BEFORE_MOVE, BEFORE_MOVE_TO
}
/**

View File

@@ -435,6 +435,14 @@ public class TriggerConditions {
return false;
}
public static boolean isMovingTo(Effect effect, LotroGame game, Filterable... filters) {
if (effect.getType() == Effect.Type.BEFORE_MOVE_TO
&& Filters.and(filters).accepts(game, game.getGameState().getCurrentSite()))
return true;
return false;
}
public static boolean movesFrom(LotroGame game, EffectResult effectResult, Filterable... filters) {
if (effectResult.getType() == EffectResult.Type.WHEN_MOVE_FROM
&& Filters.and(filters).accepts(game, ((WhenMoveFromResult) effectResult).getSite())) {

View File

@@ -9,6 +9,7 @@ import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.actions.SystemQueueAction;
import com.gempukku.lotro.logic.effects.AddTwilightEffect;
import com.gempukku.lotro.logic.effects.TriggeringResultEffect;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.UnrespondableEffect;
import com.gempukku.lotro.logic.timing.processes.GameProcess;
import com.gempukku.lotro.logic.timing.results.WhenMoveFromResult;
@@ -35,7 +36,7 @@ public class MovementGameProcess implements GameProcess {
});
game.getFormat().getAdventure().appendNextSiteAction(action);
action.appendEffect(
new TriggeringResultEffect(new WhenMoveFromResult(currentSite), "Fellowship moved from"));
new TriggeringResultEffect(Effect.Type.BEFORE_MOVE_FROM, new WhenMoveFromResult(currentSite), "Fellowship moved from"));
action.appendEffect(
new UnrespondableEffect() {
@Override
@@ -45,9 +46,9 @@ public class MovementGameProcess implements GameProcess {
}
});
action.appendEffect(
new TriggeringResultEffect(new WhenMovesResult(), "Fellowship moves"));
new TriggeringResultEffect(Effect.Type.BEFORE_MOVE, new WhenMovesResult(), "Fellowship moves"));
action.appendEffect(
new TriggeringResultEffect(new WhenMoveToResult(), "Fellowship moved to"));
new TriggeringResultEffect(Effect.Type.BEFORE_MOVE_TO, new WhenMoveToResult(), "Fellowship moved to"));
action.appendEffect(
new UnrespondableEffect() {
@Override

View File

@@ -173,6 +173,11 @@ public class GenericCardTestHelper extends AbstractAtTest {
List<PhysicalCardImpl> advDeck = (List<PhysicalCardImpl>)_game.getGameState().getAdventureDeck(playerID);
return advDeck.stream().filter(x -> x.getBlueprint().getSiteNumber() == siteNum).findFirst().get();
}
public PhysicalCardImpl GetSite(int siteNum)
{
return (PhysicalCardImpl) _game.getGameState().getSite(siteNum);
}
public PhysicalCardImpl GetFreepsSite(String name) { return GetSiteByName(P1, name); }
public PhysicalCardImpl GetShadowSite(String name) { return GetSiteByName(P2, name); }
public PhysicalCardImpl GetSiteByName(String player, String name)

View File

@@ -0,0 +1,257 @@
package com.gempukku.lotro.cards.official.set03;
import com.gempukku.lotro.cards.GenericCardTestHelper;
import com.gempukku.lotro.common.*;
import com.gempukku.lotro.filters.Filters;
import com.gempukku.lotro.game.CardNotFoundException;
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
import com.gempukku.lotro.logic.modifiers.KeywordModifier;
import org.junit.Test;
import java.util.HashMap;
import static org.junit.Assert.*;
public class Card_03_017_Tests
{
protected GenericCardTestHelper GetScenario() throws CardNotFoundException, DecisionResultInvalidException {
return new GenericCardTestHelper(
new HashMap<String, String>()
{{
put("galadriel", "3_17");
put("celeborn", "1_34");
put("greenleaf", "1_50");
}},
new HashMap<String, String>() {{
put("site1", "1_319");
put("site2", "1_332");
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("site2F", "1_329"); //We are cheating here and putting a second site 2 in
put("site2T", "4_330"); //and a Towers site 2
put("site2K", "7_337"); //and a King site 2
put("siteX", "11_231"); //and a Shadows site
}},
GenericCardTestHelper.FOTRFrodo,
GenericCardTestHelper.FOTRRing
);
}
protected GenericCardTestHelper GetExpandedScenario() throws CardNotFoundException, DecisionResultInvalidException {
return new GenericCardTestHelper(
new HashMap<String, String>()
{{
put("galadriel", "3_17");
// put other cards in here as needed for the test case
}},
new HashMap<String, String>() {{
put("site1", "1_319");
put("site2", "1_332");
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("site2F", "1_329"); //We are cheating here and putting a second site 2 in
put("site2T", "4_330"); //and a Towers site 2
put("site2K", "7_337"); //and a King site 2
put("siteX", "11_231"); //and a Shadows site
}},
GenericCardTestHelper.FOTRFrodo,
GenericCardTestHelper.FOTRRing,
"expanded"
);
}
@Test
public void GaladrielStatsAndKeywordsAreCorrect() throws DecisionResultInvalidException, CardNotFoundException {
/**
* Set: 3
* Title: *Galadriel, Lady of the Golden Wood
* Side: Free Peoples
* Culture: Elven
* Twilight Cost: 3
* Type: ally
* Subtype: Elf
* Strength: 3
* Vitality: 3
* Site Number: 6
* Game Text: At the start of each of your turns, you may heal another Elf.
* Fellowship: Exert Galadriel to play the fellowship's next site if it is a forest (replacing opponent's site if necessary).
*/
//Pre-game setup
var scn = GetScenario();
var galadriel = scn.GetFreepsCard("galadriel");
assertTrue(galadriel.getBlueprint().isUnique());
assertEquals(Side.FREE_PEOPLE, galadriel.getBlueprint().getSide());
assertEquals(Culture.ELVEN, galadriel.getBlueprint().getCulture());
assertEquals(CardType.ALLY, galadriel.getBlueprint().getCardType());
assertEquals(Race.ELF, galadriel.getBlueprint().getRace());
assertEquals(3, galadriel.getBlueprint().getTwilightCost());
assertEquals(3, galadriel.getBlueprint().getStrength());
assertEquals(3, galadriel.getBlueprint().getVitality());
//assertEquals(, galadriel.getBlueprint().getResistance());
//assertEquals(Signet., galadriel.getBlueprint().getSignet());
assertEquals(6, galadriel.getBlueprint().getAllyHomeSiteNumbers()[0]); // Change this to getAllyHomeSiteNumbers for allies
assertEquals(SitesBlock.FELLOWSHIP, galadriel.getBlueprint().getAllyHomeSiteBlock());
}
@Test
public void FellowshipActionPlaysNextFellowshipForestSite() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
var scn = GetScenario();
var galadriel = scn.GetFreepsCard("galadriel");
var forestSite = scn.GetFreepsSite("site2F");
scn.FreepsMoveCharToTable(galadriel);
var shadowSite2 = scn.GetShadowSite("site2");
scn.StartGame();
scn.FreepsDeclineOptionalTrigger();
assertTrue(scn.FreepsCardActionAvailable(galadriel));
assertEquals(Zone.ADVENTURE_DECK, shadowSite2.getZone());
assertEquals(Zone.ADVENTURE_DECK, forestSite.getZone());
assertEquals(null, scn.GetSite(2));
assertEquals(0, scn.GetWoundsOn(galadriel));
scn.FreepsUseCardAction(galadriel);
scn.FreepsChooseCardBPFromSelection(forestSite);
assertEquals(Zone.ADVENTURE_DECK, shadowSite2.getZone());
assertEquals(forestSite, scn.GetSite(2));
assertEquals(1, scn.GetWoundsOn(galadriel));
}
@Test
public void FellowshipActionPlaysNextTowersForestSite() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
var scn = GetScenario();
var galadriel = scn.GetFreepsCard("galadriel");
var forestSite = scn.GetFreepsSite("site2T");
scn.FreepsMoveCharToTable(galadriel);
var shadowSite2 = scn.GetShadowSite("site2");
scn.StartGame();
scn.FreepsDeclineOptionalTrigger();
assertTrue(scn.FreepsCardActionAvailable(galadriel));
assertEquals(Zone.ADVENTURE_DECK, shadowSite2.getZone());
assertEquals(Zone.ADVENTURE_DECK, forestSite.getZone());
assertEquals(null, scn.GetSite(2));
assertEquals(0, scn.GetWoundsOn(galadriel));
scn.FreepsUseCardAction(galadriel);
scn.FreepsChooseCardBPFromSelection(forestSite);
assertEquals(Zone.ADVENTURE_DECK, shadowSite2.getZone());
assertEquals(forestSite, scn.GetSite(2));
assertEquals(1, scn.GetWoundsOn(galadriel));
}
@Test
public void FellowshipActionPlaysNextKingForestSite() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
var scn = GetScenario();
var galadriel = scn.GetFreepsCard("galadriel");
var forestSite = scn.GetFreepsSite("site2K");
scn.FreepsMoveCharToTable(galadriel);
var shadowSite2 = scn.GetShadowSite("site2");
//cheating to ensure site 2 qualifies
scn.ApplyAdHocModifier(new KeywordModifier(null, Filters.name("West Road"), Keyword.FOREST));
scn.StartGame();
scn.FreepsDeclineOptionalTrigger();
assertTrue(scn.FreepsCardActionAvailable(galadriel));
assertEquals(Zone.ADVENTURE_DECK, shadowSite2.getZone());
assertEquals(Zone.ADVENTURE_DECK, forestSite.getZone());
assertEquals(null, scn.GetSite(2));
assertEquals(0, scn.GetWoundsOn(galadriel));
scn.FreepsUseCardAction(galadriel);
scn.FreepsChooseCardBPFromSelection(forestSite);
assertEquals(Zone.ADVENTURE_DECK, shadowSite2.getZone());
assertEquals(forestSite, scn.GetSite(2));
assertEquals(1, scn.GetWoundsOn(galadriel));
}
@Test
public void FellowshipActionPlaysNextShadowsForestSite() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
var scn = GetExpandedScenario();
var galadriel = scn.GetFreepsCard("galadriel");
var forestSite = scn.GetFreepsSite("siteX");
var site1 = scn.GetFreepsSite("site1");
scn.FreepsMoveCharToTable(galadriel);
var shadowSite2 = scn.GetShadowSite("siteX");
scn.FreepsChooseCardBPFromSelection(site1);
scn.StartGame();
scn.FreepsDeclineOptionalTrigger();
assertTrue(scn.FreepsCardActionAvailable(galadriel));
assertEquals(Zone.ADVENTURE_DECK, shadowSite2.getZone());
assertEquals(Zone.ADVENTURE_DECK, forestSite.getZone());
assertEquals(null, scn.GetSite(2));
assertEquals(0, scn.GetWoundsOn(galadriel));
scn.FreepsUseCardAction(galadriel);
scn.FreepsChooseCardBPFromSelection(forestSite);
assertEquals(Zone.ADVENTURE_DECK, shadowSite2.getZone());
assertEquals(forestSite, scn.GetSite(2));
assertEquals(1, scn.GetWoundsOn(galadriel));
}
@Test
public void HealAbilityTriggersOnElves() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
var scn = GetScenario();
var galadriel = scn.GetFreepsCard("galadriel");
var celeborn = scn.GetFreepsCard("celeborn");
var greenleaf = scn.GetFreepsCard("greenleaf");
scn.FreepsMoveCharToTable(galadriel, celeborn, greenleaf);
scn.AddWoundsToChar(galadriel, 1);
scn.AddWoundsToChar(celeborn, 1);
scn.AddWoundsToChar(greenleaf, 1);
scn.StartGame();
assertTrue(scn.FreepsHasOptionalTriggerAvailable());
scn.FreepsAcceptOptionalTrigger();
assertEquals(3, scn.GetFreepsCardChoiceCount()); //celeborn and legolas and galadriel
scn.FreepsChooseCard(celeborn);
assertEquals(0, scn.GetWoundsOn(celeborn));
assertEquals(1, scn.GetWoundsOn(greenleaf));
assertEquals(1, scn.GetWoundsOn(galadriel));
}
}

View File

@@ -2,10 +2,10 @@ package com.gempukku.lotro.cards.unofficial.pc.errata.set03;
import com.gempukku.lotro.cards.GenericCardTestHelper;
import com.gempukku.lotro.common.*;
import com.gempukku.lotro.filters.Filters;
import com.gempukku.lotro.game.CardNotFoundException;
import com.gempukku.lotro.game.PhysicalCardImpl;
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
import com.gempukku.lotro.logic.modifiers.MoveLimitModifier;
import com.gempukku.lotro.logic.modifiers.KeywordModifier;
import org.junit.Test;
import java.util.HashMap;
@@ -21,18 +21,58 @@ public class Card_03_017_ErrataTests
return new GenericCardTestHelper(
new HashMap<String, String>()
{{
put("card", "73_17");
// put other cards in here as needed for the test case
put("galadriel", "73_17");
put("celeborn", "1_34");
put("greenleaf", "1_50");
}},
new HashMap<String, String>() {{
put("site1", "1_319");
put("site2", "1_332");
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("site2F", "1_329"); //We are cheating here and putting a second site 2 in
put("site2T", "4_330"); //and a Towers site 2
put("site2K", "7_337"); //and a King site 2
put("siteX", "11_231"); //and a Shadows site
}},
GenericCardTestHelper.FellowshipSites,
GenericCardTestHelper.FOTRFrodo,
GenericCardTestHelper.FOTRRing
);
}
// Uncomment both @Test markers below once this is ready to be used
protected GenericCardTestHelper GetExpandedScenario() throws CardNotFoundException, DecisionResultInvalidException {
return new GenericCardTestHelper(
new HashMap<String, String>()
{{
put("galadriel", "73_17");
// put other cards in here as needed for the test case
}},
new HashMap<String, String>() {{
put("site1", "1_319");
put("site2", "1_332");
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("site2F", "1_329"); //We are cheating here and putting a second site 2 in
put("site2T", "4_330"); //and a Towers site 2
put("site2K", "7_337"); //and a King site 2
put("siteX", "11_231"); //and a Shadows site
}},
GenericCardTestHelper.FOTRFrodo,
GenericCardTestHelper.FOTRRing,
"expanded"
);
}
//@Test
@Test
public void GaladrielStatsAndKeywordsAreCorrect() throws DecisionResultInvalidException, CardNotFoundException {
/**
@@ -47,40 +87,204 @@ public class Card_03_017_ErrataTests
* Vitality: 3
* Site Number: 6
* Game Text: At the start of each of your turns, you may heal another Elf.
* <b>Fellowship:</b> Exert Galadriel twice to play the fellowship's next site if it is a forest (replacing opponent's site if necessary).
* Response: If the fellowship is about to move to an opponent's site during the Fellowship phase,
* exert Galadriel to replace that site with a forest site of the same site number from your adventure deck.
*/
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
var scn = GetScenario();
PhysicalCardImpl card = scn.GetFreepsCard("card");
var galadriel = scn.GetFreepsCard("galadriel");
assertTrue(card.getBlueprint().isUnique());
assertEquals(Side.FREE_PEOPLE, card.getBlueprint().getSide());
assertEquals(Culture.ELVEN, card.getBlueprint().getCulture());
assertEquals(CardType.ALLY, card.getBlueprint().getCardType());
assertEquals(Race.CREATURE, card.getBlueprint().getRace());
assertTrue(scn.HasKeyword(card, Keyword.SUPPORT_AREA));
assertEquals(3, card.getBlueprint().getTwilightCost());
assertEquals(3, card.getBlueprint().getStrength());
assertEquals(3, card.getBlueprint().getVitality());
//assertEquals(, card.getBlueprint().getResistance());
//assertEquals(Signet., card.getBlueprint().getSignet());
assertEquals(6, card.getBlueprint().getSiteNumber()); // Change this to getAllyHomeSiteNumbers for allies
assertTrue(galadriel.getBlueprint().isUnique());
assertEquals(Side.FREE_PEOPLE, galadriel.getBlueprint().getSide());
assertEquals(Culture.ELVEN, galadriel.getBlueprint().getCulture());
assertEquals(CardType.ALLY, galadriel.getBlueprint().getCardType());
assertEquals(Race.ELF, galadriel.getBlueprint().getRace());
assertEquals(3, galadriel.getBlueprint().getTwilightCost());
assertEquals(3, galadriel.getBlueprint().getStrength());
assertEquals(3, galadriel.getBlueprint().getVitality());
//assertEquals(, galadriel.getBlueprint().getResistance());
//assertEquals(Signet., galadriel.getBlueprint().getSignet());
assertEquals(6, galadriel.getBlueprint().getAllyHomeSiteNumbers()[0]); // Change this to getAllyHomeSiteNumbers for allies
assertEquals(SitesBlock.FELLOWSHIP, galadriel.getBlueprint().getAllyHomeSiteBlock());
}
//@Test
public void GaladrielTest1() throws DecisionResultInvalidException, CardNotFoundException {
@Test
public void MovingToOpponentsSiteWithMatchingFellowshipForestSiteTriggers() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
var scn = GetScenario();
PhysicalCardImpl card = scn.GetFreepsCard("card");
scn.FreepsMoveCardToHand(card);
var galadriel = scn.GetFreepsCard("galadriel");
var forestSite = scn.GetFreepsSite("site2F");
scn.FreepsMoveCharToTable(galadriel);
var shadowSite2 = scn.GetShadowSite("site2");
scn.StartGame();
scn.FreepsPlayCard(card);
assertEquals(3, scn.GetTwilight());
scn.FreepsPassCurrentPhaseAction();
//We have to specify which site here since we cheated and included a second site 2
scn.ShadowChooseCardBPFromSelection(shadowSite2);
assertEquals(shadowSite2, scn.GetCurrentSite());
assertTrue(scn.FreepsHasOptionalTriggerAvailable());
assertEquals(0, scn.GetWoundsOn(galadriel));
scn.FreepsAcceptOptionalTrigger();
scn.FreepsChooseCardBPFromSelection(forestSite);
assertEquals(forestSite.getBlueprintId(), scn.GetCurrentSite().getBlueprintId());
assertEquals(1, scn.GetWoundsOn(galadriel));
}
@Test
public void MovingToOpponentsSiteWithMatchingTowersForestSiteTriggers() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
var scn = GetScenario();
var galadriel = scn.GetFreepsCard("galadriel");
var forestSite = scn.GetFreepsSite("site2T");
scn.FreepsMoveCharToTable(galadriel);
var shadowSite2 = scn.GetShadowSite("site2");
scn.StartGame();
scn.FreepsPassCurrentPhaseAction();
//We have to specify which site here since we cheated and included a second site 2
scn.ShadowChooseCardBPFromSelection(shadowSite2);
assertEquals(shadowSite2, scn.GetCurrentSite());
assertTrue(scn.FreepsHasOptionalTriggerAvailable());
assertEquals(0, scn.GetWoundsOn(galadriel));
scn.FreepsAcceptOptionalTrigger();
scn.FreepsChooseCardBPFromSelection(forestSite);
assertEquals(forestSite.getBlueprintId(), scn.GetCurrentSite().getBlueprintId());
assertEquals(1, scn.GetWoundsOn(galadriel));
}
@Test
public void MovingToOpponentsSiteWithMatchingKingForestSiteTriggers() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
var scn = GetScenario();
var galadriel = scn.GetFreepsCard("galadriel");
var forestSite = scn.GetFreepsSite("site2K");
scn.FreepsMoveCharToTable(galadriel);
var shadowSite2 = scn.GetShadowSite("site2");
//cheating to ensure site 2 qualifies
scn.ApplyAdHocModifier(new KeywordModifier(null, Filters.name("West Road"), Keyword.FOREST));
scn.StartGame();
scn.FreepsPassCurrentPhaseAction();
//We have to specify which site here since we cheated and included a second site 2
scn.ShadowChooseCardBPFromSelection(shadowSite2);
assertEquals(shadowSite2, scn.GetCurrentSite());
assertTrue(scn.FreepsHasOptionalTriggerAvailable());
assertEquals(0, scn.GetWoundsOn(galadriel));
scn.FreepsAcceptOptionalTrigger();
scn.FreepsChooseCardBPFromSelection(forestSite);
assertEquals(forestSite.getBlueprintId(), scn.GetCurrentSite().getBlueprintId());
assertEquals(1, scn.GetWoundsOn(galadriel));
}
@Test
public void MovingToOpponentsShadowsPathSiteTriggersButCannotBePlayed() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
var scn = GetExpandedScenario();
var galadriel = scn.GetFreepsCard("galadriel");
var forestSite = scn.GetFreepsSite("site2K");
var freepsSiteX = scn.GetFreepsSite("siteX");
scn.FreepsMoveCharToTable(galadriel);
var shadowSite2 = scn.GetShadowSite("siteX");
scn.FreepsChooseCardBPFromSelection(freepsSiteX);
scn.StartGame();
scn.FreepsPassCurrentPhaseAction();
//We have to specify which site here since we cheated and included a second site 2
scn.ShadowChooseCardBPFromSelection(shadowSite2);
assertEquals(shadowSite2, scn.GetCurrentSite());
assertEquals(0, scn.GetWoundsOn(galadriel));
assertTrue(scn.FreepsHasOptionalTriggerAvailable());
scn.FreepsAcceptOptionalTrigger();
//The cheated Towers and Fellowship site 2, but not the Shadows variant (as that doesn't have a site number until played)
assertEquals(2, scn.GetFreepsCardChoiceCount());
assertEquals(1, scn.GetWoundsOn(galadriel));
}
@Test
public void ReplacedSiteDoesNotTriggerBeforeReplacement() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
var scn = GetScenario();
var frodo = scn.GetRingBearer();
var galadriel = scn.GetFreepsCard("galadriel");
var forestSite = scn.GetFreepsSite("site2F");
scn.FreepsMoveCharToTable(galadriel);
var shadowSite2 = scn.GetShadowSite("site2");
scn.StartGame();
assertEquals(0, scn.GetWoundsOn(frodo));
scn.FreepsPassCurrentPhaseAction();
//We have to specify which site here since we cheated and included a second site 2
scn.ShadowChooseCardBPFromSelection(shadowSite2);
scn.FreepsAcceptOptionalTrigger();
scn.FreepsChooseCardBPFromSelection(forestSite);
//Midgwater Moors as the replaced site 2 would have exerted all hobbits upon arrival. If everything
//worked out timing-wise, this should never have been evaluated.
assertEquals(0, scn.GetWoundsOn(frodo));
}
@Test
public void HealAbilityDoesNotTriggerOnSelf() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
var scn = GetScenario();
var galadriel = scn.GetFreepsCard("galadriel");
scn.FreepsMoveCharToTable(galadriel);
scn.AddWoundsToChar(galadriel, 1);
scn.StartGame();
assertFalse(scn.FreepsHasOptionalTriggerAvailable());
}
@Test
public void HealAbilityTriggersOnOtherElves() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
var scn = GetScenario();
var galadriel = scn.GetFreepsCard("galadriel");
var celeborn = scn.GetFreepsCard("celeborn");
var greenleaf = scn.GetFreepsCard("greenleaf");
scn.FreepsMoveCharToTable(galadriel, celeborn, greenleaf);
scn.AddWoundsToChar(galadriel, 1);
scn.AddWoundsToChar(celeborn, 1);
scn.AddWoundsToChar(greenleaf, 1);
scn.StartGame();
assertTrue(scn.FreepsHasOptionalTriggerAvailable());
scn.FreepsAcceptOptionalTrigger();
assertEquals(2, scn.GetFreepsCardChoiceCount()); //celeborn and legolas, but not galadriel
scn.FreepsChooseCard(celeborn);
assertEquals(0, scn.GetWoundsOn(celeborn));
assertEquals(1, scn.GetWoundsOn(greenleaf));
}
}