Fixes to errors reported in-game

This commit is contained in:
marcin.sciesinski
2019-08-28 09:07:28 -07:00
parent c5dd0b77c0
commit 1b51e1ba43
12 changed files with 276 additions and 4 deletions

View File

@@ -1,4 +1,57 @@
{
"40_1": {
"title": "The One Ring",
"subtitle": "Doom of Free Peoples",
"unique": true,
"type": "the one ring",
"strength": 1,
"vitality": 1,
"resistance": 1,
"effects": [
{
"type": "trigger",
"requirement": {
"type": "ringIsOn"
},
"trigger": {
"type": "aboutToTakeWound",
"filter": "hasAttached(self)"
},
"effect": [
{
"type": "negateWound",
"filter": "all(hasAttached(self))"
},
{
"type": "addBurden"
}
]
},
{
"type": "activated",
"phase": "maneuver",
"cost": {
"type": "choice",
"texts": [
"Exert bearer",
"Discard a card at random"
],
"effects": [
{
"type": "exert",
"filter": "choose(hasAttached(self))"
},
{
"type": "discardCardAtRandomFromHand"
}
]
},
"effect": {
"type": "putOnRing"
}
}
]
},
"40_3": {
"title": "Balin's Lament",
"unique": true,

View File

@@ -32,6 +32,9 @@ public class EffectAppenderFactory {
effectAppenderProducers.put("assigntoskirmishagainstminion", new AssignToSkirmishAgainstMinion());
effectAppenderProducers.put("putcardfromhandonbottomofdeck", new PutCardFromHandOnBottomOfDeck());
effectAppenderProducers.put("doesnotaddtoarcherytotal", new DoesNotAddToArcheryTotal());
effectAppenderProducers.put("negatewound", new NegateWound());
effectAppenderProducers.put("discardcardatrandomfromhand", new DiscardCardAtRandomFromHand());
effectAppenderProducers.put("putonring", new PutOnRing());
}
public EffectAppender getEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {

View File

@@ -23,7 +23,7 @@ public class AddBurden implements EffectAppenderProducer {
FieldUtils.validateAllowedFields(effectObject, "amount", "player");
final int amount = FieldUtils.getInteger(effectObject.get("amount"), "amount", 1);
final String player = FieldUtils.getString(effectObject.get("player"), "player");
final String player = FieldUtils.getString(effectObject.get("player"), "player", "owner");
final PlayerSource playerSource = PlayerResolver.resolvePlayer(player, environment);

View File

@@ -0,0 +1,40 @@
package com.gempukku.lotro.cards.build.field.effect.appender;
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.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.DiscardCardAtRandomFromHandEffect;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.EffectResult;
import org.json.simple.JSONObject;
public class DiscardCardAtRandomFromHand implements EffectAppenderProducer {
@Override
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(effectObject);
return new AbstractEffectAppender() {
@Override
protected Effect createEffect(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) {
return new DiscardCardAtRandomFromHandEffect(self, self.getOwner(), false);
}
@Override
public boolean isPlayableInFull(String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) {
return game.getGameState().getDeck(self.getOwner()).size() >= 1;
}
};
}
@Override
public Requirement createCostRequirement(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(effectObject);
return (playerId, game, self, effectResult, effect) -> game.getGameState().getDeck(self.getOwner()).size() >= 1;
}
}

View File

@@ -0,0 +1,60 @@
package com.gempukku.lotro.cards.build.field.effect.appender;
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.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.actions.CostToEffectAction;
import com.gempukku.lotro.logic.effects.NegateWoundEffect;
import com.gempukku.lotro.logic.effects.WoundCharactersEffect;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.EffectResult;
import org.json.simple.JSONObject;
import java.util.Collection;
public class NegateWound 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", "all(any)");
MultiEffectAppender result = new MultiEffectAppender();
result.addEffectAppender(
CardResolver.resolveCards(filter,
(playerId, game, source, effectResult, effect) -> {
final WoundCharactersEffect woundEffect = (WoundCharactersEffect) effect;
return Filters.in(woundEffect.getAffectedCardsMinusPrevented(game));
}, 1, 1, "_temp", "owner", "Choose characters to negate wound to", environment));
result.addEffectAppender(
new AbstractEffectAppender() {
@Override
protected Effect createEffect(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) {
final Collection<? extends PhysicalCard> cards = action.getCardsFromMemory("_temp");
final WoundCharactersEffect woundEffect = (WoundCharactersEffect) effect;
return new NegateWoundEffect(woundEffect, Filters.in(cards));
}
@Override
public boolean isPlayableInFull(String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) {
return true;
}
});
return result;
}
@Override
public Requirement createCostRequirement(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
return null;
}
}

View File

@@ -41,8 +41,7 @@ public class PutCardFromHandOnBottomOfDeck implements EffectAppenderProducer {
}
});
return null;
return result;
}
@Override

