Some Reflections cards

This commit is contained in:
marcin.sciesinski
2019-09-12 20:59:59 -07:00
parent 29382da5df
commit a128923f6f
11 changed files with 252 additions and 279 deletions

View File

@@ -899,5 +899,186 @@
}
]
}
},
"9_24": {
"title": "Ent Draught",
"culture": "gandalf",
"cost": 1,
"type": "condition",
"vitality": 1,
"condition": {
"type": "canSpot",
"filter": "ent"
},
"target": "companion,not(hasAttached(name(Ent Draught)))",
"effects": {
"type": "activated",
"phase": "skirmish",
"cost": {
"type": "exert",
"filter": "choose(bearer)",
"memorize": "bearer"
},
"effect": {
"type": "addKeyword",
"filter": "memory(bearer)",
"keyword": "damage+1"
}
}
},
"9_25": {
"title": "Huorn",
"culture": "gandalf",
"cost": 2,
"type": "companion",
"race": "tree",
"strength": 6,
"vitality": 4,
"resistance": 6,
"keyword": "damage+1",
"effects": [
{
"type": "modifier",
"modifier": {
"type": "modifyStrength",
"filter": "self",
"amount": {
"type": "forEachYouCanSpot",
"filter": "ent"
}
}
},
{
"type": "activatedTrigger",
"trigger": {
"type": "aboutToTakeWound",
"filter": "self"
},
"cost": {
"type": "exert",
"filter": "choose(ent)"
},
"effect": {
"type": "preventWound",
"filter": "self"
}
}
]
},
"9_26": {
"title": "*Radagast",
"subtitle": "The Brown",
"culture": "gandalf",
"cost": 4,
"type": "companion",
"race": "wizard",
"strength": 8,
"vitality": 4,
"resistance": 6,
"signet": "gandalf",
"effects": [
{
"type": "trigger",
"trigger": [
{
"type": "played",
"filter": "self"
},
{
"type": "startOfTurn"
}
],
"condition": {
"type": "perTurnLimit",
"limit": 1
},
"effect": [
{
"type": "incrementPerTurnLimit",
"limit": 1
},
{
"type": "addModifier",
"until": "endOfTurn",
"modifier": {
"type": "modifyMoveLimit",
"amount": 1
}
}
]
},
{
"type": "trigger",
"trigger": {
"type": "moves"
},
"condition": {
"type": "phase",
"phase": "regroup"
},
"effect": {
"type": "optional",
"player": "shadowPlayer",
"text": "Would you like to discard 2 cards to draw 2 cards?",
"effect": {
"type": "costToEffect",
"cost": {
"type": "discardFromHand",
"forced": false,
"count": 2
},
"effect": {
"type": "drawCards",
"count": 2
}
}
}
}
]
},
"9_27": {
"title": "Sent Back",
"culture": "gandalf",
"cost": 2,
"type": "condition",
"keyword": "support area",
"effects": [
{
"type": "activated",
"phase": "skirmish",
"cost": {
"type": "discard",
"filter": "self"
},
"effect": [
{
"type": "chooseActiveCards",
"text": "Choose Wizard to put in dead pile",
"filter": "choose(wizard,inSkirmish)",
"memorize": "chosenWizard"
},
{
"type": "discard",
"filter": "all(minion,inSkirmishAgainst(memory(chosenWizard)))"
},
{
"type": "kill",
"filter": "memory(chosenWizard)"
}
]
},
{
"type": "activated",
"phase": [
"fellowship",
"regroup"
],
"effect": {
"type": "play",
"filter": "choose(wizard)",
"ignoreInDeadPile": true
}
}
]
}
}

View File

