FInally hunted down the issue with Halls of My Home not permitting rearranging of enemy deck

This commit is contained in:
Christian 'ketura' McCarty
2022-07-26 04:48:16 -05:00
parent 84aa5fd8f4
commit 967e3c790c
21 changed files with 362 additions and 55 deletions

View File

@@ -409,6 +409,7 @@
"effect": [
{
"type": "choice",
"memorize": "revealChoice",
"texts": [
"Reveal top 3 cards of your deck.",
"Reveal top 3 cards of your opponent's deck."
@@ -417,34 +418,77 @@
{
"type": "revealTopCardsOfDrawDeck",
"count": 3,
"memorize": "revealedCards",
"memorize": "revealedFreepsCards",
"deck": "you"
},
{
"type": "revealTopCardsOfDrawDeck",
"count": 3,
"memorize": "revealedCards",
"memorize": "revealedShadowCards",
"deck": "shadowPlayer"
}
]
},
{
"type": "optional",
"text": "Would you like to discard 1 Shadow card revealed?",
"effect": {
"type": "discardCardsFromDrawDeck",
"filter": "choose(side(shadow),memory(revealedCards))"
}
"type": "conditional",
"condition": {
"type": "memoryLike",
"memory": "revealChoice",
"value": "your deck"
},
"effect": [
{
"type": "optional",
"text": "Would you like to discard 1 Shadow card revealed?",
"effect": {
"type": "discardCardsFromDrawDeck",
"filter": "choose(side(shadow),memory(revealedFreepsCards))"
}
},
{
"type": "reorderTopCardsOfDrawDeck",
"player": "you",
"deck": "you",
"count": {
"type": "forEachMatchingInMemory",
"memory": "revealedFreepsCards",
"filter": "zone(deck)"
}
}
]
},
{
"type": "reorderTopCardsOfDrawDeck",
"count": {
"type": "forEachMatchingInMemory",
"memory": "revealedCards",
"filter": "zone(deck)"
}
}
"type": "conditional",
"condition": {
"type": "memoryLike",
"memory": "revealChoice",
"value": "your opponent's deck"
},
"effect": [
{
"type": "optional",
"text": "Would you like to discard 1 Shadow card revealed?",
"effect": {
"type": "discardCardsFromDrawDeck",
"deck": "shadow",
"filter": "choose(side(shadow),memory(revealedShadowCards))"
}
},
{
"type": "reorderTopCardsOfDrawDeck",
"player": "you",
"deck": "shadow",
"count": {
"type": "forEachMatchingInMemory",
"memory": "revealedShadowCards",
"filter": "zone(deck)"
}
}
]
},
]
}
},

View File

@@ -19,11 +19,12 @@ import java.util.List;
public class Choice implements EffectAppenderProducer {
@Override
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(effectObject, "player", "effects", "texts");
FieldUtils.validateAllowedFields(effectObject, "player", "effects", "texts", "memorize");
final String player = FieldUtils.getString(effectObject.get("player"), "player", "you");
final JSONObject[] effectArray = FieldUtils.getObjectArray(effectObject.get("effects"), "effects");
final String[] textArray = FieldUtils.getStringArray(effectObject.get("texts"), "texts");
final String memorize = FieldUtils.getString(effectObject.get("memorize"), "memorize", "_temp");
if (effectArray.length != textArray.length)
throw new InvalidCardDefinitionException("Number of texts and effects does not match in choice effect");
@@ -51,12 +52,15 @@ public class Choice implements EffectAppenderProducer {
textIndex++;
}
if (playableEffectAppenders.size() == 0)
if (playableEffectAppenders.size() == 0) {
actionContext.setValueToMemory(memorize, "");
return null;
}
if (playableEffectAppenders.size() == 1) {
SubAction subAction = new SubAction(action);
playableEffectAppenders.get(0).appendEffect(cost, subAction, delegateActionContext);
actionContext.setValueToMemory(memorize, textArray[0]);
return new StackActionEffect(subAction);
}
@@ -67,6 +71,7 @@ public class Choice implements EffectAppenderProducer {
@Override
protected void validDecisionMade(int index, String result) {
playableEffectAppenders.get(index).appendEffect(cost, subAction, delegateActionContext);
actionContext.setValueToMemory(memorize, result);
}
}));
return new StackActionEffect(subAction);

View File

