Added all Gandalf cards from Second Edition

This commit is contained in:
marcin.sciesinski
2019-09-03 21:55:49 -07:00
parent 079ac387ef
commit 86bd454ded
7 changed files with 323 additions and 11 deletions

View File

@@ -732,6 +732,32 @@
]
}
},
"40_84": {
"title": "Mysterious Wizard",
"culture": "gandalf",
"cost": 2,
"type": "event",
"keyword": [
"skirmish",
"spell"
],
"effects": {
"type": "event",
"effect": {
"type": "modifyStrength",
"filter": "choose(name(Gandalf))",
"amount": {
"type": "condition",
"condition": {
"type": "canSpotBurdens",
"amount": 5
},
"yes": 2,
"no": 4
}
}
}
},
"40_86": {
"title": "Protector of the West",
"culture": "gandalf",
@@ -759,6 +785,142 @@
]
}
},
"40_87": {
"title": "Roll of Thunder",
"culture": "gandalf",
"cost": 3,
"type": "event",
"keyword": [
"fellowship",
"maneuver"
],
"condition": {
"type": "canSpot",
"filter": "name(Gandalf)"
},
"effects": {
"type": "event",
"effect": {
"type": "discard",
"filter": "choose(side(shadow),or(possession,artifact))"
}
}
},
"40_88": {
"title": "Speak \"Friend\" and Enter",
"culture": "gandalf",
"cost": 1,
"type": "event",
"keyword": [
"fellowship",
"regroup"
],
"condition": {
"type": "canSpot",
"filter": "name(Gandalf)"
},
"effects": {
"type": "event",
"effect": [
{
"type": "playNextSite",
"memorize": "playedSite"
},
{
"type": "conditional",
"condition": {
"type": "memoryMatches",
"memory": "playedSite",
"filter": "underground"
},
"effect": {
"type": "drawCards"
}
}
]
}
},
"40_89": {
"title": "Trusted Advisor",
"culture": "gandalf",
"cost": 1,
"type": "event",
"keyword": "fellowship",
"condition": {
"type": "canSpot",
"filter": "name(Gandalf)"
},
"effects": {
"type": "event",
"cost": {
"type": "exert",
"filter": "choose(companion,not(culture(gandalf)))",
"memorize": "exertedCompanion"
},
"effect": {
"type": "putCardsFromDeckIntoHand",
"filter": "choose(cultureFromMemory(exertedCompanion))"
}
}
},
"40_90": {
"title": "A Wizard is Never Late",
"culture": "gandalf",
"cost": 1,
"type": "event",
"keyword": "fellowship",
"effects": {
"type": "event",
"effect": {
"type": "playCardFromDrawDeck",
"filter": "choose(culture(gandalf),character)"
}
}
},
"40_91": {
"title": "Wizard Staff",
"culture": "gandalf",
"cost": 2,
"type": "possession",
"possession": "hand weapon",
"strength": 1,
"target": "wizard",
"effects": {
"type": "activated",
"phase": "skirmish",
"cost": {
"type": "exert",
"filter": "choose(bearer)"
},
"effect": {
"type": "modifyStrength",
"filter": "choose(minion)",
"amount": -3
}
}
},
"40_311": {
"title": "*Gandalf",
"subtitle": "Wisest of the Istari",
"culture": "gandalf",
"cost": 4,
"type": "companion",
"race": "wizard",
"strength": 7,
"vitality": 4,
"resistance": 8,
"effects": {
"type": "trigger",
"trigger": {
"type": "played",
"filter": "culture(gandalf),spell"
},
"optional": true,
"effect": {
"type": "drawCards"
}
}
},
"40_312": {
"title": "Go Back to the Shadow!",
"culture": "gandalf",

View File

@@ -47,7 +47,9 @@ public class EffectAppenderFactory {
effectAppenderProducers.put("putcardsfromdiscardintohand", new PutCardsFromDiscardIntoHand());
effectAppenderProducers.put("addtrigger", new AddTrigger());
effectAppenderProducers.put("stackplayedevent", new StackPlayedEvent());
effectAppenderProducers.put("play", new PlayCardFromHand());
effectAppenderProducers.put("playcardfromdiscard", new PlayCardFromDiscard());
effectAppenderProducers.put("playcardfromdrawdeck", new PlayCardFromDrawDeck());
effectAppenderProducers.put("reducearcherytotal", new ReduceArcheryTotal());
effectAppenderProducers.put("revealtopcardsofdrawdeck", new RevealTopCardsOfDrawDeck());
effectAppenderProducers.put("optional", new Optional());
@@ -58,7 +60,6 @@ public class EffectAppenderFactory {
effectAppenderProducers.put("cantbeassignedtoskirmish", new CantBeAssignedToSkirmish());
effectAppenderProducers.put("preventable", new PreventableAppenderProducer());
effectAppenderProducers.put("cantbeoverwhelmedmultiplier", new CantBeOverwhelmedMultiplier());
effectAppenderProducers.put("play", new PlayCardFromHand());
effectAppenderProducers.put("cancelskirmish", new CancelSkirmish());
effectAppenderProducers.put("discardfromhand", new DiscardCardsFromHand());
effectAppenderProducers.put("chooseandremovetwilight", new ChooseAndRemoveTwilight());
@@ -74,6 +75,7 @@ public class EffectAppenderFactory {
effectAppenderProducers.put("revealrandomcardsfromhand", new RevealRandomCardsFromHand());
effectAppenderProducers.put("putcardsfromdeckintohand", new PutCardsFromDeckIntoHand());
effectAppenderProducers.put("addmodifier", new AddModifier());
effectAppenderProducers.put("playnextsite", new PlayNextSite());
}
public EffectAppender getEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {

View File

@@ -16,8 +16,11 @@ import com.gempukku.lotro.logic.effects.StackActionEffect;
import com.gempukku.lotro.logic.modifiers.ModifierFlag;
import com.gempukku.lotro.logic.modifiers.evaluator.ConstantEvaluator;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.UnrespondableEffect;
import org.json.simple.JSONObject;
import java.util.Collection;
public class PlayCardFromDiscard implements EffectAppenderProducer {
@Override
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
@@ -38,9 +41,18 @@ public class PlayCardFromDiscard implements EffectAppenderProducer {
new DelayedAppender() {
@Override
protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) {
final PhysicalCard cardToPlay = actionContext.getCardFromMemory("_temp");
final CostToEffectAction playCardAction = PlayUtils.getPlayCardAction(actionContext.getGame(), cardToPlay, 0, Filters.any, false);
return new StackActionEffect(playCardAction);
final Collection<? extends PhysicalCard> cardsToPlay = actionContext.getCardsFromMemory("_temp");
if (cardsToPlay.size() == 1) {
final CostToEffectAction playCardAction = PlayUtils.getPlayCardAction(actionContext.getGame(), cardsToPlay.iterator().next(), 0, Filters.any, false);
return new StackActionEffect(playCardAction);
} else {
return new UnrespondableEffect() {
@Override
protected void doPlayEffect(LotroGame game) {
// do nothing
}
};
}
}
@Override

View File

@@ -0,0 +1,71 @@
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.cards.build.field.effect.appender.resolver.CardResolver;
import com.gempukku.lotro.filters.Filters;
import com.gempukku.lotro.game.PhysicalCard;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.PlayUtils;
import com.gempukku.lotro.logic.actions.CostToEffectAction;
import com.gempukku.lotro.logic.effects.StackActionEffect;
import com.gempukku.lotro.logic.modifiers.ModifierFlag;
import com.gempukku.lotro.logic.modifiers.evaluator.ConstantEvaluator;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.UnrespondableEffect;
import org.json.simple.JSONObject;
import java.util.Collection;
public class PlayCardFromDrawDeck implements EffectAppenderProducer {
@Override
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(effectObject, "filter");
final String filter = FieldUtils.getString(effectObject.get("filter"), "filter");
MultiEffectAppender result = new MultiEffectAppender();
result.setPlayabilityCheckedForEffect(true);
result.addEffectAppender(
CardResolver.resolveCardsInDeck(filter,
(actionContext) -> Filters.playable(actionContext.getGame()),
(actionContext) -> Filters.playable(actionContext.getGame()),
new ConstantEvaluator(1), "_temp", "you", "Choose card to play", environment));
result.addEffectAppender(
new DelayedAppender() {
@Override
protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) {
final Collection<? extends PhysicalCard> cardsToPlay = actionContext.getCardsFromMemory("_temp");
if (cardsToPlay.size() == 1) {
final CostToEffectAction playCardAction = PlayUtils.getPlayCardAction(actionContext.getGame(), cardsToPlay.iterator().next(), 0, Filters.any, false);
return new StackActionEffect(playCardAction);
} else {
return new UnrespondableEffect() {
@Override
protected void doPlayEffect(LotroGame game) {
// do nothing
}
};
}
}
@Override
public boolean isPlayableInFull(ActionContext actionContext) {
final LotroGame game = actionContext.getGame();
return !game.getModifiersQuerying().hasFlagActive(game, ModifierFlag.CANT_PLAY_FROM_DISCARD_OR_DECK);
}
@Override
public boolean isPlayabilityCheckedForEffect() {
return true;
}
});
return result;
}
}

View File

@@ -9,13 +9,17 @@ import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer;
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.CardResolver;
import com.gempukku.lotro.filters.Filters;
import com.gempukku.lotro.game.PhysicalCard;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.PlayUtils;
import com.gempukku.lotro.logic.actions.CostToEffectAction;
import com.gempukku.lotro.logic.effects.StackActionEffect;
import com.gempukku.lotro.logic.modifiers.evaluator.ConstantEvaluator;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.UnrespondableEffect;
import org.json.simple.JSONObject;
import java.util.Collection;
public class PlayCardFromHand implements EffectAppenderProducer {
@Override
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
@@ -34,9 +38,18 @@ public class PlayCardFromHand implements EffectAppenderProducer {
new DelayedAppender() {
@Override
protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) {
final PhysicalCard cardToPlay = actionContext.getCardFromMemory("_temp");
final CostToEffectAction playCardAction = PlayUtils.getPlayCardAction(actionContext.getGame(), cardToPlay, 0, Filters.any, false);
return new StackActionEffect(playCardAction);
final Collection<? extends PhysicalCard> cardsToPlay = actionContext.getCardsFromMemory("_temp");
if (cardsToPlay.size() == 1) {
final CostToEffectAction playCardAction = PlayUtils.getPlayCardAction(actionContext.getGame(), cardsToPlay.iterator().next(), 0, Filters.any, false);
return new StackActionEffect(playCardAction);
} else {
return new UnrespondableEffect() {
@Override
protected void doPlayEffect(LotroGame game) {
// do nothing
}
};
}
}
});

View File

@@ -0,0 +1,46 @@
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.game.PhysicalCard;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.actions.CostToEffectAction;
import com.gempukku.lotro.logic.effects.PlayNextSiteEffect;
import com.gempukku.lotro.logic.timing.Effect;
import org.json.simple.JSONObject;
public class PlayNextSite implements EffectAppenderProducer {
@Override
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(effectObject, "memorize");
final String memorize = FieldUtils.getString(effectObject.get("memorize"), "memorize");
return new DelayedAppender() {
@Override
public boolean isPlayableInFull(ActionContext actionContext) {
final LotroGame game = actionContext.getGame();
final int currentSiteNumber = game.getGameState().getCurrentSiteNumber();
final PhysicalCard nextSite = game.getGameState().getSite(currentSiteNumber + 1);
return currentSiteNumber < 9
&& (nextSite == null || game.getModifiersQuerying().canReplaceSite(game, actionContext.getPerformingPlayer(), nextSite));
}
@Override
protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) {
return new PlayNextSiteEffect(action, actionContext.getPerformingPlayer()) {
@Override
protected void sitePlayedCallback(PhysicalCard site) {
if (memorize != null) {
actionContext.setCardMemory(memorize, site);
}
}
};
}
};
}
}

View File

@@ -5,12 +5,10 @@ import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolv
import com.gempukku.lotro.common.*;
import com.gempukku.lotro.filters.Filter;
import com.gempukku.lotro.filters.Filters;
import com.gempukku.lotro.game.PhysicalCard;
import com.gempukku.lotro.logic.timing.results.CharacterLostSkirmishResult;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.*;
public class FilterFactory {
private Map<String, FilterableSource> simpleFilters = new HashMap<>();
@@ -33,6 +31,7 @@ public class FilterFactory {
simpleFilters.put("self", (actionContext) -> actionContext.getSource());
simpleFilters.put("your", (actionContext) -> Filters.owner(actionContext.getPerformingPlayer()));
simpleFilters.put("bearer", (actionContext -> Filters.hasAttached(actionContext.getSource())));
simpleFilters.put("character", (actionContext) -> Filters.character);
simpleFilters.put("weapon", (actionContext) -> Filters.weapon);
simpleFilters.put("wounded", (actionContext) -> Filters.wounded);
simpleFilters.put("unwounded", (actionContext) -> Filters.unwounded);
@@ -54,6 +53,13 @@ public class FilterFactory {
return (actionContext) -> culture;
});
parameterFilters.put("cultureFromMemory", ((parameter, environment) -> actionContext -> {
Set<Culture> cultures = new HashSet<>();
for (PhysicalCard physicalCard : actionContext.getCardsFromMemory(parameter)) {
cultures.add(physicalCard.getBlueprint().getCulture());
}
return Filters.or(cultures.toArray(new Culture[0]));
}));
parameterFilters.put("side", (parameter, environment) -> {
final Side side = Side.valueOf(parameter.toUpperCase().replace(" ", "_"));
if (side == null)