@@ -1,61 +0,0 @@
package com.gempukku.lotro.cards.set9.gandalf;
import com.gempukku.lotro.common.*;
import com.gempukku.lotro.filters.Filters;
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.cardtype.AbstractAttachable;
import com.gempukku.lotro.logic.effects.AddUntilEndOfPhaseModifierEffect;
import com.gempukku.lotro.logic.effects.ExertCharactersEffect;
import com.gempukku.lotro.logic.modifiers.KeywordModifier;
import com.gempukku.lotro.logic.timing.PlayConditions;
import java.util.Collections;
import java.util.List;
/**
* Set: Reflections
* Side: Free
* Culture: Gandalf
* Twilight Cost: 1
* Type: Condition
* Vitality: +1
* Game Text: To play, spot an Ent. Bearer must be a companion. Limit 1 per bearer. Skirmish: Exert bearer to make him
* or her damage +1.
*/
public class Card9_024 extends AbstractAttachable {
public Card9_024() {
super(Side.FREE_PEOPLE, CardType.CONDITION, 1, Culture.GANDALF, null, "Ent Draught");
}
@Override
public boolean checkPlayRequirements(LotroGame game, PhysicalCard self) {
return (Filters.countActive(game, Race.ENT) + game.getModifiersQuerying().getSpotBonus(game, Race.ENT)) >= 1;
}
@Override
public Filterable getValidTargetFilter(String playerId, LotroGame game, PhysicalCard self) {
return Filters.and(CardType.COMPANION, Filters.not(Filters.hasAttached(Filters.name(getTitle()))));
}
@Override
public int getVitality() {
return 1;
}
@Override
public List<? extends ActivateCardAction> getPhaseActionsInPlay(String playerId, LotroGame game, PhysicalCard self) {
if (PlayConditions.canUseFPCardDuringPhase(game, Phase.SKIRMISH, self)
&& PlayConditions.canExert(self, game, Filters.hasAttached(self))) {
ActivateCardAction action = new ActivateCardAction(self);
action.appendCost(
new ExertCharactersEffect(action, self, self.getAttachedTo()));
action.appendEffect(
new AddUntilEndOfPhaseModifierEffect(
new KeywordModifier(self, self.getAttachedTo(), Keyword.DAMAGE, 1)));
return Collections.singletonList(action);
}
return null;
}
}

View File

@@ -1,67 +0,0 @@
package com.gempukku.lotro.cards.set9.gandalf;
import com.gempukku.lotro.common.Culture;
import com.gempukku.lotro.common.Keyword;
import com.gempukku.lotro.common.Race;
import com.gempukku.lotro.filters.Filters;
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.cardtype.AbstractCompanion;
import com.gempukku.lotro.logic.effects.PreventCardEffect;
import com.gempukku.lotro.logic.effects.WoundCharactersEffect;
import com.gempukku.lotro.logic.effects.choose.ChooseAndExertCharactersEffect;
import com.gempukku.lotro.logic.modifiers.Modifier;
import com.gempukku.lotro.logic.modifiers.StrengthModifier;
import com.gempukku.lotro.logic.modifiers.evaluator.Evaluator;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.PlayConditions;
import com.gempukku.lotro.logic.timing.TriggerConditions;
import java.util.Collections;
import java.util.List;
/**
* Set: Reflections
* Side: Free
* Culture: Gandalf
* Twilight Cost: 2
* Type: Companion • Tree
* Strength: 6
* Vitality: 4
* Resistance: 6
* Game Text: Damage +1. This companion is strength +1 for each Ent you spot. Response: If this companion is about to
* take a wound, exert an Ent to prevent that.
*/
public class Card9_025 extends AbstractCompanion {
public Card9_025() {
super(2, 6, 4, 6, Culture.GANDALF, Race.TREE, null, "Huorn");
addKeyword(Keyword.DAMAGE, 1);
}
@Override
public List<? extends Modifier> getInPlayModifiers(LotroGame game, PhysicalCard self) {
return Collections.singletonList(
new StrengthModifier(self, self, null,
new Evaluator() {
@Override
public int evaluateExpression(LotroGame game, PhysicalCard cardAffected) {
return Filters.countActive(game, Race.ENT) + game.getModifiersQuerying().getSpotBonus(game, Race.ENT);
}
}));
}
@Override
public List<? extends ActivateCardAction> getOptionalInPlayBeforeActions(String playerId, LotroGame game, Effect effect, PhysicalCard self) {
if (TriggerConditions.isGettingWounded(effect, game, self)
&& PlayConditions.canExert(self, game, Race.ENT)) {
ActivateCardAction action = new ActivateCardAction(self);
action.appendCost(
new ChooseAndExertCharactersEffect(action, playerId, 1, 1, Race.ENT));
action.appendEffect(
new PreventCardEffect((WoundCharactersEffect) effect, self));
return Collections.singletonList(action);
}
return null;
}
}