@@ -1,13 +1,11 @@
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.*;
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.CardResolver;
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.PlayerResolver;
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver;
import com.gempukku.lotro.game.PhysicalCard;
import com.gempukku.lotro.logic.actions.CostToEffectAction;
@@ -22,17 +20,19 @@ import java.util.List;
public class DiscardCardsFromDrawDeck implements EffectAppenderProducer {
@Override
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(effectObject, "count", "filter", "memorize");
FieldUtils.validateAllowedFields(effectObject, "count", "filter", "memorize", "player", "deck");
final String filter = FieldUtils.getString(effectObject.get("filter"), "filter", "choose(any)");
final String memorize = FieldUtils.getString(effectObject.get("memorize"), "memorize", "_temp");
final String player = FieldUtils.getString(effectObject.get("player"), "player", "you");
final String deck = FieldUtils.getString(effectObject.get("deck"), "deck", "you");
final ValueSource countSource = ValueResolver.resolveEvaluator(effectObject.get("count"), 1, environment);
MultiEffectAppender result = new MultiEffectAppender();
result.addEffectAppender(
CardResolver.resolveCardsInDeck(filter, null, countSource, memorize, "you", "Choose cards to discard", environment));
CardResolver.resolveCardsInDeck(filter, null, countSource, memorize, player, deck, "Choose cards to discard", environment));
result.addEffectAppender(
new DelayedAppender() {
@Override

View File

@@ -47,7 +47,7 @@ public class PlayCardFromDrawDeck implements EffectAppenderProducer {
}
return Filters.playable(actionContext.getGame(), costModifier);
},
new ConstantEvaluator(1), memorize, "you", "Choose card to play", environment));
new ConstantEvaluator(1), memorize, "you", "you", "Choose card to play", environment));
result.addEffectAppender(
new DelayedAppender() {
@Override

View File

@@ -32,7 +32,7 @@ public class PutCardsFromDeckIntoHand implements EffectAppenderProducer {
MultiEffectAppender result = new MultiEffectAppender();
result.addEffectAppender(
CardResolver.resolveCardsInDeck(filter, null, valueSource, "_temp", "you", "Choose cards from deck", environment));
CardResolver.resolveCardsInDeck(filter, valueSource, "_temp", "you", "Choose cards from deck", environment));
result.addEffectAppender(
new DelayedAppender() {
@Override

View File

@@ -33,7 +33,7 @@ public class PutCardsFromDeckOnBottomOfDeck implements EffectAppenderProducer {
MultiEffectAppender result = new MultiEffectAppender();
result.addEffectAppender(
CardResolver.resolveCardsInDeck(filter, null, valueSource, "_temp", "you", "Choose cards from deck", environment));
CardResolver.resolveCardsInDeck(filter, valueSource, "_temp", "you", "Choose cards from deck", environment));
result.addEffectAppender(
new DelayedAppender() {
@Override

View File

@@ -34,7 +34,7 @@ public class PutCardsFromDeckOnTopOfDeck implements EffectAppenderProducer {
MultiEffectAppender result = new MultiEffectAppender();
result.addEffectAppender(
CardResolver.resolveCardsInDeck(filter, null, valueSource, "_temp", "you", "Choose cards from deck", environment));
CardResolver.resolveCardsInDeck(filter, valueSource, "_temp", "you", "Choose cards from deck", environment));
result.addEffectAppender(
new DelayedAppender() {
@Override
@@ -42,7 +42,7 @@ public class PutCardsFromDeckOnTopOfDeck implements EffectAppenderProducer {
final Collection<? extends PhysicalCard> cards = actionContext.getCardsFromMemory("_temp");
List<Effect> result = new LinkedList<>();
for (PhysicalCard card : cards) {
result.add(new PutCardFromDeckOnTopOfDeckEffect(action.getActionSource(), card));
result.add(new PutCardFromDeckOnTopOfDeckEffect(action.getActionSource().getOwner(), card));
}
return result;

View File

@@ -1,12 +1,10 @@
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.*;
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.PlayerResolver;
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver;
import com.gempukku.lotro.logic.actions.CostToEffectAction;
import com.gempukku.lotro.logic.effects.ReorderTopCardsOfDeckEffect;
@@ -17,20 +15,25 @@ import org.json.simple.JSONObject;
public class ReorderTopCardsOfDrawDeck implements EffectAppenderProducer {
@Override
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(effectObject, "count");
FieldUtils.validateAllowedFields(effectObject, "count", "player", "deck");
final ValueSource valueSource = ValueResolver.resolveEvaluator(effectObject.get("count"), 1, environment);
final String player = FieldUtils.getString(effectObject.get("player"), "player", "you");
final String deck = FieldUtils.getString(effectObject.get("deck"), "deck", "you");
final PlayerSource playerSource = PlayerResolver.resolvePlayer(player, environment);
final PlayerSource deckSource = PlayerResolver.resolvePlayer(deck, environment);
return new DelayedAppender() {
@Override
public boolean isPlayableInFull(ActionContext actionContext) {
final Evaluator count = valueSource.getEvaluator(actionContext);
return actionContext.getGame().getGameState().getDeck(actionContext.getPerformingPlayer()).size() >= count.evaluateExpression(actionContext.getGame(), null);
return actionContext.getGame().getGameState().getDeck(deckSource.getPlayer(actionContext)).size() >= count.evaluateExpression(actionContext.getGame(), null);
}
@Override
protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) {
final int count = valueSource.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
return new ReorderTopCardsOfDeckEffect(action, actionContext.getPerformingPlayer(), count);
return new ReorderTopCardsOfDeckEffect(action, playerSource.getPlayer(actionContext), deckSource.getPlayer(actionContext), count);
}
};
}

View File

@@ -35,7 +35,7 @@ public class StackCardsFromDeck implements EffectAppenderProducer {
result.addEffectAppender(
CardResolver.resolveCard(where, "_temp1", "you", "Choose card to stack on", environment));
result.addEffectAppender(
CardResolver.resolveCardsInDeck(filter, null, valueSource, "_temp2", "you", "Choose cards to stack", environment));
CardResolver.resolveCardsInDeck(filter, valueSource, "_temp2", "you", "Choose cards to stack", environment));
result.addEffectAppender(
new DelayedAppender() {
@Override

View File

@@ -185,14 +185,16 @@ public class CardResolver {
}
public static EffectAppender resolveCardsInDeck(String type, ValueSource countSource, String memory, String choicePlayer, String choiceText, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
return resolveCardsInDeck(type, null, countSource, memory, choicePlayer, choiceText, environment);
return resolveCardsInDeck(type, null, countSource, memory, choicePlayer, choicePlayer, choiceText, environment);
}
public static EffectAppender resolveCardsInDeck(String type, FilterableSource choiceFilter, ValueSource countSource, String memory, String choicePlayer, String choiceText, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
public static EffectAppender resolveCardsInDeck(String type, FilterableSource choiceFilter, ValueSource countSource, String memory, String choicePlayer, String targetDeck, String choiceText, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
final PlayerSource playerSource = PlayerResolver.resolvePlayer(choicePlayer, environment);
final PlayerSource deckSource = PlayerResolver.resolvePlayer(targetDeck, environment);
Function<ActionContext, Iterable<? extends PhysicalCard>> cardSource = actionContext -> {
String playerId = playerSource.getPlayer(actionContext);
return actionContext.getGame().getGameState().getDeck(playerId);
String deckId = deckSource.getPlayer(actionContext);
return actionContext.getGame().getGameState().getDeck(deckId);
};
if (type.startsWith("memory(") && type.endsWith(")")) {
@@ -202,7 +204,8 @@ public class CardResolver {
} else if (type.startsWith("choose(") && type.endsWith(")")) {
ChoiceEffectSource effectSource = (possibleCards, action, actionContext, min, max) -> {
String choicePlayerId = playerSource.getPlayer(actionContext);
return new ChooseCardsFromDeckEffect(choicePlayerId, min, max, Filters.in(possibleCards)) {
String targetDeckId = deckSource.getPlayer(actionContext);
return new ChooseCardsFromDeckEffect(choicePlayerId, targetDeckId, min, max, Filters.in(possibleCards)) {
@Override
protected void cardsSelected(LotroGame game, Collection<PhysicalCard> cards) {
actionContext.setCardMemory(memory, cards);

View File

@@ -0,0 +1,22 @@
package com.gempukku.lotro.cards.build.field.effect.requirement;
import com.gempukku.lotro.cards.build.CardGenerationEnvironment;
import com.gempukku.lotro.cards.build.InvalidCardDefinitionException;
import com.gempukku.lotro.cards.build.Requirement;
import com.gempukku.lotro.cards.build.field.FieldUtils;
import org.json.simple.JSONObject;
public class MemoryLike implements RequirementProducer {
@Override
public Requirement getPlayRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(object, "memory", "value");
final String memory = FieldUtils.getString(object.get("memory"), "memory");
final String value = FieldUtils.getString(object.get("value"), "value");
return (actionContext) -> {
String valueFromMemory = actionContext.getValueFromMemory(memory);
return valueFromMemory != null && valueFromMemory.contains(value);
};
}
}

View File

@@ -36,6 +36,7 @@ public class RequirementFactory {
requirementProducers.put("isside", new IsSideRequirementProducer());
requirementProducers.put("location", new Location());
requirementProducers.put("memoryis", new MemoryIs());
requirementProducers.put("memorylike", new MemoryLike());
requirementProducers.put("memorymatches", new MemoryMatches());
requirementProducers.put("movecountminimum", new MoveCountMinimum());
requirementProducers.put("perphaselimit", new PerPhaseLimit());

View File

@@ -120,7 +120,7 @@ public class GameCommunicationChannel implements GameStateListener, LongPollable
public void cardsRemoved(String playerPerforming, Collection<PhysicalCard> cards) {
Set<PhysicalCard> removedCardsVisibleByPlayer = new HashSet<PhysicalCard>();
for (PhysicalCard card : cards) {
if (card.getZone().isPublic() || (card.getZone().isVisibleByOwner() && card.getOwner().equals(_self)))
if (card.getZone().isPublic() || (card.getZone().isVisibleByOwner() && card.getOwner().equals(_self) || playerPerforming != card.getOwner()))
removedCardsVisibleByPlayer.add(card);
}
if (removedCardsVisibleByPlayer.size() > 0)

View File

@@ -10,12 +10,12 @@ import com.gempukku.lotro.logic.timing.AbstractEffect;
import java.util.Collections;
public class PutCardFromDeckOnTopOfDeckEffect extends AbstractEffect {
private PhysicalCard _source;
private String _performingPlayer;
private PhysicalCard _physicalCard;
public PutCardFromDeckOnTopOfDeckEffect(PhysicalCard source, PhysicalCard physicalCard) {
public PutCardFromDeckOnTopOfDeckEffect(String player, PhysicalCard physicalCard) {
_physicalCard = physicalCard;
_source = source;
_performingPlayer = player;
}
@Override
@@ -37,7 +37,7 @@ public class PutCardFromDeckOnTopOfDeckEffect extends AbstractEffect {
protected FullEffectResult playEffectReturningResult(LotroGame game) {
if (isPlayableInFull(game)) {
GameState gameState = game.getGameState();
gameState.removeCardsFromZone(_source.getOwner(), Collections.singleton(_physicalCard));
gameState.removeCardsFromZone(_performingPlayer, Collections.singleton(_physicalCard));
gameState.putCardOnTopOfDeck(_physicalCard);
return new FullEffectResult(true);
}

View File

@@ -61,7 +61,7 @@ public class PutCardsFromDeckOnTopOfDrawDeckEffect extends AbstractSubActionEffe
protected void cardsSelected(LotroGame game, Collection<PhysicalCard> selectedCards) {
for (PhysicalCard selectedCard : selectedCards) {
_subAction.appendEffect(
new PutCardFromDeckOnTopOfDeckEffect(_source, selectedCard));
new PutCardFromDeckOnTopOfDeckEffect(_source.getOwner(), selectedCard));
_remainingCards.remove(selectedCard);
if (_remainingCards.size() > 0)
_subAction.appendEffect(

View File

@@ -15,11 +15,20 @@ import java.util.Set;
public class ReorderTopCardsOfDeckEffect extends AbstractSubActionEffect {
private Action _action;
private String _playerId;
private String _deckId;
private int _count;
public ReorderTopCardsOfDeckEffect(Action action, String playerId, int count) {
_action = action;
_playerId = playerId;
_deckId = playerId;
_count = count;
}
public ReorderTopCardsOfDeckEffect(Action action, String playerId, String deckId, int count) {
_action = action;
_playerId = playerId;
_deckId = deckId;
_count = count;
}
@@ -35,12 +44,12 @@ public class ReorderTopCardsOfDeckEffect extends AbstractSubActionEffect {
@Override
public boolean isPlayableInFull(LotroGame game) {
return game.getGameState().getDeck(_playerId).size() >= _count;
return game.getGameState().getDeck(_deckId).size() >= _count;
}
@Override
public void playEffect(LotroGame game) {
final List<? extends PhysicalCard> deck = game.getGameState().getDeck(_playerId);
final List<? extends PhysicalCard> deck = game.getGameState().getDeck(_deckId);
int count = Math.min(deck.size(), _count);
Set<PhysicalCard> cards = new HashSet<PhysicalCard>(deck.subList(0, count));
@@ -57,7 +66,7 @@ public class ReorderTopCardsOfDeckEffect extends AbstractSubActionEffect {
private CostToEffectAction _subAction;
public ChooseAndPutNextCardFromDeckOnTopOfDeck(CostToEffectAction subAction, Collection<PhysicalCard> remainingCards) {
super(_playerId, "Choose a card to put on top of your deck", remainingCards, 1, 1);
super(_playerId, "Choose a card to put on top of the deck", remainingCards, 1, 1);
_subAction = subAction;
_remainingCards = remainingCards;
}
@@ -66,7 +75,7 @@ public class ReorderTopCardsOfDeckEffect extends AbstractSubActionEffect {
protected void cardsSelected(LotroGame game, Collection<PhysicalCard> selectedCards) {
for (PhysicalCard selectedCard : selectedCards) {
_subAction.appendEffect(
new PutCardFromDeckOnTopOfDeckEffect(_action.getActionSource(), selectedCard));
new PutCardFromDeckOnTopOfDeckEffect(_playerId, selectedCard));
_remainingCards.remove(selectedCard);
if (_remainingCards.size() > 0)
_subAction.appendEffect(

View File

@@ -13,7 +13,12 @@ public class ChooseAndPutCardFromDeckIntoDiscardEffect extends ChooseCardsFromDe
private Action _action;
public ChooseAndPutCardFromDeckIntoDiscardEffect(Action action, String playerId, int minimum, int maximum, Filterable... filters) {
super(playerId, minimum, maximum, filters);
super(playerId, playerId, minimum, maximum, filters);
_action = action;
}
public ChooseAndPutCardFromDeckIntoDiscardEffect(Action action, String playerId, String deckId, int minimum, int maximum, Filterable... filters) {
super(playerId, deckId, minimum, maximum, filters);
_action = action;
}

View File

@@ -13,7 +13,12 @@ public class ChooseAndPutCardFromDeckIntoHandEffect extends ChooseCardsFromDeckE
private Action _action;
public ChooseAndPutCardFromDeckIntoHandEffect(Action action, String playerId, int minimum, int maximum, Filterable... filters) {
super(playerId, minimum, maximum, filters);
super(playerId, playerId, minimum, maximum, filters);
_action = action;
}
public ChooseAndPutCardFromDeckIntoHandEffect(Action action, String playerId, String deckId, int minimum, int maximum, Filterable... filters) {
super(playerId, deckId, minimum, maximum, filters);
_action = action;
}

View File

@@ -15,12 +15,22 @@ import java.util.LinkedList;
public abstract class ChooseCardsFromDeckEffect extends AbstractEffect {
private String _playerId;
private String _deckId;
private int _minimum;
private int _maximum;
private Filter _filter;
public ChooseCardsFromDeckEffect(String playerId, int minimum, int maximum, Filterable... filters) {
_playerId = playerId;
_deckId = playerId;
_minimum = minimum;
_maximum = maximum;
_filter = Filters.and(filters);
}
public ChooseCardsFromDeckEffect(String playerId, String deckId, int minimum, int maximum, Filterable... filters) {
_playerId = playerId;
_deckId = deckId;
_minimum = minimum;
_maximum = maximum;
_filter = Filters.and(filters);
@@ -38,13 +48,13 @@ public abstract class ChooseCardsFromDeckEffect extends AbstractEffect {
@Override
public boolean isPlayableInFull(LotroGame game) {
Collection<PhysicalCard> cards = Filters.filter(game.getGameState().getDeck(_playerId), game, _filter);
Collection<PhysicalCard> cards = Filters.filter(game.getGameState().getDeck(_deckId), game, _filter);
return cards.size() >= _minimum;
}
@Override
protected FullEffectResult playEffectReturningResult(final LotroGame game) {
Collection<PhysicalCard> cards = Filters.filter(game.getGameState().getDeck(_playerId), game, _filter);
Collection<PhysicalCard> cards = Filters.filter(game.getGameState().getDeck(_deckId), game, _filter);
boolean success = cards.size() >= _minimum;

View File

@@ -770,4 +770,10 @@ public class GenericCardTestHelper extends AbstractAtTest {
}
});
}
public void AcknowledgeReveal() throws DecisionResultInvalidException
{
playerDecided(P1, "");
playerDecided(P2, "");
}
}

View File

@@ -0,0 +1,194 @@
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 java.util.List;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class Card1_018Tests
{
protected GenericCardTestHelper GetScenario() throws CardNotFoundException, DecisionResultInvalidException {
return new GenericCardTestHelper(
new HashMap<String, String>()
{{
put("halls", "1_18");
put("gimli", "1_13");
put("scard1", "1_178");
put("scard2", "1_21");
put("scard3", "1_203");
put("fcard1", "2_75");
put("fcard2", "2_51");
put("fcard3", "2_96");
}}
);
}
@Test
public void HallsStatsAndKeywordsAreCorrect() throws DecisionResultInvalidException, CardNotFoundException {
/**
* Set: V1
* Title: *A Shadow of the Past
* Side: Free Peoples
* Culture: sauron
* Twilight Cost: 1
* Type: condition
* Subtype: Support Area
* Game Text: While you can spot 4 burdens, each [sauron] Orc is <b>fierce</b>.
* While you can spot 6 burdens, each [Sauron] Orc is damage +1.
* Discard this condition at the start of the regroup phase.
*/
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
PhysicalCardImpl halls = scn.GetFreepsCard("halls");
assertFalse(halls.getBlueprint().isUnique());
assertEquals(Side.FREE_PEOPLE, halls.getBlueprint().getSide());
assertEquals(Culture.DWARVEN, halls.getBlueprint().getCulture());
assertEquals(CardType.EVENT, halls.getBlueprint().getCardType());
//assertEquals(Race.CREATURE, halls.getBlueprint().getRace());
assertTrue(scn.HasKeyword(halls, Keyword.FELLOWSHIP)); // test for keywords as needed
assertEquals(1, halls.getBlueprint().getTwilightCost());
//assertEquals(, halls.getBlueprint().getStrength());
//assertEquals(, halls.getBlueprint().getVitality());
//assertEquals(, halls.getBlueprint().getResistance());
//assertEquals(Signet., halls.getBlueprint().getSignet());
//assertEquals(, halls.getBlueprint().getSiteNumber()); // Change this to getAllyHomeSiteNumbers for allies
}
@Test
public void HallsExertsToRevealDiscardAndRearrangeFreepsDeck() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
PhysicalCardImpl gimli = scn.GetFreepsCard("gimli");
PhysicalCardImpl halls = scn.GetFreepsCard("halls");
scn.FreepsMoveCharToTable(gimli);
scn.FreepsMoveCardToHand(halls);
PhysicalCardImpl fcard1 = scn.GetFreepsCard("fcard1");
PhysicalCardImpl fcard2 = scn.GetFreepsCard("fcard2");
PhysicalCardImpl fcard3 = scn.GetFreepsCard("fcard3");
scn.FreepsMoveCardsToTopOfDeck(fcard3, fcard2, fcard1);
PhysicalCardImpl scard1 = scn.GetShadowCard("scard1");
PhysicalCardImpl scard2 = scn.GetShadowCard("scard2");
PhysicalCardImpl scard3 = scn.GetShadowCard("scard3");
scn.ShadowMoveCardsToTopOfDeck(scard3, scard2, scard1);
scn.StartGame();
assertTrue(scn.FreepsCardPlayAvailable(halls));
assertEquals(0, scn.GetWoundsOn(gimli));
scn.FreepsPlayCard(halls);
assertEquals(1, scn.GetWoundsOn(gimli));
assertTrue(scn.FreepsDecisionAvailable("Choose action to perform"));
assertEquals(2, scn.FreepsGetMultipleChoices().size());
scn.FreepsChooseMultipleChoiceOption("your deck");
List<String> choices = scn.FreepsGetADParamAsList("blueprintId");
assertTrue(choices.contains(fcard1.getBlueprintId()));
assertTrue(choices.contains(fcard2.getBlueprintId()));
assertTrue(choices.contains(fcard3.getBlueprintId()));
scn.AcknowledgeReveal();
assertTrue(scn.FreepsDecisionAvailable("Would you like to discard"));
scn.FreepsChooseYes();
assertTrue(scn.FreepsDecisionAvailable("Choose card from deck"));
choices = scn.FreepsGetADParamAsList("blueprintId");
assertTrue(choices.contains(fcard1.getBlueprintId()));
assertTrue(choices.contains(fcard2.getBlueprintId()));
assertFalse(choices.contains(fcard3.getBlueprintId())); // freeps card, shouldn't be able to be discarded
scn.FreepsChooseCardBPFromSelection(fcard1);
assertEquals(Zone.DISCARD, fcard1.getZone()); //discarded shadow card
choices = scn.FreepsGetADParamAsList("blueprintId");
assertFalse(choices.contains(fcard1.getBlueprintId()));
assertTrue(choices.contains(fcard2.getBlueprintId()));
assertTrue(choices.contains(fcard3.getBlueprintId()));
scn.FreepsChooseCardBPFromSelection(fcard3);
assertEquals(fcard2.getBlueprintId(), scn.GetFreepsTopOfDeck().getBlueprintId());
}
@Test
public void HallsExertsToRevealDiscardAndRearrangeShadowDeck() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
PhysicalCardImpl gimli = scn.GetFreepsCard("gimli");
PhysicalCardImpl halls = scn.GetFreepsCard("halls");
scn.FreepsMoveCharToTable(gimli);
scn.FreepsMoveCardToHand(halls);
PhysicalCardImpl fcard1 = scn.GetFreepsCard("fcard1");
PhysicalCardImpl fcard2 = scn.GetFreepsCard("fcard2");
PhysicalCardImpl fcard3 = scn.GetFreepsCard("fcard3");
scn.FreepsMoveCardsToTopOfDeck(fcard3, fcard2, fcard1);
PhysicalCardImpl scard1 = scn.GetShadowCard("scard1");
PhysicalCardImpl scard2 = scn.GetShadowCard("scard2");
PhysicalCardImpl scard3 = scn.GetShadowCard("scard3");
scn.ShadowMoveCardsToTopOfDeck(scard3, scard2, scard1);
scn.StartGame();
assertTrue(scn.FreepsCardPlayAvailable(halls));
assertEquals(0, scn.GetWoundsOn(gimli));
scn.FreepsPlayCard(halls);
assertEquals(1, scn.GetWoundsOn(gimli));
assertTrue(scn.FreepsDecisionAvailable("Choose action to perform"));
assertEquals(2, scn.FreepsGetMultipleChoices().size());
scn.FreepsChooseMultipleChoiceOption("your opponent's deck");
List<String> choices = scn.FreepsGetADParamAsList("blueprintId");
assertTrue(choices.contains(scard1.getBlueprintId()));
assertTrue(choices.contains(scard2.getBlueprintId()));
assertTrue(choices.contains(scard3.getBlueprintId()));
scn.AcknowledgeReveal();
assertTrue(scn.FreepsDecisionAvailable("Would you like to discard"));
scn.FreepsChooseYes();
assertTrue(scn.FreepsDecisionAvailable("Choose card from deck"));
choices = scn.FreepsGetADParamAsList("blueprintId");
assertTrue(choices.contains(scard1.getBlueprintId()));
assertTrue(choices.contains(scard3.getBlueprintId()));
assertFalse(choices.contains(scard2.getBlueprintId())); // freeps card, shouldn't be able to be discarded
scn.FreepsChooseCardBPFromSelection(scard1);
assertEquals(Zone.DISCARD, scard1.getZone()); //discarded shadow card
choices = scn.FreepsGetADParamAsList("blueprintId");
assertFalse(choices.contains(scard1.getBlueprintId()));
assertTrue(choices.contains(scard2.getBlueprintId()));
assertTrue(choices.contains(scard3.getBlueprintId()));
scn.FreepsChooseCardBPFromSelection(scard2);
assertEquals(scard3.getBlueprintId(), scn.GetShadowTopOfDeck().getBlueprintId());
}
}