Merge branch 'master' into update

This commit is contained in:
Christian 'ketura' McCarty
2022-08-04 10:32:04 -05:00
18 changed files with 251 additions and 84 deletions

View File

@@ -0,0 +1,24 @@
{
"11_235": {
"title": "Dammed Gate-stream",
"type": "site",
"block": "Shadows",
"cost": 3,
"keyword": "Marsh",
"direction": "right",
"effects": {
"type": "trigger",
"trigger": {
"type": "startOfPhase",
"phase": "fellowship"
},
"optional": true,
"effect": {
"type": "playCardFromDrawDeck",
"filter": "choose(culture(gollum),side(free peoples))"
}
}
},
}

View File

@@ -1,12 +1,18 @@
<pre style="font-size:80%">
<b>Most recent update</b>
<b>2022 August 04</b>
- New players now have all of the library decks in the main hall to use for matches, which persist until they make their first deck.
- Adjusted the canonical ordering of formats and decks to keep the 3 most-used formats at the top, and the rest in chronological order
- Fixed Dammed Gate-stream (11U235) causing a crash by selecting a Response event.
- Due to the above, if you see any issues with playing Response events in general, please let us know ASAP
<b>2022 August 03</b>
- Added Library Decks, which are a shared set of decks that anyone can load (tho not save or edit)
- Added all starter decks and as many Worlds championship 1/2 decks that we could find to the Library
- Improved the format listings so that all formats are sorted according to chronological order, rather than alphabetical.
- Added ability to rename decks while on the deck selection window
- New players now have all of the library decks in the main hall, which persist until they make their first deck.
<b>2022 August 02</b>
- Fixed each card draw pausing between cards

View File

@@ -1,42 +0,0 @@
package com.gempukku.lotro.cards.set11.site;
import com.gempukku.lotro.logic.cardtype.AbstractShadowsSite;
import com.gempukku.lotro.logic.timing.TriggerConditions;
import com.gempukku.lotro.logic.effects.choose.ChooseAndPlayCardFromDeckEffect;
import com.gempukku.lotro.common.Culture;
import com.gempukku.lotro.common.Keyword;
import com.gempukku.lotro.common.Phase;
import com.gempukku.lotro.common.Side;
import com.gempukku.lotro.game.PhysicalCard;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.actions.OptionalTriggerAction;
import com.gempukku.lotro.logic.timing.EffectResult;
import java.util.Collections;
import java.util.List;
/**
* Set: Shadows
* Twilight Cost: 3
* Type: Site
* Game Text: Marsh. At the start of your fellowship phase, you may play a [GOLLUM] Free Peoples card from your draw
* deck.
*/
public class Card11_235 extends AbstractShadowsSite {
public Card11_235() {
super("Dammed Gate-stream", 3, Direction.RIGHT);
addKeyword(Keyword.MARSH);
}
@Override
public List<OptionalTriggerAction> getOptionalAfterTriggers(String playerId, LotroGame game, EffectResult effectResult, PhysicalCard self) {
if (TriggerConditions.startOfPhase(game, effectResult, Phase.FELLOWSHIP)
&& playerId.equals(game.getGameState().getCurrentPlayerId())) {
OptionalTriggerAction action = new OptionalTriggerAction(self);
action.appendEffect(
new ChooseAndPlayCardFromDeckEffect(playerId, Culture.GOLLUM, Side.FREE_PEOPLE));
return Collections.singletonList(action);
}
return null;
}
}

View File

@@ -802,7 +802,7 @@ public class BuiltLotroCardBlueprint implements LotroCardBlueprint {
for (Requirement playInOtherPhaseCondition : playInOtherPhaseConditions) {
DefaultActionContext actionContext = new DefaultActionContext(playerId, game, self, null, null);
if (playInOtherPhaseCondition.accepts(actionContext)
&& PlayUtils.checkPlayRequirements(game, self, Filters.any, 0, 0, false, false))
&& PlayUtils.checkPlayRequirements(game, self, Filters.any, 0, 0, false, false, false))
playCardActions.add(PlayUtils.getPlayCardAction(game, self, 0, Filters.any, false));
}

View File