View File

@@ -1,79 +0,0 @@
package com.gempukku.lotro.cards.set9.gandalf;
import com.gempukku.lotro.logic.cardtype.AbstractCompanion;
import com.gempukku.lotro.logic.timing.PlayConditions;
import com.gempukku.lotro.logic.timing.TriggerConditions;
import com.gempukku.lotro.logic.effects.OptionalEffect;
import com.gempukku.lotro.logic.modifiers.MoveLimitModifier;
import com.gempukku.lotro.common.Culture;
import com.gempukku.lotro.common.Phase;
import com.gempukku.lotro.common.Race;
import com.gempukku.lotro.common.Signet;
import com.gempukku.lotro.filters.Filters;
import com.gempukku.lotro.game.PhysicalCard;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.GameUtils;
import com.gempukku.lotro.logic.actions.RequiredTriggerAction;
import com.gempukku.lotro.logic.effects.ChooseAndDiscardCardsFromHandEffect;
import com.gempukku.lotro.logic.effects.DrawCardsEffect;
import com.gempukku.lotro.logic.timing.EffectResult;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
/**
* Set: Reflections
* Side: Free
* Culture: Gandalf
* Twilight Cost: 4
* Type: Companion • Wizard
* Strength: 8
* Vitality: 4
* Resistance: 6
* Signet: Gandalf
* Game Text: The move limit is +1. Each time the fellowship moves during the regroup phase, each opponent may discard
* 2 cards to draw 2 cards.
*/
public class Card9_026 extends AbstractCompanion {
public Card9_026() {
super(4, 8, 4, 6, Culture.GANDALF, Race.WIZARD, Signet.GANDALF, "Radagast", "The Brown", true);
}
@Override
public List<RequiredTriggerAction> getRequiredAfterTriggers(LotroGame game, EffectResult effectResult, PhysicalCard self) {
if ((TriggerConditions.played(game, effectResult, self) || TriggerConditions.startOfTurn(game, effectResult))
&& game.getModifiersQuerying().getUntilEndOfTurnLimitCounter(self).getUsedLimit() < 1) {
game.getModifiersEnvironment().addUntilEndOfTurnModifier(
new MoveLimitModifier(self, 1));
game.getModifiersQuerying().getUntilEndOfTurnLimitCounter(self).incrementToLimit(1, 1);
}
if (TriggerConditions.moves(game, effectResult)
&& PlayConditions.isPhase(game, Phase.REGROUP)) {
List<RequiredTriggerAction> actions = new LinkedList<RequiredTriggerAction>();
for (final String opponent : GameUtils.getShadowPlayers(game)) {
if (PlayConditions.canDiscardFromHand(game, opponent, 2, Filters.any)) {
final RequiredTriggerAction action = new RequiredTriggerAction(self);
action.appendCost(
new OptionalEffect(action, opponent,
new ChooseAndDiscardCardsFromHandEffect(action, opponent, false, 2) {
@Override
public String getText(LotroGame game) {
return "Discard 2 cards to draw 2 cards";
}
@Override
protected void cardsBeingDiscardedCallback(Collection<PhysicalCard> cardsBeingDiscarded) {
if (cardsBeingDiscarded.size() == 2)
action.appendEffect(
new DrawCardsEffect(action, opponent, 2));
}
}));
actions.add(action);
}
}
return actions;
}
return null;
}
}

View File

