Merge branch 'master' into update
This commit is contained in:
@@ -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))"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user