@@ -64,10 +64,10 @@ public class PlayCardFromDiscard implements EffectAppenderProducer {
final int costModifier = costModifierSource.getEvaluator(actionContext).evaluateExpression(game, actionContext.getSource());
if (onFilterableSource != null) {
final Filterable onFilterable = onFilterableSource.getFilterable(actionContext);
return Filters.and(Filters.playable(actionContext.getGame(), removedTwilight, costModifier, false, false), ExtraFilters.attachableTo(actionContext.getGame(), onFilterable));
return Filters.and(Filters.playable(actionContext.getGame(), removedTwilight, costModifier, false, false, true), ExtraFilters.attachableTo(actionContext.getGame(), onFilterable));
}
return Filters.playable(actionContext.getGame(), removedTwilight, costModifier, false, false);
return Filters.playable(actionContext.getGame(), removedTwilight, costModifier, false, false, true);
},
countSource, memorize, "you", "Choose card to play", environment));
result.addEffectAppender(

View File

@@ -56,7 +56,7 @@ public class PlayCardFromDrawDeck implements EffectAppenderProducer {
final Filterable onFilterable = onFilterableSource.getFilterable(actionContext);
return Filters.and(Filters.playable(game, costModifier), ExtraFilters.attachableTo(game, onFilterable));
}
return Filters.playable(actionContext.getGame(), costModifier);
return Filters.playable(actionContext.getGame(), costModifier, false, false, true);
},
countSource, memorize, "you", "you", "Choose card to play", environment));
result.addEffectAppender(

View File

@@ -44,7 +44,7 @@ public class PlayCardFromStacked implements EffectAppenderProducer {
result.addEffectAppender(
CardResolver.resolveStackedCards(filter,
actionContext -> Filters.playable(actionContext.getGame()),
actionContext -> Filters.playable(actionContext.getGame(), removedTwilight, 0, false, false),
actionContext -> Filters.playable(actionContext.getGame(), removedTwilight, 0, false, false, true),
countSource, onFilterableSource, "_temp", "you", "Choose card to play", environment));
result.addEffectAppender(
new DelayedAppender() {

View File

@@ -36,7 +36,7 @@ public class CanPlayStackedCards implements ModifierSourceProducer {
new RequirementCondition(requirements, actionContext), ModifierEffect.EXTRA_ACTION_MODIFIER) {
@Override
public List<? extends Action> getExtraPhaseActionFromStacked(LotroGame game, PhysicalCard card) {
if (PlayUtils.checkPlayRequirements(game, card, Filters.any, 0, 0, false, false))
if (PlayUtils.checkPlayRequirements(game, card, Filters.any, 0, 0, false, false, false))
return Collections.singletonList(
PlayUtils.getPlayCardAction(game, card, 0, Filters.any, false));
return null;

View File

@@ -589,10 +589,14 @@ public class Filters {
}
public static Filter playable(final LotroGame game, final int twilightModifier, final boolean ignoreRoamingPenalty, final boolean ignoreCheckingDeadPile) {
return playable(game, 0, twilightModifier, ignoreRoamingPenalty, ignoreCheckingDeadPile);
return playable(game, 0, twilightModifier, ignoreRoamingPenalty, ignoreCheckingDeadPile, false);
}
public static Filter playable(final LotroGame game, final int withTwilightRemoved, final int twilightModifier, final boolean ignoreRoamingPenalty, final boolean ignoreCheckingDeadPile) {
public static Filter playable(final LotroGame game, final int twilightModifier, final boolean ignoreRoamingPenalty, final boolean ignoreCheckingDeadPile, final boolean ignoreResponseEvents) {
return playable(game, 0, twilightModifier, ignoreRoamingPenalty, ignoreCheckingDeadPile, ignoreResponseEvents);
}
public static Filter playable(final LotroGame game, final int withTwilightRemoved, final int twilightModifier, final boolean ignoreRoamingPenalty, final boolean ignoreCheckingDeadPile, final boolean ignoreResponseEvents) {
return new Filter() {
@Override
public boolean accepts(LotroGame game, PhysicalCard physicalCard) {
@@ -601,7 +605,7 @@ public class Filters {
if (blueprint.getSide() != expectedSide)
return false;
return PlayUtils.checkPlayRequirements(game, physicalCard, Filters.any, withTwilightRemoved, twilightModifier, ignoreRoamingPenalty, ignoreCheckingDeadPile);
return PlayUtils.checkPlayRequirements(game, physicalCard, Filters.any, withTwilightRemoved, twilightModifier, ignoreRoamingPenalty, ignoreCheckingDeadPile, ignoreResponseEvents);
}
};
}

View File

@@ -1,20 +1,25 @@
package com.gempukku.lotro.logic;
import com.gempukku.lotro.common.CardType;
import com.gempukku.lotro.common.Filterable;
import com.gempukku.lotro.common.Side;
import com.gempukku.lotro.common.Zone;
import com.gempukku.lotro.common.*;
import com.gempukku.lotro.filters.Filter;
import com.gempukku.lotro.filters.Filters;
import com.gempukku.lotro.game.LotroCardBlueprint;
import com.gempukku.lotro.game.PhysicalCard;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.game.state.actions.DefaultActionsEnvironment;
import com.gempukku.lotro.logic.actions.AttachPermanentAction;
import com.gempukku.lotro.logic.actions.CostToEffectAction;
import com.gempukku.lotro.logic.actions.PlayEventAction;
import com.gempukku.lotro.logic.actions.PlayPermanentAction;
import com.gempukku.lotro.logic.timing.Action;
import com.gempukku.lotro.logic.timing.PlayConditions;
import com.gempukku.lotro.logic.timing.RuleUtils;
import com.google.common.collect.ImmutableMap;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class PlayUtils {
private static Zone getPlayToZone(PhysicalCard card) {
@@ -29,6 +34,27 @@ public class PlayUtils {
}
}
public static Map<Phase, Keyword> PhaseKeywordMap = ImmutableMap.copyOf(new HashMap<Phase, Keyword>() {{
put(Phase.FELLOWSHIP, Keyword.FELLOWSHIP);
put(Phase.SHADOW, Keyword.SHADOW);
put(Phase.MANEUVER, Keyword.MANEUVER);
put(Phase.ARCHERY, Keyword.ARCHERY);
put(Phase.ASSIGNMENT, Keyword.ASSIGNMENT);
put(Phase.SKIRMISH, Keyword.SKIRMISH);
put(Phase.REGROUP, Keyword.REGROUP);
}});
// static {
// phaseKeywordMap = new HashMap<>();
// phaseKeywordMap.put(Phase.FELLOWSHIP, Keyword.FELLOWSHIP);
// phaseKeywordMap.put(Phase.SHADOW, Keyword.SHADOW);
// phaseKeywordMap.put(Phase.MANEUVER, Keyword.MANEUVER);
// phaseKeywordMap.put(Phase.ARCHERY, Keyword.ARCHERY);
// phaseKeywordMap.put(Phase.ASSIGNMENT, Keyword.ASSIGNMENT);
// phaseKeywordMap.put(Phase.SKIRMISH, Keyword.SKIRMISH);
// phaseKeywordMap.put(Phase.REGROUP, Keyword.REGROUP);
// }
private static Filter getFullAttachValidTargetFilter(final LotroGame game, final PhysicalCard card, int twilightModifier, int withTwilightRemoved) {
return Filters.and(RuleUtils.getFullValidTargetFilter(card.getOwner(), game, card),
@@ -84,6 +110,10 @@ public class PlayUtils {
}
public static boolean checkPlayRequirements(LotroGame game, PhysicalCard card, Filterable additionalAttachmentFilter, int withTwilightRemoved, int twilightModifier, boolean ignoreRoamingPenalty, boolean ignoreCheckingDeadPile) {
return checkPlayRequirements(game, card, additionalAttachmentFilter, withTwilightRemoved, twilightModifier, ignoreRoamingPenalty, ignoreCheckingDeadPile, false);
}
public static boolean checkPlayRequirements(LotroGame game, PhysicalCard card, Filterable additionalAttachmentFilter, int withTwilightRemoved, int twilightModifier, boolean ignoreRoamingPenalty, boolean ignoreCheckingDeadPile, boolean ignoreResponseEvents) {
final LotroCardBlueprint blueprint = card.getBlueprint();
// Check if card's own play requirements are met
@@ -113,9 +143,22 @@ public class PlayUtils {
return false;
if (blueprint.getCardType() == CardType.COMPANION
&& !(PlayConditions.checkRuleOfNine(game, card) && PlayConditions.checkPlayRingBearer(game, card)))
&& !(PlayConditions.checkRuleOfNine(game, card) && PlayConditions.checkPlayRingBearer(game, card)))
return false;
if(blueprint.getCardType() == CardType.EVENT)
{
if(game.getModifiersQuerying().hasKeyword(game, card, Keyword.RESPONSE)) {
if (ignoreResponseEvents)
return false;
}
else {
final Keyword phaseKeyword = PhaseKeywordMap.get(game.getGameState().getCurrentPhase());
if (phaseKeyword != null && !game.getModifiersQuerying().hasKeyword(game, card, phaseKeyword))
return false;
}
}
return (blueprint.getSide() != Side.SHADOW || PlayConditions.canPayForShadowCard(game, card, finalTargetFilter, withTwilightRemoved, twilightModifier, ignoreRoamingPenalty));
}
}

View File

@@ -19,7 +19,7 @@ public class ExtraFilters {
public boolean accepts(LotroGame game, PhysicalCard physicalCard) {
if (physicalCard.getBlueprint().getValidTargetFilter(physicalCard.getOwner(), game, physicalCard) == null)
return false;
return PlayUtils.checkPlayRequirements(game, physicalCard, Filters.and(filters), 0, twilightModifier, false, false);
return PlayUtils.checkPlayRequirements(game, physicalCard, Filters.and(filters), 0, twilightModifier, false, false, true);
}
});
}

View File

@@ -327,7 +327,7 @@ public class PlayConditions {
}
public static boolean canPlayFromHand(String playerId, LotroGame game, int withTwilightRemoved, int twilightModifier, boolean ignoreRoamingPenalty, boolean ignoreCheckingDeadPile, Filterable... filters) {
return Filters.filter(game.getGameState().getHand(playerId), game, Filters.and(filters, Filters.playable(game, withTwilightRemoved, twilightModifier, ignoreRoamingPenalty, ignoreCheckingDeadPile))).size() > 0;
return Filters.filter(game.getGameState().getHand(playerId), game, Filters.and(filters, Filters.playable(game, withTwilightRemoved, twilightModifier, ignoreRoamingPenalty, ignoreCheckingDeadPile, false))).size() > 0;
}
public static boolean canPlayFromDeadPile(String playerId, LotroGame game, Filterable... filters) {
@@ -347,7 +347,7 @@ public class PlayConditions {
public static boolean canPlayFromStacked(String playerId, LotroGame game, int withTwilightRemoved, Filterable stackedOn, Filterable... filters) {
final Collection<PhysicalCard> matchingStackedOn = Filters.filterActive(game, stackedOn);
for (PhysicalCard stackedOnCard : matchingStackedOn) {
if (Filters.filter(game.getGameState().getStackedCards(stackedOnCard), game, Filters.and(filters, Filters.playable(game, withTwilightRemoved, 0, false, false))).size() > 0)
if (Filters.filter(game.getGameState().getStackedCards(stackedOnCard), game, Filters.and(filters, Filters.playable(game, withTwilightRemoved, 0, false, false, false))).size() > 0)
return true;
}
@@ -357,7 +357,7 @@ public class PlayConditions {
public static boolean canPlayFromStacked(String playerId, LotroGame game, int withTwilightRemoved, int twilightModifier, Filterable stackedOn, Filterable... filters) {
final Collection<PhysicalCard> matchingStackedOn = Filters.filterActive(game, stackedOn);
for (PhysicalCard stackedOnCard : matchingStackedOn) {
if (Filters.filter(game.getGameState().getStackedCards(stackedOnCard), game, Filters.and(filters, Filters.playable(game, withTwilightRemoved, twilightModifier, false, false))).size() > 0)
if (Filters.filter(game.getGameState().getStackedCards(stackedOnCard), game, Filters.and(filters, Filters.playable(game, withTwilightRemoved, twilightModifier, false, false, false))).size() > 0)
return true;
}
@@ -379,7 +379,7 @@ public class PlayConditions {
public static boolean canPlayFromDiscard(String playerId, LotroGame game, int withTwilightRemoved, int modifier, Filterable... filters) {
if (game.getModifiersQuerying().hasFlagActive(game, ModifierFlag.CANT_PLAY_FROM_DISCARD_OR_DECK))
return false;
return Filters.filter(game.getGameState().getDiscard(playerId), game, Filters.and(filters, Filters.playable(game, withTwilightRemoved, modifier, false, false))).size() > 0;
return Filters.filter(game.getGameState().getDiscard(playerId), game, Filters.and(filters, Filters.playable(game, withTwilightRemoved, modifier, false, false, false))).size() > 0;
}
public static boolean canDiscardFromPlay(final PhysicalCard source, LotroGame game, final PhysicalCard card) {

View File

@@ -46,7 +46,7 @@ public class PlayerPlaysStartingFellowshipGameProcess implements GameProcess {
public boolean accepts(LotroGame game, PhysicalCard physicalCard) {
int twilightCost = game.getModifiersQuerying().getTwilightCost(game, physicalCard, null, 0, false);
return game.getGameState().getTwilightPool() + twilightCost <= 4
&& PlayUtils.checkPlayRequirements(game, physicalCard, Filters.any, 0, 0, false, false);
&& PlayUtils.checkPlayRequirements(game, physicalCard, Filters.any, 0, 0, false, false, true);
}
});
}

View File

@@ -19,19 +19,9 @@ import java.util.List;
public class PlayCardInPhaseRule {
private DefaultActionsEnvironment actionsEnvironment;
private final HashMap<Phase, Keyword> phaseKeywordMap;
public PlayCardInPhaseRule(DefaultActionsEnvironment actionsEnvironment) {
this.actionsEnvironment = actionsEnvironment;
phaseKeywordMap = new HashMap<>();
phaseKeywordMap.put(Phase.FELLOWSHIP, Keyword.FELLOWSHIP);
phaseKeywordMap.put(Phase.SHADOW, Keyword.SHADOW);
phaseKeywordMap.put(Phase.MANEUVER, Keyword.MANEUVER);
phaseKeywordMap.put(Phase.ARCHERY, Keyword.ARCHERY);
phaseKeywordMap.put(Phase.ASSIGNMENT, Keyword.ASSIGNMENT);
phaseKeywordMap.put(Phase.SKIRMISH, Keyword.SKIRMISH);
phaseKeywordMap.put(Phase.REGROUP, Keyword.REGROUP);
}
public void applyRule() {
@@ -46,7 +36,7 @@ public class PlayCardInPhaseRule {
List<Action> result = new LinkedList<>();
for (PhysicalCard card : Filters.filter(game.getGameState().getHand(playerId), game, side,
Filters.or(Filters.and(CardType.EVENT, Keyword.FELLOWSHIP), Filters.not(CardType.EVENT)))) {
if (PlayUtils.checkPlayRequirements(game, card, Filters.any, 0, 0, false, false))
if (PlayUtils.checkPlayRequirements(game, card, Filters.any, 0, 0, false, false, true))
result.add(PlayUtils.getPlayCardAction(game, card, 0, Filters.any, false));
}
return result;
@@ -56,18 +46,18 @@ public class PlayCardInPhaseRule {
List<Action> result = new LinkedList<>();
for (PhysicalCard card : Filters.filter(game.getGameState().getHand(playerId), game, side,
Filters.or(Filters.and(CardType.EVENT, Keyword.SHADOW), Filters.not(CardType.EVENT)))) {
if (PlayUtils.checkPlayRequirements(game, card, Filters.any, 0, 0, false, false))
if (PlayUtils.checkPlayRequirements(game, card, Filters.any, 0, 0, false, false, true))
result.add(PlayUtils.getPlayCardAction(game, card, 0, Filters.any, false));
}
return result;
}
} else {
final Keyword phaseKeyword = phaseKeywordMap.get(game.getGameState().getCurrentPhase());
final Keyword phaseKeyword = PlayUtils.PhaseKeywordMap.get(game.getGameState().getCurrentPhase());
if (phaseKeyword != null) {
List<Action> result = new LinkedList<>();
for (PhysicalCard card : Filters.filter(game.getGameState().getHand(playerId), game, side,
Filters.and(CardType.EVENT, phaseKeyword))) {
if (PlayUtils.checkPlayRequirements(game, card, Filters.any, 0, 0, false, false))
if (PlayUtils.checkPlayRequirements(game, card, Filters.any, 0, 0, false, false, true))
result.add(PlayUtils.getPlayCardAction(game, card, 0, Filters.any, false));
}
return result;

View File

@@ -33,7 +33,7 @@ public class PlayResponseEventRule {
List<Action> result = new LinkedList<>();
final Side side = GameUtils.getSide(game, playerId);
for (PhysicalCard responseEvent : Filters.filter(game.getGameState().getHand(playerId), game, side, CardType.EVENT, Keyword.RESPONSE)) {
if (PlayUtils.checkPlayRequirements(game, responseEvent, Filters.any, 0, 0, false, false)) {
if (PlayUtils.checkPlayRequirements(game, responseEvent, Filters.any, 0, 0, false, false, false)) {
final List<PlayEventAction> actions = responseEvent.getBlueprint().getPlayResponseEventAfterActions(playerId, game, effectResult, responseEvent);
if (actions != null)
result.addAll(actions);
@@ -47,7 +47,7 @@ public class PlayResponseEventRule {
List<Action> result = new LinkedList<>();
final Side side = GameUtils.getSide(game, playerId);
for (PhysicalCard responseEvent : Filters.filter(game.getGameState().getHand(playerId), game, side, CardType.EVENT, Keyword.RESPONSE)) {
if (PlayUtils.checkPlayRequirements(game, responseEvent, Filters.any, 0, 0, false, false)) {
if (PlayUtils.checkPlayRequirements(game, responseEvent, Filters.any, 0, 0, false, false, false)) {
final List<PlayEventAction> actions = responseEvent.getBlueprint().getPlayResponseEventBeforeActions(playerId, game, effect, responseEvent);
if (actions != null)
result.addAll(actions);

View File

@@ -51,10 +51,14 @@ public abstract class AbstractAtTest {
}
protected void initializeGameWithDecks(Map<String, LotroDeck> decks) throws DecisionResultInvalidException {
initializeGameWithDecks(decks, "multipath");
}
protected void initializeGameWithDecks(Map<String, LotroDeck> decks, String formatName) throws DecisionResultInvalidException {
_userFeedback = new DefaultUserFeedback();
LotroFormatLibrary formatLibrary = new LotroFormatLibrary(new DefaultAdventureLibrary(), _library);
LotroFormat format = formatLibrary.getFormat("multipath");
LotroFormat format = formatLibrary.getFormat(formatName);
_game = new DefaultLotroGame(format, decks, _userFeedback, _library);
_userFeedback.setGame(_game);

View File

@@ -69,14 +69,16 @@ public class GenericCardTestHelper extends AbstractAtTest {
public Map<String, Map<String, PhysicalCardImpl>> Cards = new HashMap<>();
public GenericCardTestHelper(HashMap<String, String> cardIDs) throws CardNotFoundException, DecisionResultInvalidException {
this(cardIDs, null, null, null);
this(cardIDs, null, null, null, "multipath");
}
public GenericCardTestHelper(HashMap<String, String> cardIDs, HashMap<String, String> siteIDs, String ringBearerID, String ringID) throws CardNotFoundException, DecisionResultInvalidException {
this(cardIDs, siteIDs, ringBearerID, ringID, "multipath");
}
public GenericCardTestHelper(HashMap<String, String> cardIDs, HashMap<String, String> siteIDs, String ringBearerID, String ringID, String path) throws CardNotFoundException, DecisionResultInvalidException {
super();
if(siteIDs == null || ringBearerID == null || ringID == null) {
initializeSimplestGame();
}
@@ -97,7 +99,7 @@ public class GenericCardTestHelper extends AbstractAtTest {
decks.get(P1).setRing(ringID);
decks.get(P2).setRing(ringID);
initializeGameWithDecks(decks);
initializeGameWithDecks(decks, path);
}
Cards.put(P1, new HashMap<>());
@@ -122,6 +124,15 @@ public class GenericCardTestHelper extends AbstractAtTest {
skipMulligans();
}
public void SkipStartingFellowships() throws DecisionResultInvalidException {
if(FreepsDecisionAvailable("Starting fellowship")) {
FreepsChoose("");
}
if(ShadowDecisionAvailable("Starting fellowship")) {
ShadowChoose("");
}
}
public PhysicalCardImpl GetFreepsCard(String cardName) { return Cards.get(P1).get(cardName); }
public PhysicalCardImpl GetShadowCard(String cardName) { return Cards.get(P2).get(cardName); }
public PhysicalCardImpl GetFreepsCardByID(String id) { return GetCardByID(P1, Integer.parseInt(id)); }
@@ -145,6 +156,14 @@ 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 GetFreepsSite(String name) { return GetSiteByName(P1, name); }
public PhysicalCardImpl GetShadowSite(String name) { return GetSiteByName(P2, name); }
public PhysicalCardImpl GetSiteByName(String playerID, String name)
{
final String lowername = name.toLowerCase();
List<PhysicalCardImpl> advDeck = (List<PhysicalCardImpl>)_game.getGameState().getAdventureDeck(playerID);
return advDeck.stream().filter(x -> x.getBlueprint().getTitle().toLowerCase().contains(lowername)).findFirst().get();
}
public List<String> FreepsGetAvailableActions() { return GetAvailableActions(P1); }
public List<String> ShadowGetAvailableActions() { return GetAvailableActions(P2); }

View File

@@ -0,0 +1,119 @@
package com.gempukku.lotro.cards.official.set11;
import com.gempukku.lotro.cards.GenericCardTestHelper;
import com.gempukku.lotro.common.CardType;
import com.gempukku.lotro.common.Keyword;
import com.gempukku.lotro.common.Zone;
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 junit.framework.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class Card_11_235_Tests
{
protected GenericCardTestHelper GetScenario() throws CardNotFoundException, DecisionResultInvalidException {
return new GenericCardTestHelper(
new HashMap<String, String>()
{{
put("dontlook", "6_39");
put("smeagol", "7_71");
put("boat", "13_48");
put("slippery", "6_43");
put("clever", "7_54");
}},
new HashMap<String, String>() {{
put("site1", "11_235");
put("site2", "18_138");
put("site3", "18_138");
put("site4", "18_138");
put("site5", "18_138");
put("site6", "18_138");
put("site7", "18_138");
put("site8", "18_138");
put("site9", "18_138");
}},
GenericCardTestHelper.FOTRFrodo,
GenericCardTestHelper.FOTRRing,
"open"
);
}
@Test
public void DammedGateStreamStatsAndKeywordsAreCorrect() throws DecisionResultInvalidException, CardNotFoundException {
/**
* Set: 11
* Title: Dammed Gate-stream
* Side: Site
* Culture: Site
* Twilight Cost: 3
* Type: Site
* Site Number: *
* Game Text: Marsh. At the start of your fellowship phase, you may play a [GOLLUM] Free Peoples card from your draw deck.
*/
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
PhysicalCardImpl site1 = scn.GetFreepsSite("Dammed Gate-stream");
assertFalse(site1.getBlueprint().isUnique());
//assertEquals(Side.FREE_PEOPLE, site1.getBlueprint().getSide());
//assertEquals(Culture., site1.getBlueprint().getCulture());
assertEquals(CardType.SITE, site1.getBlueprint().getCardType());
//assertEquals(Race.CREATURE, site1.getBlueprint().getRace());
assertTrue(scn.HasKeyword(site1, Keyword.MARSH)); // test for keywords as needed
assertEquals(3, site1.getBlueprint().getTwilightCost());
//assertEquals(, site1.getBlueprint().getStrength());
//assertEquals(, site1.getBlueprint().getVitality());
//assertEquals(, site1.getBlueprint().getResistance());
//assertEquals(Signet., site1.getBlueprint().getSignet());
assertEquals(0, site1.getBlueprint().getSiteNumber()); // Change this to getAllyHomeSiteNumbers for allies
}
@Test
public void StartOfFellowshipPhaseActionAllowsPlayFromDrawDeck() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
PhysicalCardImpl frodo = scn.GetRingBearer();
PhysicalCardImpl dontlook = scn.GetFreepsCard("dontlook");
PhysicalCardImpl smeagol = scn.GetFreepsCard("smeagol");
PhysicalCardImpl slippery = scn.GetFreepsCard("slippery");
PhysicalCardImpl boat = scn.GetFreepsCard("boat");
PhysicalCardImpl clever = scn.GetFreepsCard("clever");
PhysicalCardImpl site1 = scn.GetFreepsSite("Dammed Gate-stream");
scn.FreepsChooseCardBPFromSelection(site1);
scn.SkipStartingFellowships();
//Apparently it's drawing cards now. It doesn't do this in other formats.
scn.FreepsMoveCardsToBottomOfDeck(dontlook, smeagol, slippery, boat, clever);
scn.StartGame();
assertTrue(scn.FreepsHasOptionalTriggerAvailable());
scn.FreepsAcceptOptionalTrigger();
//Not Listening is a response event, it shouldn't show up
//Clever Hobbits is a skirmish event, also shouldn't show
//Smeagol and Don't Look At Them are valid. Fishing Boat would theoretically be valid if Smeagol were in play.
assertEquals(2, scn.GetFreepsCardChoiceCount());
assertEquals(Zone.DECK, dontlook.getZone());
assertEquals(Zone.DECK, smeagol.getZone());
scn.FreepsChooseCardBPFromSelection(dontlook);
assertEquals(Zone.SUPPORT, dontlook.getZone());
assertEquals(Zone.DECK, smeagol.getZone());
}
}