@@ -1,63 +0,0 @@
package com.gempukku.lotro.cards.set9.gandalf;
import com.gempukku.lotro.common.*;
import com.gempukku.lotro.filters.Filters;
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.cardtype.AbstractPermanent;
import com.gempukku.lotro.logic.effects.DiscardCardsFromPlayEffect;
import com.gempukku.lotro.logic.effects.KillEffect;
import com.gempukku.lotro.logic.effects.SelfDiscardEffect;
import com.gempukku.lotro.logic.effects.choose.ChooseAndPlayCardFromHandEffect;
import com.gempukku.lotro.logic.timing.PlayConditions;
import com.gempukku.lotro.logic.timing.UnrespondableEffect;
import java.util.Collections;
import java.util.List;
/**
* Set: Reflections
* Side: Free
* Culture: Gandalf
* Twilight Cost: 2
* Type: Condition • Support Area
* Game Text: Skirmish: Discard this condition to discard each minion skirmishing a Wizard. Place that Wizard in your
* dead pile. Fellowship or Regroup: Play a Wizard (even if another copy of that Wizard is in your dead pile).
*/
public class Card9_027 extends AbstractPermanent {
public Card9_027() {
super(Side.FREE_PEOPLE, 2, CardType.CONDITION, Culture.GANDALF, "Sent Back");
}
@Override
public List<? extends ActivateCardAction> getPhaseActionsInPlay(String playerId, LotroGame game, PhysicalCard self) {
if (PlayConditions.canUseFPCardDuringPhase(game, Phase.SKIRMISH, self)
&& PlayConditions.canSelfDiscard(self, game)) {
final ActivateCardAction action = new ActivateCardAction(self);
action.appendCost(
new SelfDiscardEffect(self));
action.appendEffect(
new DiscardCardsFromPlayEffect(self.getOwner(), self, CardType.MINION, Filters.inSkirmishAgainst(Race.WIZARD)));
action.appendEffect(
new UnrespondableEffect() {
@Override
protected void doPlayEffect(LotroGame game) {
PhysicalCard wizard = Filters.findFirstActive(game, Race.WIZARD, Filters.inSkirmish);
if (wizard != null)
action.appendEffect(
new KillEffect(wizard, KillEffect.Cause.CARD_EFFECT));
}
});
return Collections.singletonList(action);
}
if ((PlayConditions.canUseFPCardDuringPhase(game, Phase.FELLOWSHIP, self) || PlayConditions.canUseFPCardDuringPhase(game, Phase.REGROUP, self))
&& PlayConditions.canPlayFromHand(playerId, game, 0, false, true, Side.FREE_PEOPLE, Race.WIZARD)) {
ActivateCardAction action = new ActivateCardAction(self);
action.appendEffect(
new ChooseAndPlayCardFromHandEffect(playerId, game, 0, false, true, Side.FREE_PEOPLE, Race.WIZARD));
return Collections.singletonList(action);
}
return null;
}
}

View File

@@ -109,6 +109,7 @@ public class EffectAppenderFactory {
effectAppenderProducers.put("liberatesite", new LiberateSite());
effectAppenderProducers.put("filtercardsinmemory", new FilterCardsInMemory());
effectAppenderProducers.put("discardcardsfromdrawdeck", new DiscardCardsFromDrawDeck());
effectAppenderProducers.put("incrementperturnlimit", new IncrementPerTurnLimit());
}
public EffectAppender getEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {

View File

@@ -0,0 +1,35 @@
package com.gempukku.lotro.cards.build.field.effect.appender;
import com.gempukku.lotro.cards.build.ActionContext;
import com.gempukku.lotro.cards.build.CardGenerationEnvironment;
import com.gempukku.lotro.cards.build.InvalidCardDefinitionException;
import com.gempukku.lotro.cards.build.field.FieldUtils;
import com.gempukku.lotro.cards.build.field.effect.EffectAppender;
import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer;
import com.gempukku.lotro.logic.actions.CostToEffectAction;
import com.gempukku.lotro.logic.effects.IncrementTurnLimitEffect;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.PlayConditions;
import org.json.simple.JSONObject;
public class IncrementPerTurnLimit implements EffectAppenderProducer {
@Override
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(effectObject, "limit");
final int limit = FieldUtils.getInteger(effectObject.get("limit"), "limit", 1);
return new DelayedAppender() {
@Override
protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) {
return new IncrementTurnLimitEffect(actionContext.getSource(), limit);
}
@Override
public boolean isPlayableInFull(ActionContext actionContext) {
return PlayConditions.checkTurnLimit(actionContext.getGame(), actionContext.getSource(), limit);
}
};
}
}