View File

@@ -0,0 +1,38 @@
package com.gempukku.lotro.cards.build.field.effect.appender;
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.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.PutOnTheOneRingEffect;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.EffectResult;
import org.json.simple.JSONObject;
public class PutOnRing implements EffectAppenderProducer {
@Override
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(effectObject);
return new AbstractEffectAppender() {
@Override
protected Effect createEffect(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) {
return new PutOnTheOneRingEffect();
}
@Override
public boolean isPlayableInFull(String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) {
return !game.getGameState().isWearingRing();
}
};
}
@Override
public Requirement createCostRequirement(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
return (playerId, game, self, effectResult, effect) -> !game.getGameState().isWearingRing();
}
}

View File

@@ -116,6 +116,26 @@ public class CardResolver {
};
}
};
} else if (type.startsWith("all(") && type.endsWith(")")) {
final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")"));
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter);
return new AbstractEffectAppender() {
@Override
protected Effect createEffect(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) {
return new UnrespondableEffect() {
@Override
protected void doPlayEffect(LotroGame game) {
final Filterable filterable = filterableSource.getFilterable(playerId, game, self, effectResult, effect);
action.setCardMemory(memory, Filters.filterActive(game, filterable));
}
};
}
@Override
public boolean isPlayableInFull(String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) {
return true;
}
};
} else if (type.startsWith("choose(") && type.endsWith(")")) {
final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")"));
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter);
@@ -146,6 +166,6 @@ public class CardResolver {
}
};
}
throw new RuntimeException("Unable to resolve card resolver of type: " + type);
throw new InvalidCardDefinitionException("Unable to resolve card resolver of type: " + type);
}
}

View File

@@ -18,6 +18,7 @@ public class RequirementFactory {
requirementProducers.put("controlssite", new ControlsSite());
requirementProducers.put("twilightpoollessthan", new TwilightPoolLessThan());
requirementProducers.put("location", new Location());
requirementProducers.put("ringison", new RingIsOn());
}
public Requirement getRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {

View File

@@ -0,0 +1,13 @@
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 org.json.simple.JSONObject;
public class RingIsOn implements RequirementProducer {
@Override
public Requirement getPlayRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
return (playerId, game, self, effectResult, effect) -> game.getGameState().isWearingRing();
}
}

View File

@@ -0,0 +1,44 @@
package com.gempukku.lotro.cards.build.field.effect.trigger;
import com.gempukku.lotro.cards.build.CardGenerationEnvironment;
import com.gempukku.lotro.cards.build.FilterableSource;
import com.gempukku.lotro.cards.build.InvalidCardDefinitionException;
import com.gempukku.lotro.cards.build.field.FieldUtils;
import com.gempukku.lotro.common.Filterable;
import com.gempukku.lotro.filters.Filters;
import com.gempukku.lotro.game.PhysicalCard;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.EffectResult;
import com.gempukku.lotro.logic.timing.TriggerConditions;
import org.json.simple.JSONObject;
public class AboutToTakeWound implements TriggerCheckerProducer {
@Override
public TriggerChecker getTriggerChecker(JSONObject value, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(value, "source", "filter");
String source = FieldUtils.getString(value.get("source"), "source", "any");
String filter = FieldUtils.getString(value.get("filter"), "source");
final FilterableSource sourceFilter = environment.getFilterFactory().generateFilter(source);
final FilterableSource affectedFilter = environment.getFilterFactory().generateFilter(filter);
return new TriggerChecker() {
@Override
public boolean accepts(String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) {
final Filterable sourceFilterable = sourceFilter.getFilterable(playerId, game, self, effectResult, effect);
final Filterable affected = affectedFilter.getFilterable(playerId, game, self, effectResult, effect);
if (sourceFilterable == Filters.any)
return TriggerConditions.isGettingWounded(effect, game, affected);
else
return TriggerConditions.isGettingWoundedBy(effect, game, sourceFilterable, affected);
}
@Override
public boolean isBefore() {
return true;
}
};
}
}

View File

@@ -17,6 +17,7 @@ public class TriggerCheckerFactory {
triggerCheckers.put("losesskirmish", new LosesSkirmish());
triggerCheckers.put("winsskirmish", new WinsSkirmish());
triggerCheckers.put("startofturn", new StartOfTurn());
triggerCheckers.put("abouttotakewound", new AboutToTakeWound());
}
public TriggerChecker getTriggerChecker(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {