Fixing Alatar/Pallando decieved not being pumped by Throne of Isengard
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
strength: 11
|
||||
vitality: 1
|
||||
keywords: fierce
|
||||
race: Wizard
|
||||
until: regroup
|
||||
}
|
||||
{
|
||||
@@ -97,6 +98,7 @@
|
||||
strength: 10
|
||||
vitality: 1
|
||||
keywords: fierce
|
||||
race: Wizard
|
||||
until: regroup
|
||||
}
|
||||
{
|
||||
|
||||
@@ -6,7 +6,6 @@ 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.common.Race;
|
||||
import com.gempukku.lotro.game.PhysicalCard;
|
||||
import com.gempukku.lotro.game.ReadableStringWhileInZoneData;
|
||||
import com.gempukku.lotro.game.state.LotroGame;
|
||||
@@ -30,7 +29,10 @@ public class StoreRaceFromCard implements EffectAppenderProducer {
|
||||
protected void doPlayEffect(LotroGame game) {
|
||||
PhysicalCard card = actionContext.getCardFromMemory(memory);
|
||||
if (card != null) {
|
||||
Race race = card.getBlueprint().getRace();
|
||||
var races = game.getModifiersQuerying().getRaces(game, card);
|
||||
if(races.isEmpty())
|
||||
return;
|
||||
var race = races.getFirst();
|
||||
actionContext.getSource().setWhileInZoneData(new ReadableStringWhileInZoneData(race.name(), race.getHumanReadable()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.gempukku.lotro.cards.build.field.effect.appender.resolver.TimeResolve
|
||||
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver;
|
||||
import com.gempukku.lotro.common.CardType;
|
||||
import com.gempukku.lotro.common.Keyword;
|
||||
import com.gempukku.lotro.common.Race;
|
||||
import com.gempukku.lotro.common.Zone;
|
||||
import com.gempukku.lotro.filters.Filters;
|
||||
import com.gempukku.lotro.game.AbstractActionProxy;
|
||||
@@ -34,7 +35,7 @@ import java.util.List;
|
||||
public class TurnIntoMinion implements EffectAppenderProducer {
|
||||
@Override
|
||||
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
|
||||
FieldUtils.validateAllowedFields(effectObject, "select", "count", "strength", "vitality", "keywords", "until", "memorize");
|
||||
FieldUtils.validateAllowedFields(effectObject, "select", "count", "strength", "vitality", "keywords", "race", "until", "memorize");
|
||||
|
||||
final String select = FieldUtils.getString(effectObject.get("select"), "select", "choose(any)");
|
||||
final ValueSource valueSource = ValueResolver.resolveEvaluator(effectObject.get("count"), 1, environment);
|
||||
@@ -42,6 +43,7 @@ public class TurnIntoMinion implements EffectAppenderProducer {
|
||||
final ValueSource vitality = ValueResolver.resolveEvaluator(effectObject.get("vitality"), environment);
|
||||
final String[] keywordStrings = FieldUtils.getStringArray(effectObject.get("keywords"), "keywords");
|
||||
final TimeResolver.Time until = TimeResolver.resolveTime(effectObject.get("until"), "end(current)");
|
||||
final Race race = FieldUtils.getEnum(Race.class, effectObject.get("race"), "race");
|
||||
|
||||
String memory = FieldUtils.getString(effectObject.get("memorize"), "memorize", "_temp");
|
||||
|
||||
@@ -75,6 +77,9 @@ public class TurnIntoMinion implements EffectAppenderProducer {
|
||||
addModifier(action, new StrengthModifier(card, card, null, strengthValue), until);
|
||||
addModifier(action, new VitalityModifier(card, card, null, vitalityValue), until);
|
||||
addModifier(action, new IsAdditionalCardTypeModifier(card, card, null, CardType.MINION), until);
|
||||
if(race != null) {
|
||||
addModifier(action, new IsAdditionalRaceModifier(card, card, null, race), until);
|
||||
}
|
||||
|
||||
for (Keyword keyword : keywordsList) {
|
||||
addModifier(action, new AddKeywordModifier(card, card, null, keyword), until);
|
||||
|
||||
@@ -14,11 +14,8 @@ import com.gempukku.lotro.logic.modifiers.evaluator.Evaluator;
|
||||
import com.gempukku.lotro.logic.modifiers.evaluator.SingleMemoryEvaluator;
|
||||
import com.gempukku.lotro.logic.timing.Effect;
|
||||
import com.gempukku.lotro.logic.timing.results.CharacterLostSkirmishResult;
|
||||
import com.google.common.base.Predicates;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class FilterFactory {
|
||||
private final Map<String, FilterableSource> simpleFilters = new HashMap<>();
|
||||
@@ -111,7 +108,7 @@ public class FilterFactory {
|
||||
return Filters.none;
|
||||
}));
|
||||
simpleFilters.put("hasrace",
|
||||
(actionContext -> (Filter) (game, physicalCard) -> physicalCard.getBlueprint().getRace() != null));
|
||||
(actionContext -> (Filter) (game, physicalCard) -> !game.getModifiersQuerying().getRaces(game, physicalCard).isEmpty()));
|
||||
simpleFilters.put("idinstored",
|
||||
(actionContext ->
|
||||
(Filter) (game, physicalCard) -> {
|
||||
@@ -337,12 +334,12 @@ public class FilterFactory {
|
||||
(parameter, environment) -> {
|
||||
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
||||
return actionContext -> {
|
||||
var game = actionContext.getGame();
|
||||
final Filterable sourceFilterable = filterableSource.getFilterable(actionContext);
|
||||
|
||||
Map<Race, Integer> counts = new HashMap<>();
|
||||
for (PhysicalCard card : Filters.filterActive(actionContext.getGame(), sourceFilterable)) {
|
||||
final Race race = card.getBlueprint().getRace();
|
||||
if (race != null) {
|
||||
for(var race : game.getModifiersQuerying().getRaces(game, card)) {
|
||||
Integer count = counts.get(race);
|
||||
if (count == null)
|
||||
count = 0;
|
||||
@@ -572,23 +569,31 @@ public class FilterFactory {
|
||||
if (parameter.startsWith("memory(") && parameter.endsWith(")")) {
|
||||
return actionContext -> (Filter) (game, physicalCard) -> {
|
||||
String memory = parameter.substring(parameter.indexOf("(") + 1, parameter.lastIndexOf(")"));
|
||||
Set<Race> races = actionContext.getCardsFromMemory(memory).stream().map(
|
||||
(Function<PhysicalCard, Race>) cardFromMemory -> cardFromMemory.getBlueprint().getRace()).filter(Predicates.notNull()).collect(Collectors.toSet());
|
||||
return races.contains(physicalCard.getBlueprint().getRace());
|
||||
var races = new HashSet<Race>();
|
||||
for(var memoryCard : actionContext.getCardsFromMemory(memory)) {
|
||||
races.addAll(game.getModifiersQuerying().getRaces(game, memoryCard));
|
||||
}
|
||||
//Disjoint returns true if there are no elements in common between two collections
|
||||
return !Collections.disjoint(races, game.getModifiersQuerying().getRaces(game, physicalCard));
|
||||
};
|
||||
} else if (parameter.equals("stored")) {
|
||||
return actionContext -> (Filter) (game, physicalCard) -> {
|
||||
final PhysicalCard.WhileInZoneData value = actionContext.getSource().getWhileInZoneData();
|
||||
if (value != null)
|
||||
return Race.valueOf(value.getValue()) == physicalCard.getBlueprint().getRace();
|
||||
return game.getModifiersQuerying().getRaces(game, physicalCard).contains(Race.valueOf(value.getValue()));
|
||||
return false;
|
||||
};
|
||||
} else if (parameter.equals("cannotspot")) {
|
||||
return actionContext -> (Filter) (game, physicalCard) -> {
|
||||
final Race race = physicalCard.getBlueprint().getRace();
|
||||
if (race != null)
|
||||
return !Filters.canSpot(game, race);
|
||||
return false;
|
||||
var races = game.getModifiersQuerying().getRaces(game, physicalCard);
|
||||
if(races.isEmpty())
|
||||
return false;
|
||||
|
||||
for(var race : races) {
|
||||
if(Filters.canSpot(game, race))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
throw new InvalidCardDefinitionException("Unknown race definition in filter: " + parameter
|
||||
|
||||
@@ -417,10 +417,7 @@ public class Filters {
|
||||
private static Filter race(final Race race) {
|
||||
return Filters.and(
|
||||
Filters.or(CardType.COMPANION, CardType.ALLY, CardType.MINION, CardType.FOLLOWER),
|
||||
(Filter) (game, physicalCard) -> {
|
||||
LotroCardBlueprint blueprint = physicalCard.getBlueprint();
|
||||
return blueprint.getRace() == race;
|
||||
});
|
||||
(Filter) (game, physicalCard) -> game.getModifiersQuerying().isRace(game, physicalCard, race));
|
||||
}
|
||||
|
||||
|
||||
@@ -572,8 +569,7 @@ public class Filters {
|
||||
}
|
||||
|
||||
private static Filter type(final CardType cardType) {
|
||||
return (game, physicalCard) -> (physicalCard.getBlueprint().getCardType() == cardType)
|
||||
|| game.getModifiersQuerying().isAdditionalCardType(game, physicalCard, cardType);
|
||||
return (game, physicalCard) -> game.getModifiersQuerying().isCardType(game, physicalCard, cardType);
|
||||
}
|
||||
|
||||
public static Filter attachedTo(final Filterable... filters) {
|
||||
|
||||
@@ -308,9 +308,7 @@ public class GameUtils {
|
||||
public static int getSpottableRacesCount(LotroGame game, Filterable... filters) {
|
||||
Set<Race> races = new HashSet<>();
|
||||
for (PhysicalCard physicalCard : Filters.filterActive(game, filters)) {
|
||||
final Race race = physicalCard.getBlueprint().getRace();
|
||||
if (race != null)
|
||||
races.add(race);
|
||||
races.addAll(game.getModifiersQuerying().getRaces(game, physicalCard));
|
||||
}
|
||||
return races.size();
|
||||
}
|
||||
|
||||
@@ -124,6 +124,11 @@ public abstract class AbstractModifier implements Modifier {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdditionalRaceModifier(LotroGame game, PhysicalCard physicalCard, Race race) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTwilightCostModifier(LotroGame game, PhysicalCard physicalCard, PhysicalCard target, boolean ignoreRoamingPenalty) {
|
||||
return 0;
|
||||
|
||||
@@ -319,6 +319,11 @@ public class DelegateModifier implements Modifier {
|
||||
return delegate.isAdditionalCardTypeModifier(game, physicalCard, cardType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdditionalRaceModifier(LotroGame game, PhysicalCard physicalCard, Race race) {
|
||||
return delegate.isAdditionalRaceModifier(game, physicalCard, race);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllyParticipateInArcheryFire(LotroGame game, PhysicalCard card) {
|
||||
return delegate.isAllyParticipateInArcheryFire(game, card);
|
||||
|
||||
@@ -17,4 +17,8 @@ public class IsAdditionalCardTypeModifier extends AbstractModifier {
|
||||
public boolean isAdditionalCardTypeModifier(LotroGame game, PhysicalCard physicalCard, CardType cardType) {
|
||||
return cardType == _cardType;
|
||||
}
|
||||
|
||||
public CardType getType() {
|
||||
return _cardType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.gempukku.lotro.logic.modifiers;
|
||||
|
||||
import com.gempukku.lotro.common.Filterable;
|
||||
import com.gempukku.lotro.common.Race;
|
||||
import com.gempukku.lotro.game.PhysicalCard;
|
||||
import com.gempukku.lotro.game.state.LotroGame;
|
||||
|
||||
public class IsAdditionalRaceModifier extends AbstractModifier {
|
||||
private final Race _race;
|
||||
|
||||
public IsAdditionalRaceModifier(PhysicalCard source, Filterable affectFilter, Condition condition, Race race) {
|
||||
super(source, "Has additional race - " + race.toString(), affectFilter, condition, ModifierEffect.ADDITIONAL_RACE);
|
||||
_race = race;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdditionalRaceModifier(LotroGame game, PhysicalCard physicalCard, Race race) {
|
||||
return race == _race;
|
||||
}
|
||||
|
||||
public Race getRace() {
|
||||
return _race;
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,7 @@ public interface Modifier {
|
||||
int getMinionSiteNumberModifier(LotroGame game, PhysicalCard physicalCard);
|
||||
|
||||
boolean isAdditionalCardTypeModifier(LotroGame game, PhysicalCard physicalCard, CardType cardType);
|
||||
boolean isAdditionalRaceModifier(LotroGame game, PhysicalCard physicalCard, Race race);
|
||||
|
||||
int getTwilightCostModifier(LotroGame game, PhysicalCard physicalCard, PhysicalCard target, boolean ignoreRoamingPenalty);
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ public enum ModifierEffect {
|
||||
|
||||
SPECIAL_FLAG_MODIFIER, REPLACE_SITE_MODIFIER, PLAY_SITE_MODIFIER,
|
||||
|
||||
ADDITIONAL_CARD_TYPE,
|
||||
ADDITIONAL_CARD_TYPE, ADDITIONAL_RACE,
|
||||
|
||||
REMOVE_KEYWORD_MODIFIER, GIVE_KEYWORD_MODIFIER, CANCEL_KEYWORD_BONUS_TARGET_MODIFIER, LOSE_ALL_KEYWORDS_MODIFIER,
|
||||
|
||||
|
||||
@@ -531,11 +531,44 @@ public class ModifiersLogic implements ModifiersEnvironment, ModifiersQuerying {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdditionalCardType(LotroGame game, PhysicalCard card, CardType cardType) {
|
||||
for (Modifier modifier : getModifiersAffectingCard(game, ModifierEffect.ADDITIONAL_CARD_TYPE, card))
|
||||
if (modifier.isAdditionalCardTypeModifier(game, card, cardType))
|
||||
return true;
|
||||
return false;
|
||||
public List<CardType> getCardTypes(LotroGame game, PhysicalCard card) {
|
||||
var types = new ArrayList<CardType>();
|
||||
types.add(card.getBlueprint().getCardType());
|
||||
for (Modifier modifier : getModifiersAffectingCard(game, ModifierEffect.ADDITIONAL_CARD_TYPE, card)) {
|
||||
var cardTypeMod = (IsAdditionalCardTypeModifier)modifier;
|
||||
types.add(cardTypeMod.getType());
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCardType(LotroGame game, PhysicalCard card, CardType cardType) {
|
||||
var types = getCardTypes(game, card);
|
||||
return types.contains(cardType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public List<Race> getRaces(LotroGame game, PhysicalCard card) {
|
||||
var races = new ArrayList<Race>();
|
||||
if(card.getBlueprint().getRace() != null) {
|
||||
races.add(card.getBlueprint().getRace());
|
||||
}
|
||||
|
||||
for (Modifier modifier : getModifiersAffectingCard(game, ModifierEffect.ADDITIONAL_RACE, card)) {
|
||||
var cardTypeMod = (IsAdditionalRaceModifier)modifier;
|
||||
races.add(cardTypeMod.getRace());
|
||||
}
|
||||
|
||||
return races;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRace(LotroGame game, PhysicalCard card, Race race) {
|
||||
var races = getRaces(game, card);
|
||||
return races.contains(race);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -68,7 +68,10 @@ public interface ModifiersQuerying {
|
||||
|
||||
int getOverwhelmMultiplier(LotroGame game, PhysicalCard card);
|
||||
|
||||
boolean isAdditionalCardType(LotroGame game, PhysicalCard card, CardType cardType);
|
||||
List<CardType> getCardTypes(LotroGame game, PhysicalCard card);
|
||||
boolean isCardType(LotroGame game, PhysicalCard card, CardType cardType);
|
||||
List<Race> getRaces(LotroGame game, PhysicalCard card);
|
||||
boolean isRace(LotroGame game, PhysicalCard card, Race race);
|
||||
|
||||
// Wounds/exertions
|
||||
boolean canTakeWounds(LotroGame game, Collection<PhysicalCard> woundSources, PhysicalCard card, int woundsToTake);
|
||||
|
||||
@@ -170,7 +170,7 @@ public class GameStats {
|
||||
newCharStrengths.put(character.getCardId(), game.getModifiersQuerying().getStrength(game, character));
|
||||
newCharVitalities.put(character.getCardId(), game.getModifiersQuerying().getVitality(game, character));
|
||||
final LotroCardBlueprint blueprint = character.getBlueprint();
|
||||
if (blueprint.getCardType() == CardType.MINION || game.getModifiersQuerying().isAdditionalCardType(game, character, CardType.MINION))
|
||||
if (blueprint.getCardType() == CardType.MINION || game.getModifiersQuerying().isCardType(game, character, CardType.MINION))
|
||||
newSiteNumbers.put(character.getCardId(), game.getModifiersQuerying().getMinionSiteNumber(game, character));
|
||||
else {
|
||||
final int resistance = game.getModifiersQuerying().getResistance(game, character);
|
||||
|
||||
@@ -1021,8 +1021,12 @@ public class GenericCardTestHelper extends AbstractAtTest {
|
||||
|
||||
public boolean IsType(PhysicalCardImpl card, CardType type)
|
||||
{
|
||||
return card.getBlueprint().getCardType() == type
|
||||
|| _game.getModifiersQuerying().isAdditionalCardType(_game, card, type);
|
||||
return _game.getModifiersQuerying().isCardType(_game, card, type);
|
||||
}
|
||||
|
||||
public boolean IsRace(PhysicalCardImpl card, Race race)
|
||||
{
|
||||
return _game.getModifiersQuerying().isRace(_game, card, race);
|
||||
}
|
||||
|
||||
public Boolean CanBeAssigned(PhysicalCardImpl card)
|
||||
|
||||
@@ -17,8 +17,9 @@ public class Card_13_079_Tests
|
||||
return new GenericCardTestHelper(
|
||||
new HashMap<>()
|
||||
{{
|
||||
put("card", "13_79");
|
||||
// put other cards in here as needed for the test case
|
||||
put("pallando", "13_79");
|
||||
put("throne", "17_39");
|
||||
put("saruman", "4_173");
|
||||
}},
|
||||
GenericCardTestHelper.FellowshipSites,
|
||||
GenericCardTestHelper.FOTRFrodo,
|
||||
@@ -43,7 +44,7 @@ public class Card_13_079_Tests
|
||||
|
||||
var scn = GetScenario();
|
||||
|
||||
var card = scn.GetFreepsCard("card");
|
||||
var card = scn.GetFreepsCard("pallando");
|
||||
|
||||
assertEquals("Pallando Deceived", card.getBlueprint().getTitle());
|
||||
assertNull(card.getBlueprint().getSubtitle());
|
||||
@@ -55,18 +56,25 @@ public class Card_13_079_Tests
|
||||
assertEquals(3, card.getBlueprint().getTwilightCost());
|
||||
}
|
||||
|
||||
// Uncomment any @Test markers below once this is ready to be used
|
||||
//@Test
|
||||
public void PallandoDeceivedTest1() throws DecisionResultInvalidException, CardNotFoundException {
|
||||
@Test
|
||||
public void PallandoDeceivedIsPumpedByThroneOfIsengardAfterConversion() throws DecisionResultInvalidException, CardNotFoundException {
|
||||
//Pre-game setup
|
||||
var scn = GetScenario();
|
||||
|
||||
var card = scn.GetFreepsCard("card");
|
||||
scn.FreepsMoveCardToHand(card);
|
||||
var pallando = scn.GetShadowCard("pallando");
|
||||
var throne = scn.GetShadowCard("throne");
|
||||
var saruman = scn.GetShadowCard("saruman");
|
||||
scn.ShadowMoveCardToSupportArea(pallando, throne);
|
||||
scn.ShadowMoveCharToTable(saruman);
|
||||
|
||||
scn.StartGame();
|
||||
scn.FreepsPlayCard(card);
|
||||
|
||||
assertEquals(3, scn.GetTwilight());
|
||||
scn.SkipToPhase(Phase.MANEUVER);
|
||||
|
||||
assertTrue(scn.ShadowHasOptionalTriggerAvailable());
|
||||
scn.ShadowAcceptOptionalTrigger();
|
||||
|
||||
//10 base +3 from throne making Wizards stronger
|
||||
assertEquals(13, scn.getStrength(pallando));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user