View File

@@ -1,11 +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.*;
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.logic.actions.CostToEffectAction;
import com.gempukku.lotro.logic.actions.SubAction;
import com.gempukku.lotro.logic.decisions.YesNoDecision;
@@ -17,26 +16,32 @@ import org.json.simple.JSONObject;
public class Optional implements EffectAppenderProducer {
@Override
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(effectObject, "text", "effect");
FieldUtils.validateAllowedFields(effectObject, "player", "text", "effect");
final String player = FieldUtils.getString(effectObject.get("player"), "player", "you");
final String text = FieldUtils.getString(effectObject.get("text"), "text");
final JSONObject effect = (JSONObject) effectObject.get("effect");
if (text == null)
throw new InvalidCardDefinitionException("There is a text required for optional effects");
final PlayerSource playerSource = PlayerResolver.resolvePlayer(player, environment);
final EffectAppender effectAppender = environment.getEffectAppenderFactory().getEffectAppender(effect, environment);
return new DelayedAppender() {
@Override
protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) {
final String choosingPlayer = playerSource.getPlayer(actionContext);
SubAction subAction = new SubAction(action);
subAction.appendCost(
new PlayoutDecisionEffect(actionContext.getPerformingPlayer(),
new PlayoutDecisionEffect(choosingPlayer,
new YesNoDecision(text) {
@Override
protected void yes() {
effectAppender.appendEffect(cost, subAction, actionContext);
ActionContext delegate = new DelegateActionContext(actionContext,
choosingPlayer, actionContext.getGame(), actionContext.getSource(),
actionContext.getEffectResult(), actionContext.getEffect());
effectAppender.appendEffect(cost, subAction, delegate);
}
}));
return new StackActionEffect(subAction);

View File

@@ -24,11 +24,12 @@ import java.util.Collection;
public class PlayCardFromHand implements EffectAppenderProducer {
@Override
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(effectObject, "filter", "on", "cost");
FieldUtils.validateAllowedFields(effectObject, "filter", "on", "cost", "ignoreInDeadPile");
final String filter = FieldUtils.getString(effectObject.get("filter"), "filter");
final String onFilter = FieldUtils.getString(effectObject.get("on"), "on");
final ValueSource costModifierSource = ValueResolver.resolveEvaluator(effectObject.get("cost"), 0, environment);
final boolean ignoreInDeadPile = FieldUtils.getBoolean(effectObject.get("ignoreInDeadPile"), "ignoreInDeadPile", false);
final FilterableSource onFilterableSource = (onFilter != null) ? environment.getFilterFactory().generateFilter(onFilter, environment) : null;
@@ -42,9 +43,9 @@ public class PlayCardFromHand 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(game, costModifier), ExtraFilters.attachableTo(game, onFilterable));
return Filters.and(Filters.playable(game, costModifier, false, ignoreInDeadPile), ExtraFilters.attachableTo(game, onFilterable));
}
return Filters.playable(game, costModifier);
return Filters.playable(game, costModifier, false, ignoreInDeadPile);
},
new ConstantEvaluator(1), "_temp", "you", "Choose card to play", environment));
result.addEffectAppender(

View File

@@ -0,0 +1,19 @@
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 com.gempukku.lotro.logic.timing.PlayConditions;
import org.json.simple.JSONObject;
public class PerTurnLimit implements RequirementProducer {
@Override
public Requirement getPlayRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(object, "limit");
final int limit = FieldUtils.getInteger(object.get("limit"), "limit", 1);
return (actionContext) -> PlayConditions.checkTurnLimit(actionContext.getGame(), actionContext.getSource(), limit);
}
}

View File

@@ -36,6 +36,7 @@ public class RequirementFactory {
requirementProducers.put("ismore", new IsMore());
requirementProducers.put("hasinzonedata", new HasInZoneData());
requirementProducers.put("isside", new IsSideRequirementProducer());
requirementProducers.put("perturnlimit", new PerTurnLimit());
}
public Requirement getRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {