4 Fellowship companions

This commit is contained in:
marcin.sciesinski
2019-08-27 12:02:17 -07:00
parent 4cdcbb6abf
commit 33ce5436a5
7 changed files with 220 additions and 1 deletions

View File

@@ -119,6 +119,26 @@
}
}
},
"1_30": {
"title": "Arwen",
"subtitle": "Daughter of Elrond",
"unique": true,
"side": "free people",
"culture": "elven",
"cost": 2,
"type": "companion",
"race": "elf",
"strength": 6,
"vitality": 3,
"resistance": 6,
"signet": "aragorn",
"keyword": "ranger",
"effects": {
"type": "modifyStrength",
"amount": 3,
"filter": "self,inSkirmishAgainst(nazgul)"
}
},
"1_38": {
"title": "Double Shot",
"side": "free people",
@@ -139,6 +159,64 @@
}
}
},
"1_48": {
"title": "Haldir",
"subtitle": "Elf of the Golden Wood",
"unique": true,
"side": "free people",
"culture": "elven",
"cost": 2,
"type": "companion",
"race": "elf",
"strength": 5,
"vitality": 3,
"resistance": 6,
"requirement": {
"type": "canSpot",
"filter": "elf"
},
"effects": {
"type": "modifyStrength",
"amount": 2,
"condition": {
"type": "location",
"filter": "siteBlock(fellowship),or(siteNumber(6),siteNumber(7),siteNumber(8))"
}
}
},
"1_50": {
"title": "Legolas",
"subtitle": "Greenleaf",
"unique": true,
"side": "free people",
"culture": "elven",
"cost": 2,
"type": "companion",
"race": "elf",
"strength": 6,
"vitality": 3,
"resistance": 6,
"signet": "frodo",
"keyword": "archer",
"effects": {
"type": "activated",
"phase": "archery",
"cost": {
"type": "exert",
"filter": "self"
},
"effect": [
{
"type": "wound",
"filter": "choose(minion)"
},
{
"type": "doesNotAddToArcheryTotal",
"filter": "self"
}
]
}
},
"1_51": {
"title": "Legolas",
"subtitle": "Prince of Mirkwood",
@@ -159,6 +237,21 @@
"amount": 3
}
},
"1_53": {
"title": "Lorien Elf",
"side": "free people",
"culture": "elven",
"cost": 1,
"type": "companion",
"race": "elf",
"strength": 4,
"vitality": 2,
"resistance": 6,
"requirement": {
"type": "canSpot",
"filter": "elf"
}
},
"1_94": {
"title": "Athelas",
"side": "free people",

View File

@@ -31,6 +31,7 @@ public class EffectAppenderFactory {
effectAppenderProducers.put("choice", new Choice());
effectAppenderProducers.put("assigntoskirmishagainstminion", new AssignToSkirmishAgainstMinion());
effectAppenderProducers.put("putcardfromhandonbottomofdeck", new PutCardFromHandOnBottomOfDeck());
effectAppenderProducers.put("doesnotaddtoarcherytotal", new DoesNotAddToArcheryTotal());
}
public EffectAppender getEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {

View File

@@ -0,0 +1,68 @@
package com.gempukku.lotro.cards.build.field.effect.appender;
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.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.cards.build.field.effect.appender.resolver.CountResolver;
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.AddUntilEndOfPhaseModifierEffect;
import com.gempukku.lotro.logic.modifiers.DoesNotAddToArcheryTotalModifier;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.EffectResult;
import com.gempukku.lotro.logic.timing.PlayConditions;
import org.json.simple.JSONObject;
import java.util.Collection;
public class DoesNotAddToArcheryTotal implements EffectAppenderProducer {
@Override
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(effectObject, "count", "filter", "memory");
final CountResolver.Count count = CountResolver.resolveCount(effectObject.get("count"), 1);
final String filter = FieldUtils.getString(effectObject.get("filter"), "filter");
final String memory = FieldUtils.getString(effectObject.get("memory"), "memory", "_temp");
MultiEffectAppender result = new MultiEffectAppender();
result.addEffectAppender(
CardResolver.resolveCards(filter,
count.getMin(), count.getMax(), memory, "owner", "Choose cards to make not add to archery total", environment));
result.addEffectAppender(
new DelayedAppender() {
@Override
protected Effect createEffect(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) {
final Collection<? extends PhysicalCard> cardsFromMemory = action.getCardsFromMemory(memory);
return new AddUntilEndOfPhaseModifierEffect(
new DoesNotAddToArcheryTotalModifier(self, Filters.in(cardsFromMemory)));
}
});
return result;
}
@Override
public Requirement createCostRequirement(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(effectObject, "count", "filter", "memory");
final CountResolver.Count count = CountResolver.resolveCount(effectObject.get("count"), 1);
final String type = FieldUtils.getString(effectObject.get("filter"), "filter");
if (type.startsWith("choose(") && type.endsWith(")")) {
final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")"));
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter);
return (playerId, game, self, effectResult, effect) -> PlayConditions.isActive(game, count.getMin(),
filterableSource.getFilterable(playerId, game, self, effectResult, effect));
}
return null;
}
}

View File

@@ -93,6 +93,30 @@ public class FilterFactory {
int number = Integer.parseInt(parameterSplit[1]);
return Filters.and(Filters.siteBlock(sitesBlock), Filters.siteNumber(number));
});
parameterFilters.put("siteBlock",
(parameter, filterFactory) -> {
final SitesBlock sitesBlock = Enum.valueOf(SitesBlock.class, parameter.toUpperCase().replace(' ', '_'));
return (playerId, game, source, effectResult, effect) -> Filters.siteBlock(sitesBlock);
});
parameterFilters.put("siteNumber",
(parameter, filterFactory) -> {
int number = Integer.parseInt(parameter);
return (playerId, game, source, effectResult, effect) -> Filters.siteNumber(number);
});
parameterFilters.put("or",
(parameter, filterFactory) -> {
final String[] filters = splitIntoFilters(parameter);
FilterableSource[] filterables = new FilterableSource[filters.length];
for (int i = 0; i < filters.length; i++)
filterables[i] = filterFactory.generateFilter(filters[i]);
return (playerId, game, source, effectResult, effect) -> {
Filterable[] filters1 = new Filterable[filterables.length];
for (int i = 0; i < filterables.length; i++)
filters1[i] = filterables[i].getFilterable(playerId, game, source, effectResult, effect);
return Filters.or(filters1);
};
});
}
private void appendFilter(Filterable value) {

View File

@@ -0,0 +1,28 @@
package com.gempukku.lotro.cards.build.field.effect.requirement;
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.Requirement;
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 org.json.simple.JSONObject;
public class Location implements RequirementProducer {
@Override
public Requirement getPlayRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(object, "filter");
final String filter = FieldUtils.getString(object.get("filter"), "filter");
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter);
return (playerId, game, self, effectResult, effect) -> {
final Filterable filterable = filterableSource.getFilterable(playerId, game, self, effectResult, effect);
final PhysicalCard currentSite = game.getGameState().getCurrentSite();
return Filters.and(filterable).accepts(game, currentSite);
};
}
}

View File

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

View File

@@ -234,7 +234,11 @@ public class PlayConditions {
}
public static boolean isActive(LotroGame game, Filterable... filters) {
return Filters.countActive(game, filters) > 0;
return isActive(game, 1, filters);
}
public static boolean isActive(LotroGame game, int count, Filterable... filters) {
return Filters.countActive(game, filters) >= count;
}
public static boolean canSpot(LotroGame game, int count, Filterable... filters) {