mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 18:58:00 +00:00
Merge branch 'master' of https://git.cardforge.org/core-developers/forge.git
This commit is contained in:
@@ -2079,8 +2079,7 @@ public class AiController {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReplacementEffect chooseSingleReplacementEffect(List<ReplacementEffect> list,
|
public ReplacementEffect chooseSingleReplacementEffect(List<ReplacementEffect> list) {
|
||||||
Map<String, Object> runParams) {
|
|
||||||
// no need to choose anything
|
// no need to choose anything
|
||||||
if (list.size() <= 1) {
|
if (list.size() <= 1) {
|
||||||
return Iterables.getFirst(list, null);
|
return Iterables.getFirst(list, null);
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import forge.card.MagicColor;
|
|||||||
import forge.card.mana.ManaCostShard;
|
import forge.card.mana.ManaCostShard;
|
||||||
import forge.game.*;
|
import forge.game.*;
|
||||||
import forge.game.ability.AbilityFactory;
|
import forge.game.ability.AbilityFactory;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.ApiType;
|
import forge.game.ability.ApiType;
|
||||||
import forge.game.ability.effects.CharmEffect;
|
import forge.game.ability.effects.CharmEffect;
|
||||||
@@ -1266,7 +1267,7 @@ public class ComputerUtil {
|
|||||||
public static boolean preventRunAwayActivations(final SpellAbility sa) {
|
public static boolean preventRunAwayActivations(final SpellAbility sa) {
|
||||||
int activations = sa.getActivationsThisTurn();
|
int activations = sa.getActivationsThisTurn();
|
||||||
|
|
||||||
if (sa.isTemporary()) {
|
if (!sa.isIntrinsic()) {
|
||||||
return MyRandom.getRandom().nextFloat() >= .95; // Abilities created by static abilities have no memory
|
return MyRandom.getRandom().nextFloat() >= .95; // Abilities created by static abilities have no memory
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2849,10 +2850,9 @@ public class ComputerUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run any applicable replacement effects.
|
// Run any applicable replacement effects.
|
||||||
final Map<String, Object> repParams = Maps.newHashMap();
|
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(player);
|
||||||
repParams.put("Affected", player);
|
repParams.put(AbilityKey.LifeGained, 1);
|
||||||
repParams.put("LifeGained", 1);
|
repParams.put(AbilityKey.Source, source);
|
||||||
repParams.put("Source", source);
|
|
||||||
|
|
||||||
List<ReplacementEffect> list = player.getGame().getReplacementHandler().getReplacementList(
|
List<ReplacementEffect> list = player.getGame().getReplacementHandler().getReplacementList(
|
||||||
ReplacementType.GainLife,
|
ReplacementType.GainLife,
|
||||||
@@ -2880,15 +2880,15 @@ public class ComputerUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run any applicable replacement effects.
|
// Run any applicable replacement effects.
|
||||||
final Map<String, Object> repParams = Maps.newHashMap();
|
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(player);
|
||||||
repParams.put("Affected", player);
|
repParams.put(AbilityKey.LifeGained, n);
|
||||||
repParams.put("LifeGained", n);
|
repParams.put(AbilityKey.Source, source);
|
||||||
repParams.put("Source", source);
|
|
||||||
|
|
||||||
List<ReplacementEffect> list = player.getGame().getReplacementHandler().getReplacementList(
|
List<ReplacementEffect> list = player.getGame().getReplacementHandler().getReplacementList(
|
||||||
ReplacementType.GainLife,
|
ReplacementType.GainLife,
|
||||||
repParams,
|
repParams,
|
||||||
ReplacementLayer.Other);
|
ReplacementLayer.Other
|
||||||
|
);
|
||||||
|
|
||||||
if (Iterables.any(list, CardTraitPredicates.hasParam("AiLogic", "NoLife"))) {
|
if (Iterables.any(list, CardTraitPredicates.hasParam("AiLogic", "NoLife"))) {
|
||||||
// no life gain is not negative
|
// no life gain is not negative
|
||||||
|
|||||||
@@ -1128,14 +1128,14 @@ public class ComputerUtilCard {
|
|||||||
// assume it either benefits the player or disrupts the opponent
|
// assume it either benefits the player or disrupts the opponent
|
||||||
for (final StaticAbility stAb : c.getStaticAbilities()) {
|
for (final StaticAbility stAb : c.getStaticAbilities()) {
|
||||||
final Map<String, String> params = stAb.getMapParams();
|
final Map<String, String> params = stAb.getMapParams();
|
||||||
if (params.get("Mode").equals("Continuous") && stAb.isIntrinsic() && !stAb.isTemporary()) {
|
if (params.get("Mode").equals("Continuous") && stAb.isIntrinsic()) {
|
||||||
priority = true;
|
priority = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!priority) {
|
if (!priority) {
|
||||||
for (final Trigger t : c.getTriggers()) {
|
for (final Trigger t : c.getTriggers()) {
|
||||||
if (t.isIntrinsic() && !t.isTemporary()) {
|
if (t.isIntrinsic()) {
|
||||||
// has a triggered ability, could be benefitting the opponent or disrupting the AI
|
// has a triggered ability, could be benefitting the opponent or disrupting the AI
|
||||||
priority = true;
|
priority = true;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import forge.game.CardTraitBase;
|
|||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.GameEntity;
|
import forge.game.GameEntity;
|
||||||
import forge.game.ability.AbilityFactory;
|
import forge.game.ability.AbilityFactory;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.ApiType;
|
import forge.game.ability.ApiType;
|
||||||
import forge.game.card.*;
|
import forge.game.card.*;
|
||||||
@@ -2580,13 +2581,11 @@ public class ComputerUtilCombat {
|
|||||||
final Game game = attacker.getGame();
|
final Game game = attacker.getGame();
|
||||||
|
|
||||||
// first try to replace the damage
|
// first try to replace the damage
|
||||||
final Map<String, Object> repParams = Maps.newHashMap();
|
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(target);
|
||||||
repParams.put("Affected", target);
|
repParams.put(AbilityKey.DamageSource, attacker);
|
||||||
repParams.put("DamageSource", attacker);
|
repParams.put(AbilityKey.DamageAmount, damage);
|
||||||
repParams.put("DamageAmount", damage);
|
repParams.put(AbilityKey.IsCombat, true);
|
||||||
repParams.put("IsCombat", true);
|
repParams.put(AbilityKey.Prevention, true);
|
||||||
repParams.put("Prevention", true);
|
|
||||||
// repParams.put("PreventMap", preventMap);
|
|
||||||
|
|
||||||
List<ReplacementEffect> list = game.getReplacementHandler().getReplacementList(
|
List<ReplacementEffect> list = game.getReplacementHandler().getReplacementList(
|
||||||
ReplacementType.DamageDone, repParams, ReplacementLayer.Other);
|
ReplacementType.DamageDone, repParams, ReplacementLayer.Other);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import forge.card.mana.ManaCostParser;
|
|||||||
import forge.card.mana.ManaCostShard;
|
import forge.card.mana.ManaCostShard;
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.GameActionUtil;
|
import forge.game.GameActionUtil;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.ApiType;
|
import forge.game.ability.ApiType;
|
||||||
import forge.game.card.*;
|
import forge.game.card.*;
|
||||||
@@ -1408,11 +1409,11 @@ public class ComputerUtilMana {
|
|||||||
AbilityManaPart mp = m.getManaPart();
|
AbilityManaPart mp = m.getManaPart();
|
||||||
|
|
||||||
// setup produce mana replacement effects
|
// setup produce mana replacement effects
|
||||||
final Map<String, Object> repParams = new HashMap<>();
|
final Map<AbilityKey, Object> repParams = AbilityKey.newMap();
|
||||||
repParams.put("Mana", mp.getOrigProduced());
|
repParams.put(AbilityKey.Mana, mp.getOrigProduced());
|
||||||
repParams.put("Affected", sourceCard);
|
repParams.put(AbilityKey.Affected, sourceCard);
|
||||||
repParams.put("Player", ai);
|
repParams.put(AbilityKey.Player, ai);
|
||||||
repParams.put("AbilityMana", m);
|
repParams.put(AbilityKey.AbilityMana, m);
|
||||||
|
|
||||||
for (final ReplacementEffect replacementEffect : replacementEffects) {
|
for (final ReplacementEffect replacementEffect : replacementEffects) {
|
||||||
if (replacementEffect.canReplace(repParams)) {
|
if (replacementEffect.canReplace(repParams)) {
|
||||||
|
|||||||
@@ -866,8 +866,8 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReplacementEffect chooseSingleReplacementEffect(String prompt, List<ReplacementEffect> possibleReplacers, Map<String, Object> runParams) {
|
public ReplacementEffect chooseSingleReplacementEffect(String prompt, List<ReplacementEffect> possibleReplacers) {
|
||||||
return brains.chooseSingleReplacementEffect(possibleReplacers, runParams);
|
return brains.chooseSingleReplacementEffect(possibleReplacers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -467,26 +467,19 @@ public class AnimateAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
AnimateEffectBase.doAnimate(card, sa, power, toughness, types, removeTypes, finalDesc, keywords, removeKeywords, hiddenKeywords, timestamp);
|
AnimateEffectBase.doAnimate(card, sa, power, toughness, types, removeTypes, finalDesc, keywords, removeKeywords, hiddenKeywords, timestamp);
|
||||||
|
|
||||||
// back to duplicating AnimateEffect.resolve
|
|
||||||
// TODO will all these abilities/triggers/replacements/etc. lead to
|
|
||||||
// memory leaks or unintended effects?
|
|
||||||
// remove abilities
|
// remove abilities
|
||||||
final List<SpellAbility> removedAbilities = Lists.newArrayList();
|
final List<SpellAbility> removedAbilities = Lists.newArrayList();
|
||||||
boolean clearAbilities = sa.hasParam("OverwriteAbilities");
|
|
||||||
boolean clearSpells = sa.hasParam("OverwriteSpells");
|
boolean clearSpells = sa.hasParam("OverwriteSpells");
|
||||||
boolean removeAll = sa.hasParam("RemoveAllAbilities");
|
boolean removeAll = sa.hasParam("RemoveAllAbilities");
|
||||||
boolean removeIntrinsic = sa.hasParam("RemoveIntrinsicAbilities");
|
boolean removeIntrinsic = sa.hasParam("RemoveIntrinsicAbilities");
|
||||||
|
|
||||||
if (clearAbilities || clearSpells || removeAll) {
|
if (clearSpells) {
|
||||||
for (final SpellAbility ab : card.getSpellAbilities()) {
|
removedAbilities.addAll(Lists.newArrayList(card.getSpells()));
|
||||||
if (removeAll
|
}
|
||||||
|| (ab.isIntrinsic() && removeIntrinsic && !ab.isBasicLandAbility())
|
|
||||||
|| (ab.isAbility() && clearAbilities)
|
if (sa.hasParam("RemoveThisAbility") && !removedAbilities.contains(sa)) {
|
||||||
|| (ab.isSpell() && clearSpells)) {
|
removedAbilities.add(sa);
|
||||||
card.removeSpellAbility(ab);
|
|
||||||
removedAbilities.add(ab);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// give abilities
|
// give abilities
|
||||||
@@ -494,9 +487,7 @@ public class AnimateAi extends SpellAbilityAi {
|
|||||||
if (abilities.size() > 0) {
|
if (abilities.size() > 0) {
|
||||||
for (final String s : abilities) {
|
for (final String s : abilities) {
|
||||||
final String actualAbility = source.getSVar(s);
|
final String actualAbility = source.getSVar(s);
|
||||||
final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, source);
|
addedAbilities.add(AbilityFactory.getAbility(actualAbility, card));
|
||||||
addedAbilities.add(grantedAbility);
|
|
||||||
card.addSpellAbility(grantedAbility);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,8 +496,8 @@ public class AnimateAi extends SpellAbilityAi {
|
|||||||
if (triggers.size() > 0) {
|
if (triggers.size() > 0) {
|
||||||
for (final String s : triggers) {
|
for (final String s : triggers) {
|
||||||
final String actualTrigger = source.getSVar(s);
|
final String actualTrigger = source.getSVar(s);
|
||||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, source, false);
|
final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, card, false);
|
||||||
addedTriggers.add(card.addTrigger(parsedTrigger));
|
addedTriggers.add(parsedTrigger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,24 +506,28 @@ public class AnimateAi extends SpellAbilityAi {
|
|||||||
if (replacements.size() > 0) {
|
if (replacements.size() > 0) {
|
||||||
for (final String s : replacements) {
|
for (final String s : replacements) {
|
||||||
final String actualReplacement = source.getSVar(s);
|
final String actualReplacement = source.getSVar(s);
|
||||||
final ReplacementEffect parsedReplacement = ReplacementHandler.parseReplacement(actualReplacement,
|
final ReplacementEffect parsedReplacement = ReplacementHandler.parseReplacement(actualReplacement, card, false);
|
||||||
source, false);
|
addedReplacements.add(parsedReplacement);
|
||||||
addedReplacements.add(card.addReplacementEffect(parsedReplacement));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// suppress triggers from the animated card
|
// give static abilities (should only be used by cards to give
|
||||||
final List<Trigger> removedTriggers = Lists.newArrayList();
|
// itself a static ability)
|
||||||
if (sa.hasParam("OverwriteTriggers") || removeAll || removeIntrinsic) {
|
final List<StaticAbility> addedStaticAbilities = Lists.newArrayList();
|
||||||
for (final Trigger trigger : card.getTriggers()) {
|
if (stAbs.size() > 0) {
|
||||||
if (removeIntrinsic && !trigger.isIntrinsic()) {
|
for (final String s : stAbs) {
|
||||||
continue;
|
final String actualAbility = source.getSVar(s);
|
||||||
}
|
addedStaticAbilities.add(new StaticAbility(actualAbility, card));
|
||||||
trigger.setSuppressed(true);
|
|
||||||
removedTriggers.add(trigger);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (removeAll || removeIntrinsic
|
||||||
|
|| !addedAbilities.isEmpty() || !removedAbilities.isEmpty() || !addedTriggers.isEmpty()
|
||||||
|
|| !addedReplacements.isEmpty() || !addedStaticAbilities.isEmpty()) {
|
||||||
|
card.addChangedCardTraits(addedAbilities, removedAbilities, addedTriggers, addedReplacements,
|
||||||
|
addedStaticAbilities, removeAll, false, removeIntrinsic, timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
// give static abilities (should only be used by cards to give
|
// give static abilities (should only be used by cards to give
|
||||||
// itself a static ability)
|
// itself a static ability)
|
||||||
if (stAbs.size() > 0) {
|
if (stAbs.size() > 0) {
|
||||||
@@ -560,30 +555,6 @@ public class AnimateAi extends SpellAbilityAi {
|
|||||||
card.setSVar(name, actualsVar);
|
card.setSVar(name, actualsVar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// suppress static abilities from the animated card
|
|
||||||
final List<StaticAbility> removedStatics = Lists.newArrayList();
|
|
||||||
if (sa.hasParam("OverwriteStatics") || removeAll || removeIntrinsic) {
|
|
||||||
for (final StaticAbility stAb : card.getStaticAbilities()) {
|
|
||||||
if (removeIntrinsic && !stAb.isIntrinsic()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
stAb.setTemporarilySuppressed(true);
|
|
||||||
removedStatics.add(stAb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// suppress static abilities from the animated card
|
|
||||||
final List<ReplacementEffect> removedReplacements = Lists.newArrayList();
|
|
||||||
if (sa.hasParam("OverwriteReplacements") || removeAll || removeIntrinsic) {
|
|
||||||
for (final ReplacementEffect re : card.getReplacementEffects()) {
|
|
||||||
if (removeIntrinsic && !re.isIntrinsic()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
re.setTemporarilySuppressed(true);
|
|
||||||
removedReplacements.add(re);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ComputerUtilCard.applyStaticContPT(game, card, null);
|
ComputerUtilCard.applyStaticContPT(game, card, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import forge.card.MagicColor;
|
|||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.GameObject;
|
import forge.game.GameObject;
|
||||||
import forge.game.GlobalRuleChange;
|
import forge.game.GlobalRuleChange;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.ApiType;
|
import forge.game.ability.ApiType;
|
||||||
import forge.game.card.*;
|
import forge.game.card.*;
|
||||||
@@ -1789,8 +1790,8 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean doReturnCommanderLogic(SpellAbility sa, Player aiPlayer) {
|
public boolean doReturnCommanderLogic(SpellAbility sa, Player aiPlayer) {
|
||||||
Map<String, Object> originalParams = (Map<String, Object>)sa.getReplacingObject("OriginalParams");
|
Map<AbilityKey, Object> originalParams = (Map<AbilityKey, Object>)sa.getReplacingObject(AbilityKey.OriginalParams);
|
||||||
SpellAbility causeSa = (SpellAbility)originalParams.get("Cause");
|
SpellAbility causeSa = (SpellAbility)originalParams.get(AbilityKey.Cause);
|
||||||
SpellAbility causeSub = null;
|
SpellAbility causeSub = null;
|
||||||
|
|
||||||
// Squee, the Immortal: easier to recast it (the call below has to be "contains" since SA is an intrinsic effect)
|
// Squee, the Immortal: easier to recast it (the call below has to be "contains" since SA is an intrinsic effect)
|
||||||
@@ -1813,7 +1814,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
// A blink effect implemented using a delayed trigger
|
// A blink effect implemented using a delayed trigger
|
||||||
return !"Exile".equals(exec.getParam("Origin")) || !"Battlefield".equals(exec.getParam("Destination"));
|
return !"Exile".equals(exec.getParam("Origin")) || !"Battlefield".equals(exec.getParam("Destination"));
|
||||||
}
|
}
|
||||||
} else return causeSa.getHostCard() == null || !causeSa.getHostCard().equals(sa.getReplacingObject("Card"))
|
} else return causeSa.getHostCard() == null || !causeSa.getHostCard().equals(sa.getReplacingObject(AbilityKey.Card))
|
||||||
|| !causeSa.getActivatingPlayer().equals(aiPlayer);
|
|| !causeSa.getActivatingPlayer().equals(aiPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ package forge.ai.ability;
|
|||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import forge.ai.ComputerUtil;
|
import forge.ai.ComputerUtil;
|
||||||
import forge.ai.ComputerUtilCard;
|
import forge.ai.ComputerUtilCard;
|
||||||
import forge.ai.ComputerUtilMana;
|
import forge.ai.ComputerUtilMana;
|
||||||
import forge.ai.SpellAbilityAi;
|
import forge.ai.SpellAbilityAi;
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardCollection;
|
import forge.game.card.CardCollection;
|
||||||
import forge.game.card.CardCollectionView;
|
import forge.game.card.CardCollectionView;
|
||||||
@@ -97,11 +97,10 @@ public class ManifestAi extends SpellAbilityAi {
|
|||||||
topCopy.turnFaceDownNoUpdate();
|
topCopy.turnFaceDownNoUpdate();
|
||||||
topCopy.setManifested(true);
|
topCopy.setManifested(true);
|
||||||
|
|
||||||
final Map<String, Object> repParams = Maps.newHashMap();
|
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(topCopy);
|
||||||
repParams.put("Affected", topCopy);
|
repParams.put(AbilityKey.Origin, card.getZone().getZoneType());
|
||||||
repParams.put("Origin", card.getZone().getZoneType());
|
repParams.put(AbilityKey.Destination, ZoneType.Battlefield);
|
||||||
repParams.put("Destination", ZoneType.Battlefield);
|
repParams.put(AbilityKey.Source, sa.getHostCard());
|
||||||
repParams.put("Source", sa.getHostCard());
|
|
||||||
List<ReplacementEffect> list = game.getReplacementHandler().getReplacementList(ReplacementType.Moved, repParams, ReplacementLayer.Other);
|
List<ReplacementEffect> list = game.getReplacementHandler().getReplacementList(ReplacementType.Moved, repParams, ReplacementLayer.Other);
|
||||||
if (!list.isEmpty()) {
|
if (!list.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -38,15 +38,9 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView {
|
|||||||
/** The is intrinsic. */
|
/** The is intrinsic. */
|
||||||
protected boolean intrinsic;
|
protected boolean intrinsic;
|
||||||
|
|
||||||
/** The temporary. */
|
|
||||||
protected boolean temporary = false;
|
|
||||||
|
|
||||||
/** The suppressed. */
|
/** The suppressed. */
|
||||||
protected boolean suppressed = false;
|
protected boolean suppressed = false;
|
||||||
|
|
||||||
/** The temporarily suppressed. */
|
|
||||||
protected boolean temporarilySuppressed = false;
|
|
||||||
|
|
||||||
protected Map<String, String> sVars = Maps.newHashMap();
|
protected Map<String, String> sVars = Maps.newHashMap();
|
||||||
|
|
||||||
protected Map<String, String> intrinsicChangedTextColors = Maps.newHashMap();
|
protected Map<String, String> intrinsicChangedTextColors = Maps.newHashMap();
|
||||||
@@ -66,24 +60,6 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView {
|
|||||||
*/
|
*/
|
||||||
private static final ImmutableList<String> noChangeKeys = ImmutableList.<String>builder()
|
private static final ImmutableList<String> noChangeKeys = ImmutableList.<String>builder()
|
||||||
.add("TokenScript", "LegacyImage", "TokenImage", "NewName").build();
|
.add("TokenScript", "LegacyImage", "TokenImage", "NewName").build();
|
||||||
/**
|
|
||||||
* Sets the temporary.
|
|
||||||
*
|
|
||||||
* @param temp
|
|
||||||
* the new temporary
|
|
||||||
*/
|
|
||||||
public final void setTemporary(final boolean temp) {
|
|
||||||
this.temporary = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if is temporary.
|
|
||||||
*
|
|
||||||
* @return true, if is temporary
|
|
||||||
*/
|
|
||||||
public final boolean isTemporary() {
|
|
||||||
return this.temporary;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -196,26 +172,12 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView {
|
|||||||
this.suppressed = supp;
|
this.suppressed = supp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the temporarily suppressed.
|
|
||||||
*
|
|
||||||
* @param supp
|
|
||||||
* the new temporarily suppressed
|
|
||||||
*/
|
|
||||||
public final void setTemporarilySuppressed(final boolean supp) {
|
|
||||||
this.temporarilySuppressed = supp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if is suppressed.
|
* Checks if is suppressed.
|
||||||
*
|
*
|
||||||
* @return true, if is suppressed
|
* @return true, if is suppressed
|
||||||
*/
|
*/
|
||||||
public final boolean isSuppressed() {
|
public final boolean isSuppressed() {
|
||||||
return (this.suppressed || this.temporarilySuppressed);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final boolean isNonTempSuppressed() {
|
|
||||||
return this.suppressed;
|
return this.suppressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,8 +55,6 @@ import org.apache.commons.lang3.tuple.ImmutablePair;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static forge.util.EnumMapUtil.toStringMap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Methods for common actions performed during a game.
|
* Methods for common actions performed during a game.
|
||||||
*
|
*
|
||||||
@@ -148,7 +146,7 @@ public class GameAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if an adventureCard is put from Stack somewhere else, need to reset to Original State
|
// if an adventureCard is put from Stack somewhere else, need to reset to Original State
|
||||||
if (c.isAdventureCard() && (ZoneType.Stack.equals(zoneFrom) || !ZoneType.Stack.equals(zoneTo))) { //fix NPE momir
|
if (c.isAdventureCard() && ((zoneFrom != null && zoneFrom.is(ZoneType.Stack)) || !zoneTo.is(ZoneType.Stack))) {
|
||||||
c.setState(CardStateName.Original, true);
|
c.setState(CardStateName.Original, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,8 +290,7 @@ public class GameAction {
|
|||||||
copied.getOwner().addInboundToken(copied);
|
copied.getOwner().addInboundToken(copied);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<AbilityKey, Object> repParams = AbilityKey.newMap();
|
Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(copied);
|
||||||
repParams.put(AbilityKey.Affected, copied);
|
|
||||||
repParams.put(AbilityKey.CardLKI, lastKnownInfo);
|
repParams.put(AbilityKey.CardLKI, lastKnownInfo);
|
||||||
repParams.put(AbilityKey.Cause, cause);
|
repParams.put(AbilityKey.Cause, cause);
|
||||||
repParams.put(AbilityKey.Origin, zoneFrom != null ? zoneFrom.getZoneType() : null);
|
repParams.put(AbilityKey.Origin, zoneFrom != null ? zoneFrom.getZoneType() : null);
|
||||||
@@ -303,7 +300,7 @@ public class GameAction {
|
|||||||
repParams.putAll(params);
|
repParams.putAll(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReplacementResult repres = game.getReplacementHandler().run(ReplacementType.Moved, toStringMap(repParams));
|
ReplacementResult repres = game.getReplacementHandler().run(ReplacementType.Moved, repParams);
|
||||||
if (repres != ReplacementResult.NotReplaced) {
|
if (repres != ReplacementResult.NotReplaced) {
|
||||||
// reset failed manifested Cards back to original
|
// reset failed manifested Cards back to original
|
||||||
if (c.isManifested()) {
|
if (c.isManifested()) {
|
||||||
@@ -760,8 +757,6 @@ public class GameAction {
|
|||||||
|
|
||||||
// remove old effects
|
// remove old effects
|
||||||
game.getStaticEffects().clearStaticEffects(affectedCards);
|
game.getStaticEffects().clearStaticEffects(affectedCards);
|
||||||
game.getTriggerHandler().cleanUpTemporaryTriggers();
|
|
||||||
game.getReplacementHandler().cleanUpTemporaryReplacements();
|
|
||||||
|
|
||||||
for (final Player p : game.getPlayers()) {
|
for (final Player p : game.getPlayers()) {
|
||||||
if (!game.getStack().isFrozen()) {
|
if (!game.getStack().isFrozen()) {
|
||||||
@@ -779,17 +774,11 @@ public class GameAction {
|
|||||||
public boolean visit(final Card c) {
|
public boolean visit(final Card c) {
|
||||||
// need to get Card from preList if able
|
// need to get Card from preList if able
|
||||||
final Card co = preList.get(c);
|
final Card co = preList.get(c);
|
||||||
List<StaticAbility> toRemove = Lists.newArrayList();
|
|
||||||
for (StaticAbility stAb : co.getStaticAbilities()) {
|
for (StaticAbility stAb : co.getStaticAbilities()) {
|
||||||
if (stAb.isTemporary()) {
|
if (stAb.getParam("Mode").equals("Continuous")) {
|
||||||
toRemove.add(stAb);
|
|
||||||
} else if (stAb.getParam("Mode").equals("Continuous")) {
|
|
||||||
staticAbilities.add(stAb);
|
staticAbilities.add(stAb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (StaticAbility stAb : toRemove) {
|
|
||||||
co.removeStaticAbility(stAb);
|
|
||||||
}
|
|
||||||
if (!co.getStaticCommandList().isEmpty()) {
|
if (!co.getStaticCommandList().isEmpty()) {
|
||||||
staticList.add(co);
|
staticList.add(co);
|
||||||
}
|
}
|
||||||
@@ -1397,11 +1386,10 @@ public class GameAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Replacement effects
|
// Replacement effects
|
||||||
final Map<String, Object> repRunParams = Maps.newHashMap();
|
final Map<AbilityKey, Object> repRunParams = AbilityKey.mapFromCard(c);
|
||||||
repRunParams.put("Source", sa);
|
repRunParams.put(AbilityKey.Source, sa);
|
||||||
repRunParams.put("Card", c);
|
repRunParams.put(AbilityKey.Affected, c);
|
||||||
repRunParams.put("Affected", c);
|
repRunParams.put(AbilityKey.Regeneration, regenerate);
|
||||||
repRunParams.put("Regeneration", regenerate);
|
|
||||||
|
|
||||||
if (game.getReplacementHandler().run(ReplacementType.Destroy, repRunParams) != ReplacementResult.NotReplaced) {
|
if (game.getReplacementHandler().run(ReplacementType.Destroy, repRunParams) != ReplacementResult.NotReplaced) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -115,25 +115,24 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
|
|||||||
public int replaceDamage(final int damage, final Card source, final boolean isCombat, final boolean prevention,
|
public int replaceDamage(final int damage, final Card source, final boolean isCombat, final boolean prevention,
|
||||||
final CardDamageMap damageMap, final CardDamageMap preventMap, GameEntityCounterTable counterTable, final SpellAbility cause) {
|
final CardDamageMap damageMap, final CardDamageMap preventMap, GameEntityCounterTable counterTable, final SpellAbility cause) {
|
||||||
// Replacement effects
|
// Replacement effects
|
||||||
final Map<String, Object> repParams = Maps.newHashMap();
|
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
|
||||||
repParams.put("Affected", this);
|
repParams.put(AbilityKey.DamageSource, source);
|
||||||
repParams.put("DamageSource", source);
|
repParams.put(AbilityKey.DamageAmount, damage);
|
||||||
repParams.put("DamageAmount", damage);
|
repParams.put(AbilityKey.IsCombat, isCombat);
|
||||||
repParams.put("IsCombat", isCombat);
|
repParams.put(AbilityKey.NoPreventDamage, !prevention);
|
||||||
repParams.put("NoPreventDamage", !prevention);
|
repParams.put(AbilityKey.DamageMap, damageMap);
|
||||||
repParams.put("DamageMap", damageMap);
|
repParams.put(AbilityKey.PreventMap, preventMap);
|
||||||
repParams.put("PreventMap", preventMap);
|
repParams.put(AbilityKey.CounterTable, counterTable);
|
||||||
repParams.put("CounterTable", counterTable);
|
|
||||||
if (cause != null) {
|
if (cause != null) {
|
||||||
repParams.put("Cause", cause);
|
repParams.put(AbilityKey.Cause, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (getGame().getReplacementHandler().run(ReplacementType.DamageDone, repParams)) {
|
switch (getGame().getReplacementHandler().run(ReplacementType.DamageDone, repParams)) {
|
||||||
case NotReplaced:
|
case NotReplaced:
|
||||||
return damage;
|
return damage;
|
||||||
case Updated:
|
case Updated:
|
||||||
int newDamage = (int) repParams.get("DamageAmount");
|
int newDamage = (int) repParams.get(AbilityKey.DamageAmount);
|
||||||
GameEntity newTarget = (GameEntity) repParams.get("Affected");
|
GameEntity newTarget = (GameEntity) repParams.get(AbilityKey.Affected);
|
||||||
// check if this is still the affected card or player
|
// check if this is still the affected card or player
|
||||||
if (this.equals(newTarget)) {
|
if (this.equals(newTarget)) {
|
||||||
return newDamage;
|
return newDamage;
|
||||||
@@ -169,15 +168,14 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
|
|||||||
int restDamage = damage;
|
int restDamage = damage;
|
||||||
|
|
||||||
// first try to replace the damage
|
// first try to replace the damage
|
||||||
final Map<String, Object> repParams = Maps.newHashMap();
|
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
|
||||||
repParams.put("Affected", this);
|
repParams.put(AbilityKey.DamageSource, source);
|
||||||
repParams.put("DamageSource", source);
|
repParams.put(AbilityKey.DamageAmount, damage);
|
||||||
repParams.put("DamageAmount", damage);
|
repParams.put(AbilityKey.IsCombat, isCombat);
|
||||||
repParams.put("IsCombat", isCombat);
|
repParams.put(AbilityKey.Prevention, true);
|
||||||
repParams.put("Prevention", true);
|
repParams.put(AbilityKey.PreventMap, preventMap);
|
||||||
repParams.put("PreventMap", preventMap);
|
|
||||||
if (cause != null) {
|
if (cause != null) {
|
||||||
repParams.put("Cause", cause);
|
repParams.put(AbilityKey.Cause, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (getGame().getReplacementHandler().run(ReplacementType.DamageDone, repParams)) {
|
switch (getGame().getReplacementHandler().run(ReplacementType.DamageDone, repParams)) {
|
||||||
@@ -185,7 +183,7 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
|
|||||||
restDamage = damage;
|
restDamage = damage;
|
||||||
break;
|
break;
|
||||||
case Updated:
|
case Updated:
|
||||||
restDamage = (int) repParams.get("DamageAmount");
|
restDamage = (int) repParams.get(AbilityKey.DamageAmount);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
restDamage = 0;
|
restDamage = 0;
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ import forge.game.card.CardCollection;
|
|||||||
import forge.game.card.CardCollectionView;
|
import forge.game.card.CardCollectionView;
|
||||||
import forge.game.card.CardUtil;
|
import forge.game.card.CardUtil;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.AbilityStatic;
|
|
||||||
import forge.game.spellability.SpellAbility;
|
|
||||||
import forge.game.staticability.StaticAbility;
|
import forge.game.staticability.StaticAbility;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -236,11 +234,7 @@ public class StaticEffect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("IgnoreEffectCost")) {
|
if (hasParam("IgnoreEffectCost")) {
|
||||||
for (final SpellAbility s : getSource().getSpellAbilities()) {
|
getSource().removeChangedCardTraits(getTimestamp());
|
||||||
if (s instanceof AbilityStatic && s.isTemporary()) {
|
|
||||||
getSource().removeSpellAbility(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// modify players
|
// modify players
|
||||||
@@ -273,22 +267,12 @@ public class StaticEffect {
|
|||||||
// the view is updated in GameAction#checkStaticAbilities to avoid flickering
|
// the view is updated in GameAction#checkStaticAbilities to avoid flickering
|
||||||
|
|
||||||
// remove keywords
|
// remove keywords
|
||||||
// TODO regular keywords currently don't try to use keyword multiplier
|
|
||||||
// (Although nothing uses it at this time)
|
// (Although nothing uses it at this time)
|
||||||
if (hasParam("AddKeyword") || hasParam("RemoveKeyword")
|
if (hasParam("AddKeyword") || hasParam("RemoveKeyword")
|
||||||
|| hasParam("RemoveAllAbilities")) {
|
|| hasParam("RemoveAllAbilities")) {
|
||||||
affectedCard.removeChangedCardKeywords(getTimestamp());
|
affectedCard.removeChangedCardKeywords(getTimestamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove abilities
|
|
||||||
if (hasParam("AddAbility") || hasParam("GainsAbilitiesOf")) {
|
|
||||||
for (final SpellAbility s : affectedCard.getSpellAbilities().threadSafeIterable()) {
|
|
||||||
if (s.isTemporary()) {
|
|
||||||
affectedCard.removeSpellAbility(s, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addHiddenKeywords != null) {
|
if (addHiddenKeywords != null) {
|
||||||
for (final String k : addHiddenKeywords) {
|
for (final String k : addHiddenKeywords) {
|
||||||
affectedCard.removeHiddenExtrinsicKeyword(k);
|
affectedCard.removeHiddenExtrinsicKeyword(k);
|
||||||
@@ -296,8 +280,10 @@ public class StaticEffect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// remove abilities
|
// remove abilities
|
||||||
if (hasParam("RemoveAllAbilities") || hasParam("RemoveIntrinsicAbilities")) {
|
if (hasParam("AddAbility") || hasParam("GainsAbilitiesOf")
|
||||||
affectedCard.unSuppressCardTraits();
|
|| hasParam("AddTrigger") || hasParam("AddStaticAbility") || hasParam("AddReplacementEffects")
|
||||||
|
|| hasParam("RemoveAllAbilities") || hasParam("RemoveIntrinsicAbilities")) {
|
||||||
|
affectedCard.removeChangedCardTraits(getTimestamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove Types
|
// remove Types
|
||||||
|
|||||||
@@ -80,4 +80,13 @@ public class StaticEffects {
|
|||||||
public Iterable<StaticEffect> getEffects() {
|
public Iterable<StaticEffect> getEffects() {
|
||||||
return staticEffects.values();
|
return staticEffects.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean removeStaticEffect(final StaticAbility staticAbility) {
|
||||||
|
final StaticEffect currentEffect = staticEffects.remove(staticAbility);
|
||||||
|
if (currentEffect == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
currentEffect.remove();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package forge.game.ability;
|
|||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import forge.game.GameEntity;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,12 +38,15 @@ public enum AbilityKey {
|
|||||||
CostStack("CostStack"),
|
CostStack("CostStack"),
|
||||||
CounterAmount("CounterAmount"),
|
CounterAmount("CounterAmount"),
|
||||||
CounteredSA("CounteredSA"),
|
CounteredSA("CounteredSA"),
|
||||||
|
CounterNum("CounterNum"),
|
||||||
|
CounterTable("CounterTable"),
|
||||||
CounterType("CounterType"),
|
CounterType("CounterType"),
|
||||||
Crew("Crew"),
|
Crew("Crew"),
|
||||||
CumulativeUpkeepPaid("CumulativeUpkeepPaid"),
|
CumulativeUpkeepPaid("CumulativeUpkeepPaid"),
|
||||||
CurrentCastSpells("CurrentCastSpells"),
|
CurrentCastSpells("CurrentCastSpells"),
|
||||||
CurrentStormCount("CurrentStormCount"),
|
CurrentStormCount("CurrentStormCount"),
|
||||||
DamageAmount("DamageAmount"),
|
DamageAmount("DamageAmount"),
|
||||||
|
DamageMap("DamageMap"),
|
||||||
DamageSource("DamageSource"),
|
DamageSource("DamageSource"),
|
||||||
DamageSources("DamageSources"),
|
DamageSources("DamageSources"),
|
||||||
DamageTarget("DamageTarget"),
|
DamageTarget("DamageTarget"),
|
||||||
@@ -53,18 +57,23 @@ public enum AbilityKey {
|
|||||||
Destination("Destination"),
|
Destination("Destination"),
|
||||||
Devoured("Devoured"),
|
Devoured("Devoured"),
|
||||||
EchoPaid("EchoPaid"),
|
EchoPaid("EchoPaid"),
|
||||||
|
EffectOnly("EffectOnly"),
|
||||||
Exploited("Exploited"),
|
Exploited("Exploited"),
|
||||||
Explorer("Explorer"),
|
Explorer("Explorer"),
|
||||||
Event("Event"),
|
Event("Event"),
|
||||||
Fighter("Fighter"),
|
Fighter("Fighter"),
|
||||||
FirstTime("FirstTime"),
|
FirstTime("FirstTime"),
|
||||||
Fizzle("Fizzle"),
|
Fizzle("Fizzle"),
|
||||||
|
IsCombat("IsCombat"), // TODO confirm that this and IsCombatDamage can be merged
|
||||||
IsCombatDamage("IsCombatDamage"),
|
IsCombatDamage("IsCombatDamage"),
|
||||||
IndividualCostPaymentInstance("IndividualCostPaymentInstance"),
|
IndividualCostPaymentInstance("IndividualCostPaymentInstance"),
|
||||||
IsMadness("IsMadness"),
|
IsMadness("IsMadness"),
|
||||||
LifeAmount("LifeAmount"),
|
LifeAmount("LifeAmount"), //TODO confirm that this and LifeGained can be merged
|
||||||
|
LifeGained("LifeGained"),
|
||||||
|
Mana("Mana"),
|
||||||
MonstrosityAmount("MonstrosityAmount"),
|
MonstrosityAmount("MonstrosityAmount"),
|
||||||
NewCounterAmount("NewCounterAmount"),
|
NewCounterAmount("NewCounterAmount"),
|
||||||
|
NoPreventDamage("NoPreventDamage"),
|
||||||
Num("Num"), // TODO confirm that this and NumThisTurn can be merged
|
Num("Num"), // TODO confirm that this and NumThisTurn can be merged
|
||||||
NumBlockers("NumBlockers"),
|
NumBlockers("NumBlockers"),
|
||||||
NumThisTurn("NumThisTurn"),
|
NumThisTurn("NumThisTurn"),
|
||||||
@@ -76,10 +85,15 @@ public enum AbilityKey {
|
|||||||
Origin("Origin"),
|
Origin("Origin"),
|
||||||
OriginalController("OriginalController"),
|
OriginalController("OriginalController"),
|
||||||
OriginalDefender("OriginalDefender"),
|
OriginalDefender("OriginalDefender"),
|
||||||
|
OriginalParams("OriginalParams"),
|
||||||
PayingMana("PayingMana"),
|
PayingMana("PayingMana"),
|
||||||
Phase("Phase"),
|
Phase("Phase"),
|
||||||
Player("Player"),
|
Player("Player"),
|
||||||
|
PreventMap("PreventMap"),
|
||||||
|
Prevention("Prevention"),
|
||||||
Produced("Produced"),
|
Produced("Produced"),
|
||||||
|
Regeneration("Regeneration"),
|
||||||
|
ReplacementResult("ReplacementResult"),
|
||||||
Result("Result"),
|
Result("Result"),
|
||||||
Scheme("Scheme"),
|
Scheme("Scheme"),
|
||||||
Source("Source"),
|
Source("Source"),
|
||||||
@@ -91,8 +105,12 @@ public enum AbilityKey {
|
|||||||
StackInstance("StackInstance"),
|
StackInstance("StackInstance"),
|
||||||
StackSa("StackSa"),
|
StackSa("StackSa"),
|
||||||
StackSi("StackSi"),
|
StackSi("StackSi"),
|
||||||
|
SurveilNum("SurveilNum"),
|
||||||
Target("Target"),
|
Target("Target"),
|
||||||
Targets("Targets"),
|
Targets("Targets"),
|
||||||
|
TgtSA("TgtSA"),
|
||||||
|
Token("Token"),
|
||||||
|
TokenNum("TokenNum"),
|
||||||
Transformer("Transformer"),
|
Transformer("Transformer"),
|
||||||
Vehicle("Vehicle"),
|
Vehicle("Vehicle"),
|
||||||
Won("Won");
|
Won("Won");
|
||||||
@@ -141,4 +159,11 @@ public enum AbilityKey {
|
|||||||
runParams.put(Card, card);
|
runParams.put(Card, card);
|
||||||
return runParams;
|
return runParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Map<AbilityKey, Object> mapFromAffected(GameEntity gameEntity) {
|
||||||
|
final Map<AbilityKey, Object> runParams = newMap();
|
||||||
|
|
||||||
|
runParams.put(Affected, gameEntity);
|
||||||
|
return runParams;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class AbilityUtils {
|
|||||||
public static CounterType getCounterType(String name, SpellAbility sa) throws Exception {
|
public static CounterType getCounterType(String name, SpellAbility sa) throws Exception {
|
||||||
CounterType counterType;
|
CounterType counterType;
|
||||||
if ("ReplacedCounterType".equals(name)) {
|
if ("ReplacedCounterType".equals(name)) {
|
||||||
name = (String) sa.getReplacingObject("CounterType");
|
name = (String) sa.getReplacingObject(AbilityKey.CounterType);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
counterType = CounterType.getType(name);
|
counterType = CounterType.getType(name);
|
||||||
@@ -157,7 +157,9 @@ public class AbilityUtils {
|
|||||||
}
|
}
|
||||||
else if (defined.startsWith("Replaced") && (sa != null)) {
|
else if (defined.startsWith("Replaced") && (sa != null)) {
|
||||||
final SpellAbility root = sa.getRootAbility();
|
final SpellAbility root = sa.getRootAbility();
|
||||||
final Object crd = root.getReplacingObject(defined.substring(8));
|
AbilityKey type = AbilityKey.fromString(defined.substring(8));
|
||||||
|
final Object crd = root.getReplacingObject(type);
|
||||||
|
|
||||||
if (crd instanceof Card) {
|
if (crd instanceof Card) {
|
||||||
c = game.getCardState((Card) crd);
|
c = game.getCardState((Card) crd);
|
||||||
} else if (crd instanceof List<?>) {
|
} else if (crd instanceof List<?>) {
|
||||||
@@ -712,7 +714,7 @@ public class AbilityUtils {
|
|||||||
}
|
}
|
||||||
else if (calcX[0].startsWith("Replaced")) {
|
else if (calcX[0].startsWith("Replaced")) {
|
||||||
final SpellAbility root = sa.getRootAbility();
|
final SpellAbility root = sa.getRootAbility();
|
||||||
list = new CardCollection((Card) root.getReplacingObject(calcX[0].substring(8)));
|
list = new CardCollection((Card) root.getReplacingObject(AbilityKey.fromString(calcX[0].substring(8))));
|
||||||
}
|
}
|
||||||
else if (calcX[0].startsWith("ReplaceCount")) {
|
else if (calcX[0].startsWith("ReplaceCount")) {
|
||||||
// ReplaceCount is similar to a regular Count, but just
|
// ReplaceCount is similar to a regular Count, but just
|
||||||
@@ -720,7 +722,7 @@ public class AbilityUtils {
|
|||||||
final SpellAbility root = sa.getRootAbility();
|
final SpellAbility root = sa.getRootAbility();
|
||||||
final String[] l = calcX[1].split("/");
|
final String[] l = calcX[1].split("/");
|
||||||
final String m = CardFactoryUtil.extractOperators(calcX[1]);
|
final String m = CardFactoryUtil.extractOperators(calcX[1]);
|
||||||
final int count = (Integer) root.getReplacingObject(l[0]);
|
final int count = (Integer) root.getReplacingObject(AbilityKey.fromString(l[0]));
|
||||||
|
|
||||||
return CardFactoryUtil.doXMath(count, m, card) * multiplier;
|
return CardFactoryUtil.doXMath(count, m, card) * multiplier;
|
||||||
}
|
}
|
||||||
@@ -1063,7 +1065,7 @@ public class AbilityUtils {
|
|||||||
if (defined.endsWith("Controller")) {
|
if (defined.endsWith("Controller")) {
|
||||||
String replacingType = defined.substring(8);
|
String replacingType = defined.substring(8);
|
||||||
replacingType = replacingType.substring(0, replacingType.length() - 10);
|
replacingType = replacingType.substring(0, replacingType.length() - 10);
|
||||||
final Object c = root.getReplacingObject(replacingType);
|
final Object c = root.getReplacingObject(AbilityKey.fromString(replacingType));
|
||||||
if (c instanceof Card) {
|
if (c instanceof Card) {
|
||||||
o = ((Card) c).getController();
|
o = ((Card) c).getController();
|
||||||
}
|
}
|
||||||
@@ -1074,14 +1076,14 @@ public class AbilityUtils {
|
|||||||
else if (defined.endsWith("Owner")) {
|
else if (defined.endsWith("Owner")) {
|
||||||
String replacingType = defined.substring(8);
|
String replacingType = defined.substring(8);
|
||||||
replacingType = replacingType.substring(0, replacingType.length() - 5);
|
replacingType = replacingType.substring(0, replacingType.length() - 5);
|
||||||
final Object c = root.getReplacingObject(replacingType);
|
final Object c = root.getReplacingObject(AbilityKey.fromString(replacingType));
|
||||||
if (c instanceof Card) {
|
if (c instanceof Card) {
|
||||||
o = ((Card) c).getOwner();
|
o = ((Card) c).getOwner();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final String replacingType = defined.substring(8);
|
final String replacingType = defined.substring(8);
|
||||||
o = root.getReplacingObject(replacingType);
|
o = root.getReplacingObject(AbilityKey.fromString(replacingType));
|
||||||
}
|
}
|
||||||
if (o != null) {
|
if (o != null) {
|
||||||
if (o instanceof Player) {
|
if (o instanceof Player) {
|
||||||
|
|||||||
@@ -14,19 +14,15 @@ import forge.game.player.Player;
|
|||||||
import forge.game.replacement.ReplacementEffect;
|
import forge.game.replacement.ReplacementEffect;
|
||||||
import forge.game.replacement.ReplacementHandler;
|
import forge.game.replacement.ReplacementHandler;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.staticability.StaticAbility;
|
|
||||||
import forge.game.trigger.Trigger;
|
import forge.game.trigger.Trigger;
|
||||||
import forge.game.trigger.TriggerHandler;
|
import forge.game.trigger.TriggerHandler;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.collect.FCollectionView;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
|
|
||||||
public class AnimateAllEffect extends AnimateEffectBase {
|
public class AnimateAllEffect extends AnimateEffectBase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -160,30 +156,16 @@ public class AnimateAllEffect extends AnimateEffectBase {
|
|||||||
final String actualAbility = host.getSVar(s);
|
final String actualAbility = host.getSVar(s);
|
||||||
final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, c);
|
final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, c);
|
||||||
addedAbilities.add(grantedAbility);
|
addedAbilities.add(grantedAbility);
|
||||||
c.addSpellAbility(grantedAbility);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove abilities
|
|
||||||
final List<SpellAbility> removedAbilities = new ArrayList<>();
|
|
||||||
if (sa.hasParam("OverwriteAbilities") || removeAll || removeIntrinsic) {
|
|
||||||
for (final SpellAbility ab : c.getSpellAbilities()) {
|
|
||||||
if (ab.isAbility()) {
|
|
||||||
if (removeAll
|
|
||||||
|| (ab.isIntrinsic() && removeIntrinsic && !ab.isBasicLandAbility())) {
|
|
||||||
ab.setTemporarilySuppressed(true);
|
|
||||||
removedAbilities.add(ab);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// give replacement effects
|
// give replacement effects
|
||||||
final List<ReplacementEffect> addedReplacements = new ArrayList<>();
|
final List<ReplacementEffect> addedReplacements = new ArrayList<>();
|
||||||
if (replacements.size() > 0) {
|
if (replacements.size() > 0) {
|
||||||
for (final String s : replacements) {
|
for (final String s : replacements) {
|
||||||
final String actualReplacement = host.getSVar(s);
|
final String actualReplacement = host.getSVar(s);
|
||||||
final ReplacementEffect parsedReplacement = ReplacementHandler.parseReplacement(actualReplacement, c, false);
|
final ReplacementEffect parsedReplacement = ReplacementHandler.parseReplacement(actualReplacement, c, false);
|
||||||
addedReplacements.add(c.addReplacementEffect(parsedReplacement));
|
addedReplacements.add(parsedReplacement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Grant triggers
|
// Grant triggers
|
||||||
@@ -192,45 +174,12 @@ public class AnimateAllEffect extends AnimateEffectBase {
|
|||||||
for (final String s : triggers) {
|
for (final String s : triggers) {
|
||||||
final String actualTrigger = host.getSVar(s);
|
final String actualTrigger = host.getSVar(s);
|
||||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, c, false);
|
final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, c, false);
|
||||||
addedTriggers.add(c.addTrigger(parsedTrigger));
|
addedTriggers.add(parsedTrigger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// suppress triggers from the animated card
|
if (!addedAbilities.isEmpty() || !addedTriggers.isEmpty() || !addedReplacements.isEmpty()) {
|
||||||
final List<Trigger> removedTriggers = new ArrayList<>();
|
c.addChangedCardTraits(addedAbilities, null, addedTriggers, addedReplacements, null, removeAll, false, removeIntrinsic, timestamp);
|
||||||
if (sa.hasParam("OverwriteTriggers") || removeAll || removeIntrinsic) {
|
|
||||||
final FCollectionView<Trigger> triggersToRemove = c.getTriggers();
|
|
||||||
for (final Trigger trigger : triggersToRemove) {
|
|
||||||
if (removeIntrinsic && !trigger.isIntrinsic()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
trigger.setSuppressed(true); // why this not TemporarilySuppressed?
|
|
||||||
removedTriggers.add(trigger);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// suppress static abilities from the animated card
|
|
||||||
final List<StaticAbility> removedStatics = new ArrayList<>();
|
|
||||||
if (sa.hasParam("OverwriteStatics") || removeAll || removeIntrinsic) {
|
|
||||||
for (final StaticAbility stAb : c.getStaticAbilities()) {
|
|
||||||
if (removeIntrinsic && !stAb.isIntrinsic()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
stAb.setTemporarilySuppressed(true);
|
|
||||||
removedStatics.add(stAb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// suppress static abilities from the animated card
|
|
||||||
final List<ReplacementEffect> removedReplacements = new ArrayList<>();
|
|
||||||
if (sa.hasParam("OverwriteReplacements") || removeAll || removeIntrinsic) {
|
|
||||||
for (final ReplacementEffect re : c.getReplacementEffects()) {
|
|
||||||
if (removeIntrinsic && !re.isIntrinsic()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
re.setTemporarilySuppressed(true);
|
|
||||||
removedReplacements.add(re);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// give sVars
|
// give sVars
|
||||||
@@ -247,27 +196,8 @@ public class AnimateAllEffect extends AnimateEffectBase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
doUnanimate(c, sa, finalDesc, hiddenKeywords,
|
doUnanimate(c, sa, hiddenKeywords, timestamp);
|
||||||
addedAbilities, addedTriggers, addedReplacements,
|
|
||||||
ImmutableList.of(), timestamp);
|
|
||||||
|
|
||||||
for (final SpellAbility sa : removedAbilities) {
|
|
||||||
sa.setTemporarilySuppressed(false);
|
|
||||||
}
|
|
||||||
// give back suppressed triggers
|
|
||||||
for (final Trigger t : removedTriggers) {
|
|
||||||
t.setSuppressed(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// give back suppressed static abilities
|
|
||||||
for (final StaticAbility s : removedStatics) {
|
|
||||||
s.setTemporarilySuppressed(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// give back suppressed replacement effects
|
|
||||||
for (final ReplacementEffect re : removedReplacements) {
|
|
||||||
re.setTemporarilySuppressed(false);
|
|
||||||
}
|
|
||||||
game.fireEvent(new GameEventCardStatsChanged(c));
|
game.fireEvent(new GameEventCardStatsChanged(c));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -162,25 +162,15 @@ public class AnimateEffect extends AnimateEffectBase {
|
|||||||
|
|
||||||
// remove abilities
|
// remove abilities
|
||||||
final List<SpellAbility> removedAbilities = Lists.newArrayList();
|
final List<SpellAbility> removedAbilities = Lists.newArrayList();
|
||||||
boolean clearAbilities = sa.hasParam("OverwriteAbilities");
|
|
||||||
boolean clearSpells = sa.hasParam("OverwriteSpells");
|
boolean clearSpells = sa.hasParam("OverwriteSpells");
|
||||||
boolean removeAll = sa.hasParam("RemoveAllAbilities");
|
boolean removeAll = sa.hasParam("RemoveAllAbilities");
|
||||||
boolean removeIntrinsic = sa.hasParam("RemoveIntrinsicAbilities");
|
boolean removeIntrinsic = sa.hasParam("RemoveIntrinsicAbilities");
|
||||||
|
|
||||||
if (clearAbilities || clearSpells || removeAll) {
|
if (clearSpells) {
|
||||||
for (final SpellAbility ab : c.getSpellAbilities()) {
|
removedAbilities.addAll(Lists.newArrayList(c.getSpells()));
|
||||||
if (removeAll
|
|
||||||
|| (ab.isIntrinsic() && removeIntrinsic && !ab.isBasicLandAbility())
|
|
||||||
|| (ab.isAbility() && clearAbilities)
|
|
||||||
|| (ab.isSpell() && clearSpells)) {
|
|
||||||
ab.setTemporarilySuppressed(true);
|
|
||||||
removedAbilities.add(ab);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sa.hasParam("RemoveThisAbility") && !removedAbilities.contains(sa)) {
|
if (sa.hasParam("RemoveThisAbility") && !removedAbilities.contains(sa)) {
|
||||||
c.removeSpellAbility(sa);
|
|
||||||
removedAbilities.add(sa);
|
removedAbilities.add(sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,9 +179,7 @@ public class AnimateEffect extends AnimateEffectBase {
|
|||||||
if (abilities.size() > 0) {
|
if (abilities.size() > 0) {
|
||||||
for (final String s : abilities) {
|
for (final String s : abilities) {
|
||||||
final String actualAbility = source.getSVar(s);
|
final String actualAbility = source.getSVar(s);
|
||||||
final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, c);
|
addedAbilities.add(AbilityFactory.getAbility(actualAbility, c));
|
||||||
addedAbilities.add(grantedAbility);
|
|
||||||
c.addSpellAbility(grantedAbility);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,7 +189,7 @@ public class AnimateEffect extends AnimateEffectBase {
|
|||||||
for (final String s : triggers) {
|
for (final String s : triggers) {
|
||||||
final String actualTrigger = source.getSVar(s);
|
final String actualTrigger = source.getSVar(s);
|
||||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, c, false);
|
final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, c, false);
|
||||||
addedTriggers.add(c.addTrigger(parsedTrigger));
|
addedTriggers.add(parsedTrigger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,19 +199,7 @@ public class AnimateEffect extends AnimateEffectBase {
|
|||||||
for (final String s : replacements) {
|
for (final String s : replacements) {
|
||||||
final String actualReplacement = source.getSVar(s);
|
final String actualReplacement = source.getSVar(s);
|
||||||
final ReplacementEffect parsedReplacement = ReplacementHandler.parseReplacement(actualReplacement, c, false);
|
final ReplacementEffect parsedReplacement = ReplacementHandler.parseReplacement(actualReplacement, c, false);
|
||||||
addedReplacements.add(c.addReplacementEffect(parsedReplacement));
|
addedReplacements.add(parsedReplacement);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// suppress triggers from the animated card
|
|
||||||
final List<Trigger> removedTriggers = Lists.newArrayList();
|
|
||||||
if (sa.hasParam("OverwriteTriggers") || removeAll || removeIntrinsic) {
|
|
||||||
for (final Trigger trigger : c.getTriggers()) {
|
|
||||||
if (removeIntrinsic && !trigger.isIntrinsic()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
trigger.setSuppressed(true); // why this not TemporarilySuppressed?
|
|
||||||
removedTriggers.add(trigger);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +209,7 @@ public class AnimateEffect extends AnimateEffectBase {
|
|||||||
if (stAbs.size() > 0) {
|
if (stAbs.size() > 0) {
|
||||||
for (final String s : stAbs) {
|
for (final String s : stAbs) {
|
||||||
final String actualAbility = source.getSVar(s);
|
final String actualAbility = source.getSVar(s);
|
||||||
addedStaticAbilities.add(c.addStaticAbility(actualAbility));
|
addedStaticAbilities.add(new StaticAbility(actualAbility, c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,30 +227,6 @@ public class AnimateEffect extends AnimateEffectBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// suppress static abilities from the animated card
|
|
||||||
final List<StaticAbility> removedStatics = Lists.newArrayList();
|
|
||||||
if (sa.hasParam("OverwriteStatics") || removeAll || removeIntrinsic) {
|
|
||||||
for (final StaticAbility stAb : c.getStaticAbilities()) {
|
|
||||||
if (removeIntrinsic && !stAb.isIntrinsic()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
stAb.setTemporarilySuppressed(true);
|
|
||||||
removedStatics.add(stAb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// suppress static abilities from the animated card
|
|
||||||
final List<ReplacementEffect> removedReplacements = Lists.newArrayList();
|
|
||||||
if (sa.hasParam("OverwriteReplacements") || removeAll || removeIntrinsic) {
|
|
||||||
for (final ReplacementEffect re : c.getReplacementEffects()) {
|
|
||||||
if (removeIntrinsic && !re.isIntrinsic()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
re.setTemporarilySuppressed(true);
|
|
||||||
removedReplacements.add(re);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// give Remembered
|
// give Remembered
|
||||||
if (animateRemembered != null) {
|
if (animateRemembered != null) {
|
||||||
for (final Object o : AbilityUtils.getDefinedObjects(source, animateRemembered, sa)) {
|
for (final Object o : AbilityUtils.getDefinedObjects(source, animateRemembered, sa)) {
|
||||||
@@ -287,35 +239,40 @@ public class AnimateEffect extends AnimateEffectBase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
doUnanimate(c, sa, finalDesc, hiddenKeywords,
|
doUnanimate(c, sa, hiddenKeywords, timestamp);
|
||||||
addedAbilities, addedTriggers, addedReplacements,
|
|
||||||
addedStaticAbilities, timestamp);
|
|
||||||
|
|
||||||
c.removeChangedName(timestamp);
|
c.removeChangedName(timestamp);
|
||||||
c.updateStateForView();
|
c.updateStateForView();
|
||||||
|
|
||||||
game.fireEvent(new GameEventCardStatsChanged(c));
|
game.fireEvent(new GameEventCardStatsChanged(c));
|
||||||
|
|
||||||
for (final SpellAbility sa : removedAbilities) {
|
|
||||||
sa.setTemporarilySuppressed(false);
|
|
||||||
}
|
|
||||||
// give back suppressed triggers
|
|
||||||
for (final Trigger t : removedTriggers) {
|
|
||||||
t.setSuppressed(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// give back suppressed static abilities
|
|
||||||
for (final StaticAbility s : removedStatics) {
|
|
||||||
s.setTemporarilySuppressed(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// give back suppressed replacement effects
|
|
||||||
for (final ReplacementEffect re : removedReplacements) {
|
|
||||||
re.setTemporarilySuppressed(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if (sa.hasParam("RevertCost")) {
|
||||||
|
final ManaCost cost = new ManaCost(new ManaCostParser(sa.getParam("RevertCost")));
|
||||||
|
final String desc = this.getStackDescription(sa);
|
||||||
|
final SpellAbility revertSA = new AbilityStatic(c, cost) {
|
||||||
|
@Override
|
||||||
|
public void resolve() {
|
||||||
|
unanimate.run();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return cost + ": End Effect: " + desc;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
addedAbilities.add(revertSA);
|
||||||
|
}
|
||||||
|
|
||||||
|
// after unanimate to add RevertCost
|
||||||
|
if (removeAll || removeIntrinsic
|
||||||
|
|| !addedAbilities.isEmpty() || !removedAbilities.isEmpty() || !addedTriggers.isEmpty()
|
||||||
|
|| !addedReplacements.isEmpty() || !addedStaticAbilities.isEmpty()) {
|
||||||
|
c.addChangedCardTraits(addedAbilities, removedAbilities, addedTriggers, addedReplacements,
|
||||||
|
addedStaticAbilities, removeAll, false, removeIntrinsic, timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
if (!permanent) {
|
if (!permanent) {
|
||||||
if (sa.hasParam("UntilEndOfCombat")) {
|
if (sa.hasParam("UntilEndOfCombat")) {
|
||||||
game.getEndOfCombat().addUntil(unanimate);
|
game.getEndOfCombat().addUntil(unanimate);
|
||||||
@@ -343,22 +300,6 @@ public class AnimateEffect extends AnimateEffectBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sa.hasParam("RevertCost")) {
|
|
||||||
final ManaCost cost = new ManaCost(new ManaCostParser(sa.getParam("RevertCost")));
|
|
||||||
final String desc = this.getStackDescription(sa);
|
|
||||||
final SpellAbility revertSA = new AbilityStatic(c, cost) {
|
|
||||||
@Override
|
|
||||||
public void resolve() {
|
|
||||||
unanimate.run();
|
|
||||||
c.removeSpellAbility(this);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public String getDescription() {
|
|
||||||
return cost + ": End Effect: " + desc;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
c.addSpellAbility(revertSA);
|
|
||||||
}
|
|
||||||
|
|
||||||
game.fireEvent(new GameEventCardStatsChanged(c));
|
game.fireEvent(new GameEventCardStatsChanged(c));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,10 +20,8 @@ package forge.game.ability.effects;
|
|||||||
import forge.card.CardType;
|
import forge.card.CardType;
|
||||||
import forge.game.ability.SpellAbilityEffect;
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.replacement.ReplacementEffect;
|
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.staticability.StaticAbility;
|
|
||||||
import forge.game.trigger.Trigger;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
||||||
@@ -128,14 +126,8 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
|||||||
* @param timestamp
|
* @param timestamp
|
||||||
* a long.
|
* a long.
|
||||||
*/
|
*/
|
||||||
static void doUnanimate(final Card c, SpellAbility sa, final String colorDesc,
|
static void doUnanimate(final Card c, SpellAbility sa,
|
||||||
final List<String> hiddenKeywords, final List<SpellAbility> addedAbilities,
|
final List<String> hiddenKeywords, final long timestamp) {
|
||||||
final List<Trigger> addedTriggers, final List<ReplacementEffect> addedReplacements,
|
|
||||||
final List<StaticAbility> addedStaticAbilities, final long timestamp) {
|
|
||||||
|
|
||||||
if (sa.hasParam("LastsIndefinitely")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
c.removeNewPT(timestamp);
|
c.removeNewPT(timestamp);
|
||||||
|
|
||||||
@@ -144,26 +136,12 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
|||||||
c.removeChangedCardTypes(timestamp);
|
c.removeChangedCardTypes(timestamp);
|
||||||
c.removeColor(timestamp);
|
c.removeColor(timestamp);
|
||||||
|
|
||||||
|
c.removeChangedCardTraits(timestamp);
|
||||||
|
|
||||||
for (final String k : hiddenKeywords) {
|
for (final String k : hiddenKeywords) {
|
||||||
c.removeHiddenExtrinsicKeyword(k);
|
c.removeHiddenExtrinsicKeyword(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final SpellAbility saAdd : addedAbilities) {
|
|
||||||
c.removeSpellAbility(saAdd);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final Trigger t : addedTriggers) {
|
|
||||||
c.removeTrigger(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final ReplacementEffect rep : addedReplacements) {
|
|
||||||
c.removeReplacementEffect(rep);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final StaticAbility stAb : addedStaticAbilities) {
|
|
||||||
c.removeStaticAbility(stAb);
|
|
||||||
}
|
|
||||||
|
|
||||||
// any other unanimate cleanup
|
// any other unanimate cleanup
|
||||||
if (!c.isCreature()) {
|
if (!c.isCreature()) {
|
||||||
c.unEquipAllCards();
|
c.unEquipAllCards();
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
|
|
||||||
public class CounterEffect extends SpellAbilityEffect {
|
public class CounterEffect extends SpellAbilityEffect {
|
||||||
@Override
|
@Override
|
||||||
@@ -155,10 +154,9 @@ public class CounterEffect extends SpellAbilityEffect {
|
|||||||
final SpellAbility srcSA, final SpellAbilityStackInstance si) {
|
final SpellAbility srcSA, final SpellAbilityStackInstance si) {
|
||||||
final Game game = tgtSA.getActivatingPlayer().getGame();
|
final Game game = tgtSA.getActivatingPlayer().getGame();
|
||||||
// Run any applicable replacement effects.
|
// Run any applicable replacement effects.
|
||||||
final Map<String, Object> repParams = Maps.newHashMap();
|
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(tgtSA.getHostCard());
|
||||||
repParams.put("TgtSA", tgtSA);
|
repParams.put(AbilityKey.TgtSA, tgtSA);
|
||||||
repParams.put("Affected", tgtSA.getHostCard());
|
repParams.put(AbilityKey.Cause, srcSA.getHostCard());
|
||||||
repParams.put("Cause", srcSA.getHostCard());
|
|
||||||
if (game.getReplacementHandler().run(ReplacementType.Counter, repParams) != ReplacementResult.NotReplaced) {
|
if (game.getReplacementHandler().run(ReplacementType.Counter, repParams) != ReplacementResult.NotReplaced) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package forge.game.ability.effects;
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.SpellAbilityEffect;
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
@@ -11,6 +12,6 @@ import forge.game.spellability.SpellAbility;
|
|||||||
public class ETBReplacementEffect extends SpellAbilityEffect {
|
public class ETBReplacementEffect extends SpellAbilityEffect {
|
||||||
@Override
|
@Override
|
||||||
public void resolve(SpellAbility sa) {
|
public void resolve(SpellAbility sa) {
|
||||||
sa.getActivatingPlayer().getGame().getAction().moveToPlay(((Card) sa.getReplacingObject("Card")), sa);
|
sa.getActivatingPlayer().getGame().getAction().moveToPlay(((Card) sa.getReplacingObject(AbilityKey.Card)), sa);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ public abstract class RegenerateBaseEffect extends SpellAbilityEffect {
|
|||||||
+ " | TriggerDescription$ " + trigSA.getDescription();
|
+ " | TriggerDescription$ " + trigSA.getDescription();
|
||||||
final Trigger trigger = TriggerHandler.parseTrigger(trigStr, eff, true);
|
final Trigger trigger = TriggerHandler.parseTrigger(trigStr, eff, true);
|
||||||
trigger.setOverridingAbility(trigSA);
|
trigger.setOverridingAbility(trigSA);
|
||||||
eff.moveTrigger(trigger);
|
eff.addTrigger(trigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy text changes
|
// Copy text changes
|
||||||
|
|||||||
@@ -2,10 +2,9 @@ package forge.game.ability.effects;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.SpellAbilityEffect;
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
@@ -31,10 +30,10 @@ public class ReplaceDamageEffect extends SpellAbilityEffect {
|
|||||||
String varValue = sa.getParamOrDefault("VarName", "1");
|
String varValue = sa.getParamOrDefault("VarName", "1");
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Map<String, Object> originalParams = (Map<String, Object>) sa.getReplacingObject("OriginalParams");
|
Map<AbilityKey, Object> originalParams = (Map<AbilityKey, Object>) sa.getReplacingObject(AbilityKey.OriginalParams);
|
||||||
Map<String, Object> params = Maps.newHashMap(originalParams);
|
Map<AbilityKey, Object> params = AbilityKey.newMap(originalParams);
|
||||||
|
|
||||||
Integer dmg = (Integer) sa.getReplacingObject("DamageAmount");
|
Integer dmg = (Integer) sa.getReplacingObject(AbilityKey.DamageAmount);
|
||||||
|
|
||||||
int prevent = AbilityUtils.calculateAmount(card, varValue, sa);
|
int prevent = AbilityUtils.calculateAmount(card, varValue, sa);
|
||||||
|
|
||||||
@@ -54,10 +53,10 @@ public class ReplaceDamageEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
// no damage for original target anymore
|
// no damage for original target anymore
|
||||||
if (dmg <= 0) {
|
if (dmg <= 0) {
|
||||||
originalParams.put("ReplacementResult", ReplacementResult.Replaced);
|
originalParams.put(AbilityKey.ReplacementResult, ReplacementResult.Replaced);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
params.put("DamageAmount", dmg);
|
params.put(AbilityKey.DamageAmount, dmg);
|
||||||
|
|
||||||
|
|
||||||
//try to call replacementHandler with new Params
|
//try to call replacementHandler with new Params
|
||||||
@@ -65,16 +64,16 @@ public class ReplaceDamageEffect extends SpellAbilityEffect {
|
|||||||
switch (result) {
|
switch (result) {
|
||||||
case NotReplaced:
|
case NotReplaced:
|
||||||
case Updated: {
|
case Updated: {
|
||||||
for (Map.Entry<String, Object> e : params.entrySet()) {
|
for (Map.Entry<AbilityKey, Object> e : params.entrySet()) {
|
||||||
originalParams.put(e.getKey(), e.getValue());
|
originalParams.put(e.getKey(), e.getValue());
|
||||||
}
|
}
|
||||||
// effect was updated
|
// effect was updated
|
||||||
originalParams.put("ReplacementResult", ReplacementResult.Updated);
|
originalParams.put(AbilityKey.ReplacementResult, ReplacementResult.Updated);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// effect was replaced with something else
|
// effect was replaced with something else
|
||||||
originalParams.put("ReplacementResult", result);
|
originalParams.put(AbilityKey.ReplacementResult, result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.google.common.collect.Maps;
|
|||||||
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.GameObject;
|
import forge.game.GameObject;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.SpellAbilityEffect;
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
@@ -23,14 +24,14 @@ public class ReplaceEffect extends SpellAbilityEffect {
|
|||||||
final Card card = sa.getHostCard();
|
final Card card = sa.getHostCard();
|
||||||
final Game game = card.getGame();
|
final Game game = card.getGame();
|
||||||
|
|
||||||
final String varName = sa.getParam("VarName");
|
final AbilityKey varName = AbilityKey.fromString(sa.getParam("VarName"));
|
||||||
final String varValue = sa.getParam("VarValue");
|
final String varValue = sa.getParam("VarValue");
|
||||||
final String type = sa.getParamOrDefault("VarType", "amount");
|
final String type = sa.getParamOrDefault("VarType", "amount");
|
||||||
final ReplacementType retype = sa.getReplacementEffect().getMode();
|
final ReplacementType retype = sa.getReplacementEffect().getMode();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Map<String, Object> originalParams = (Map<String, Object>) sa.getReplacingObject("OriginalParams");
|
Map<AbilityKey, Object> originalParams = (Map<AbilityKey, Object>) sa.getReplacingObject(AbilityKey.OriginalParams);
|
||||||
Map<String, Object> params = Maps.newHashMap(originalParams);
|
Map<AbilityKey, Object> params = Maps.newHashMap(originalParams);
|
||||||
|
|
||||||
if ("Card".equals(type)) {
|
if ("Card".equals(type)) {
|
||||||
List<Card> list = AbilityUtils.getDefinedCards(card, varValue, sa);
|
List<Card> list = AbilityUtils.getDefinedCards(card, varValue, sa);
|
||||||
@@ -56,8 +57,8 @@ public class ReplaceEffect extends SpellAbilityEffect {
|
|||||||
params.put(varName, AbilityUtils.calculateAmount(card, varValue, sa));
|
params.put(varName, AbilityUtils.calculateAmount(card, varValue, sa));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.containsKey("EffectOnly")) {
|
if (params.containsKey(AbilityKey.EffectOnly)) {
|
||||||
params.put("EffectOnly", true);
|
params.put(AbilityKey.EffectOnly, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//try to call replacementHandler with new Params
|
//try to call replacementHandler with new Params
|
||||||
@@ -65,16 +66,16 @@ public class ReplaceEffect extends SpellAbilityEffect {
|
|||||||
switch (result) {
|
switch (result) {
|
||||||
case NotReplaced:
|
case NotReplaced:
|
||||||
case Updated: {
|
case Updated: {
|
||||||
for (Map.Entry<String, Object> e : params.entrySet()) {
|
for (Map.Entry<AbilityKey, Object> e : params.entrySet()) {
|
||||||
originalParams.put(e.getKey(), e.getValue());
|
originalParams.put(e.getKey(), e.getValue());
|
||||||
}
|
}
|
||||||
// effect was updated
|
// effect was updated
|
||||||
originalParams.put("ReplacementResult", ReplacementResult.Updated);
|
originalParams.put(AbilityKey.ReplacementResult, ReplacementResult.Updated);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// effect was replaced with something else
|
// effect was replaced with something else
|
||||||
originalParams.put("ReplacementResult", result);
|
originalParams.put(AbilityKey.ReplacementResult, result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,9 @@ package forge.game.ability.effects;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.GameEntity;
|
import forge.game.GameEntity;
|
||||||
import forge.game.GameEntityCounterTable;
|
import forge.game.GameEntityCounterTable;
|
||||||
@@ -36,10 +35,10 @@ public class ReplaceSplitDamageEffect extends SpellAbilityEffect {
|
|||||||
String varValue = sa.getParamOrDefault("VarName", "1");
|
String varValue = sa.getParamOrDefault("VarName", "1");
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Map<String, Object> originalParams = (Map<String, Object>) sa.getReplacingObject("OriginalParams");
|
Map<AbilityKey, Object> originalParams = (Map<AbilityKey , Object>) sa.getReplacingObject(AbilityKey.OriginalParams);
|
||||||
Map<String, Object> params = Maps.newHashMap(originalParams);
|
Map<AbilityKey, Object> params = AbilityKey.newMap(originalParams);
|
||||||
|
|
||||||
Integer dmg = (Integer) sa.getReplacingObject("DamageAmount");
|
Integer dmg = (Integer) sa.getReplacingObject(AbilityKey.DamageAmount);
|
||||||
|
|
||||||
|
|
||||||
int prevent = AbilityUtils.calculateAmount(card, varValue, sa);
|
int prevent = AbilityUtils.calculateAmount(card, varValue, sa);
|
||||||
@@ -57,15 +56,15 @@ public class ReplaceSplitDamageEffect extends SpellAbilityEffect {
|
|||||||
card.setSVar(varValue, "Number$" + prevent);
|
card.setSVar(varValue, "Number$" + prevent);
|
||||||
}
|
}
|
||||||
|
|
||||||
Card sourceLKI = (Card) sa.getReplacingObject("Source");
|
Card sourceLKI = (Card) sa.getReplacingObject(AbilityKey.Source);
|
||||||
|
|
||||||
CardDamageMap damageMap = (CardDamageMap) originalParams.get("DamageMap");
|
CardDamageMap damageMap = (CardDamageMap) originalParams.get(AbilityKey.DamageMap);
|
||||||
CardDamageMap preventMap = (CardDamageMap) originalParams.get("PreventMap");
|
CardDamageMap preventMap = (CardDamageMap) originalParams.get(AbilityKey.PreventMap);
|
||||||
GameEntityCounterTable counterTable = (GameEntityCounterTable) originalParams.get("CounterTable");
|
GameEntityCounterTable counterTable = (GameEntityCounterTable) originalParams.get(AbilityKey.CounterTable);
|
||||||
SpellAbility cause = (SpellAbility) originalParams.get("Cause");
|
SpellAbility cause = (SpellAbility) originalParams.get(AbilityKey.Cause);
|
||||||
|
|
||||||
boolean isCombat = (Boolean) originalParams.get("IsCombat");
|
boolean isCombat = (Boolean) originalParams.get(AbilityKey.IsCombat);
|
||||||
boolean noPrevention = (Boolean) originalParams.get("NoPreventDamage");
|
boolean noPrevention = (Boolean) originalParams.get(AbilityKey.NoPreventDamage);
|
||||||
|
|
||||||
GameEntity obj = (GameEntity) list.get(0);
|
GameEntity obj = (GameEntity) list.get(0);
|
||||||
|
|
||||||
@@ -74,26 +73,26 @@ public class ReplaceSplitDamageEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
// no damage for original target anymore
|
// no damage for original target anymore
|
||||||
if (dmg <= 0) {
|
if (dmg <= 0) {
|
||||||
originalParams.put("ReplacementResult", ReplacementResult.Replaced);
|
originalParams.put(AbilityKey.ReplacementResult, ReplacementResult.Replaced);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
params.put("DamageAmount", dmg);
|
params.put(AbilityKey.DamageAmount, dmg);
|
||||||
|
|
||||||
//try to call replacementHandler with new Params
|
//try to call replacementHandler with new Params
|
||||||
ReplacementResult result = game.getReplacementHandler().run(event, params);
|
ReplacementResult result = game.getReplacementHandler().run(event, params);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case NotReplaced:
|
case NotReplaced:
|
||||||
case Updated: {
|
case Updated: {
|
||||||
for (Map.Entry<String, Object> e : params.entrySet()) {
|
for (Map.Entry<AbilityKey, Object> e : params.entrySet()) {
|
||||||
originalParams.put(e.getKey(), e.getValue());
|
originalParams.put(e.getKey(), e.getValue());
|
||||||
}
|
}
|
||||||
// effect was updated
|
// effect was updated
|
||||||
originalParams.put("ReplacementResult", ReplacementResult.Updated);
|
originalParams.put(AbilityKey.ReplacementResult, ReplacementResult.Updated);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// effect was replaced with something else
|
// effect was replaced with something else
|
||||||
originalParams.put("ReplacementResult", result);
|
originalParams.put(AbilityKey.ReplacementResult, result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ public class RestartGameEffect extends SpellAbilityEffect {
|
|||||||
forge.game.trigger.Trigger.resetIDs();
|
forge.game.trigger.Trigger.resetIDs();
|
||||||
TriggerHandler trigHandler = game.getTriggerHandler();
|
TriggerHandler trigHandler = game.getTriggerHandler();
|
||||||
trigHandler.clearDelayedTrigger();
|
trigHandler.clearDelayedTrigger();
|
||||||
trigHandler.cleanUpTemporaryTriggers();
|
|
||||||
trigHandler.suppressMode(TriggerType.ChangesZone);
|
trigHandler.suppressMode(TriggerType.ChangesZone);
|
||||||
|
|
||||||
game.getStack().reset();
|
game.getStack().reset();
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.token.TokenInfo;
|
import forge.game.card.token.TokenInfo;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
@@ -224,8 +225,11 @@ public class TokenEffect extends SpellAbilityEffect {
|
|||||||
// Cause of the Token Effect, in general it should be this
|
// Cause of the Token Effect, in general it should be this
|
||||||
// but if its a Replacement Effect, it might be something else or null
|
// but if its a Replacement Effect, it might be something else or null
|
||||||
SpellAbility cause = sa;
|
SpellAbility cause = sa;
|
||||||
if (root.isReplacementAbility() && root.hasReplacingObject("Cause")) {
|
if (root.isReplacementAbility()) {
|
||||||
cause = (SpellAbility)root.getReplacingObject("Cause");
|
Object replacingObject = root.getReplacingObject(AbilityKey.Cause);
|
||||||
|
if (replacingObject != null) {
|
||||||
|
cause = (SpellAbility) replacingObject;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean remember = sa.hasParam("RememberTokens");
|
final boolean remember = sa.hasParam("RememberTokens");
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
package forge.game.card;
|
package forge.game.card;
|
||||||
|
|
||||||
import com.esotericsoftware.minlog.Log;
|
import com.esotericsoftware.minlog.Log;
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.*;
|
import com.google.common.collect.*;
|
||||||
import forge.GameCommand;
|
import forge.GameCommand;
|
||||||
@@ -121,6 +122,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
private final Map<Long, CardChangedType> changedCardTypes = Maps.newTreeMap();
|
private final Map<Long, CardChangedType> changedCardTypes = Maps.newTreeMap();
|
||||||
private final NavigableMap<Long, String> changedCardNames = Maps.newTreeMap();
|
private final NavigableMap<Long, String> changedCardNames = Maps.newTreeMap();
|
||||||
private final Map<Long, KeywordsChange> changedCardKeywords = Maps.newTreeMap();
|
private final Map<Long, KeywordsChange> changedCardKeywords = Maps.newTreeMap();
|
||||||
|
private final Map<Long, CardTraitChanges> changedCardTraits = Maps.newTreeMap();
|
||||||
private final Map<Long, CardColor> changedCardColors = Maps.newTreeMap();
|
private final Map<Long, CardColor> changedCardColors = Maps.newTreeMap();
|
||||||
private final NavigableMap<Long, CardCloneStates> clonedStates = Maps.newTreeMap();
|
private final NavigableMap<Long, CardCloneStates> clonedStates = Maps.newTreeMap();
|
||||||
private final NavigableMap<Long, CardCloneStates> textChangeStates = Maps.newTreeMap();
|
private final NavigableMap<Long, CardCloneStates> textChangeStates = Maps.newTreeMap();
|
||||||
@@ -687,9 +689,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
|
|
||||||
if (result && runTriggers) {
|
if (result && runTriggers) {
|
||||||
// Run replacement effects
|
// Run replacement effects
|
||||||
Map<String, Object> repParams = Maps.newHashMap();
|
getGame().getReplacementHandler().run(ReplacementType.TurnFaceUp, AbilityKey.mapFromAffected(this));
|
||||||
repParams.put("Affected", this);
|
|
||||||
getGame().getReplacementHandler().run(ReplacementType.TurnFaceUp, repParams);
|
|
||||||
|
|
||||||
// Run triggers
|
// Run triggers
|
||||||
getGame().getTriggerHandler().registerActiveTrigger(this, false);
|
getGame().getTriggerHandler().registerActiveTrigger(this, false);
|
||||||
@@ -1012,28 +1012,15 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
public final FCollectionView<Trigger> getTriggers() {
|
public final FCollectionView<Trigger> getTriggers() {
|
||||||
return currentState.getTriggers();
|
return currentState.getTriggers();
|
||||||
}
|
}
|
||||||
// only used for LKI
|
|
||||||
public final void setTriggers(final Iterable<Trigger> trigs, boolean intrinsicOnly) {
|
|
||||||
final FCollection<Trigger> copyList = new FCollection<>();
|
|
||||||
for (final Trigger t : trigs) {
|
|
||||||
if (!intrinsicOnly || t.isIntrinsic()) {
|
|
||||||
copyList.add(t.copy(this, true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentState.setTriggers(copyList);
|
|
||||||
}
|
|
||||||
public final Trigger addTrigger(final Trigger t) {
|
public final Trigger addTrigger(final Trigger t) {
|
||||||
final Trigger newtrig = t.copy(this, false);
|
|
||||||
currentState.addTrigger(newtrig);
|
|
||||||
return newtrig;
|
|
||||||
}
|
|
||||||
public final void moveTrigger(final Trigger t) {
|
|
||||||
t.setHostCard(this);
|
|
||||||
currentState.addTrigger(t);
|
currentState.addTrigger(t);
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
|
@Deprecated
|
||||||
public final void removeTrigger(final Trigger t) {
|
public final void removeTrigger(final Trigger t) {
|
||||||
currentState.removeTrigger(t);
|
currentState.removeTrigger(t);
|
||||||
}
|
}
|
||||||
|
@Deprecated
|
||||||
public final void removeTrigger(final Trigger t, final CardStateName state) {
|
public final void removeTrigger(final Trigger t, final CardStateName state) {
|
||||||
getState(state).removeTrigger(t);
|
getState(state).removeTrigger(t);
|
||||||
}
|
}
|
||||||
@@ -1050,6 +1037,25 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateTriggers(List<Trigger> list, CardState state) {
|
public void updateTriggers(List<Trigger> list, CardState state) {
|
||||||
|
|
||||||
|
boolean removeIntrinsic = false;
|
||||||
|
for (final CardTraitChanges ck : changedCardTraits.values()) {
|
||||||
|
if (ck.isRemoveIntrinsic()) {
|
||||||
|
removeIntrinsic = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (removeIntrinsic) {
|
||||||
|
list.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final CardTraitChanges ck : changedCardTraits.values()) {
|
||||||
|
if (ck.isRemoveAll()) {
|
||||||
|
list.clear();
|
||||||
|
}
|
||||||
|
list.addAll(ck.getTriggers());
|
||||||
|
}
|
||||||
|
|
||||||
for (KeywordInterface kw : getUnhiddenKeywords(state)) {
|
for (KeywordInterface kw : getUnhiddenKeywords(state)) {
|
||||||
list.addAll(kw.getTriggers());
|
list.addAll(kw.getTriggers());
|
||||||
}
|
}
|
||||||
@@ -1233,18 +1239,17 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
addAmount = 0; // As per rule 107.1b
|
addAmount = 0; // As per rule 107.1b
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
final Map<String, Object> repParams = Maps.newHashMap();
|
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
|
||||||
repParams.put("Affected", this);
|
repParams.put(AbilityKey.Source, source);
|
||||||
repParams.put("Source", source);
|
repParams.put(AbilityKey.CounterType, counterType);
|
||||||
repParams.put("CounterType", counterType);
|
repParams.put(AbilityKey.CounterNum, addAmount);
|
||||||
repParams.put("CounterNum", addAmount);
|
repParams.put(AbilityKey.EffectOnly, applyMultiplier);
|
||||||
repParams.put("EffectOnly", applyMultiplier);
|
|
||||||
|
|
||||||
switch (getGame().getReplacementHandler().run(ReplacementType.AddCounter, repParams)) {
|
switch (getGame().getReplacementHandler().run(ReplacementType.AddCounter, repParams)) {
|
||||||
case NotReplaced:
|
case NotReplaced:
|
||||||
break;
|
break;
|
||||||
case Updated: {
|
case Updated: {
|
||||||
addAmount = (int) repParams.get("CounterNum");
|
addAmount = (int) repParams.get(AbilityKey.CounterNum);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -2379,10 +2384,12 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void removeSpellAbility(final SpellAbility a) {
|
public final void removeSpellAbility(final SpellAbility a) {
|
||||||
removeSpellAbility(a, true);
|
removeSpellAbility(a, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void removeSpellAbility(final SpellAbility a, final boolean updateView) {
|
public final void removeSpellAbility(final SpellAbility a, final boolean updateView) {
|
||||||
if (currentState.removeSpellAbility(a) && updateView) {
|
if (currentState.removeSpellAbility(a) && updateView) {
|
||||||
currentState.getView().updateAbilityText(this, currentState);
|
currentState.getView().updateAbilityText(this, currentState);
|
||||||
@@ -2408,15 +2415,44 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateSpellAbilities(List<SpellAbility> list, CardState state, Boolean mana) {
|
public void updateSpellAbilities(List<SpellAbility> list, CardState state, Boolean mana) {
|
||||||
|
|
||||||
|
boolean removeIntrinsic = false;
|
||||||
|
for (final CardTraitChanges ck : changedCardTraits.values()) {
|
||||||
|
if (ck.isRemoveIntrinsic()) {
|
||||||
|
removeIntrinsic = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (removeIntrinsic) {
|
||||||
|
list.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// do Basic Land Abilities there
|
// do Basic Land Abilities there
|
||||||
if (mana == null || mana == true) {
|
if (null == mana || true == mana) {
|
||||||
updateBasicLandAbilities(list, state);
|
updateBasicLandAbilities(list, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (final CardTraitChanges ck : changedCardTraits.values()) {
|
||||||
|
if (ck.isRemoveNonMana()) {
|
||||||
|
// List only has nonMana
|
||||||
|
if (null == mana) {
|
||||||
|
List<SpellAbility> toRemove = Lists.newArrayList(
|
||||||
|
Iterables.filter(list, Predicates.not(SpellAbilityPredicates.isManaAbility())));
|
||||||
|
list.removeAll(toRemove);
|
||||||
|
} else if (false == mana) {
|
||||||
|
list.clear();
|
||||||
|
}
|
||||||
|
} else if (ck.isRemoveAll()) {
|
||||||
|
list.clear();
|
||||||
|
}
|
||||||
|
list.removeAll(ck.getRemovedAbilities());
|
||||||
|
list.addAll(ck.getAbilities());
|
||||||
|
}
|
||||||
|
|
||||||
// add Facedown abilities from Original state but only if this state is face down
|
// add Facedown abilities from Original state but only if this state is face down
|
||||||
// need CardStateView#getState or might crash in StackOverflow
|
// need CardStateView#getState or might crash in StackOverflow
|
||||||
if (isInZone(ZoneType.Battlefield)) {
|
if (isInZone(ZoneType.Battlefield)) {
|
||||||
if ((mana == null || mana == false) && isFaceDown() && state.getView().getState() == CardStateName.FaceDown) {
|
if ((null == mana || false == mana) && isFaceDown() && state.getView().getState() == CardStateName.FaceDown) {
|
||||||
for (SpellAbility sa : getState(CardStateName.Original).getNonManaAbilities()) {
|
for (SpellAbility sa : getState(CardStateName.Original).getNonManaAbilities()) {
|
||||||
if (sa.isManifestUp() || sa.isMorphUp()) {
|
if (sa.isManifestUp() || sa.isMorphUp()) {
|
||||||
list.add(sa);
|
list.add(sa);
|
||||||
@@ -2729,14 +2765,14 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
*
|
*
|
||||||
* Control, Controller: "Control" is the system that determines who gets to use an object in the game.
|
* Control, Controller: "Control" is the system that determines who gets to use an object in the game.
|
||||||
* An object's "controller" is the player who currently controls it. See rule 108.4.
|
* An object's "controller" is the player who currently controls it. See rule 108.4.
|
||||||
*
|
*
|
||||||
* 400.6. If an object would move from one zone to another, determine what event is moving the object.
|
* 400.6. If an object would move from one zone to another, determine what event is moving the object.
|
||||||
* If the object is moving to a public zone and its owner will be able to look at it in that zone,
|
* If the object is moving to a public zone and its owner will be able to look at it in that zone,
|
||||||
* its owner looks at it to see if it has any abilities that would affect the move.
|
* its owner looks at it to see if it has any abilities that would affect the move.
|
||||||
* If the object is moving to the battlefield, each other player who will be able to look at it in that
|
* If the object is moving to the battlefield, each other player who will be able to look at it in that
|
||||||
* zone does so. Then any appropriate replacement effects, whether they come from that object or from
|
* zone does so. Then any appropriate replacement effects, whether they come from that object or from
|
||||||
* elsewhere, are applied to that event. If any effects or rules try to do two or more contradictory or
|
* elsewhere, are applied to that event. If any effects or rules try to do two or more contradictory or
|
||||||
* mutually exclusive things to a particular object, that object’s CONTROLLER—or its OWNER
|
* mutually exclusive things to a particular object, that object’s CONTROLLER—or its OWNER
|
||||||
* IF IT HAS NO CONTROLLER—chooses which effect to apply, and what that effect does.
|
* IF IT HAS NO CONTROLLER—chooses which effect to apply, and what that effect does.
|
||||||
*/
|
*/
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
@@ -3572,10 +3608,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
if (!tapped) { return; }
|
if (!tapped) { return; }
|
||||||
|
|
||||||
// Run Replacement effects
|
// Run Replacement effects
|
||||||
final Map<String, Object> repRunParams = Maps.newHashMap();
|
if (getGame().getReplacementHandler().run(ReplacementType.Untap, AbilityKey.mapFromAffected(this)) != ReplacementResult.NotReplaced) {
|
||||||
repRunParams.put("Affected", this);
|
|
||||||
|
|
||||||
if (getGame().getReplacementHandler().run(ReplacementType.Untap, repRunParams) != ReplacementResult.NotReplaced) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3589,6 +3622,31 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
getGame().fireEvent(new GameEventCardTapped(this, false));
|
getGame().fireEvent(new GameEventCardTapped(this, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void addChangedCardTraits(Collection<SpellAbility> spells, Collection<SpellAbility> removedAbilities,
|
||||||
|
Collection<Trigger> trigger, Collection<ReplacementEffect> replacements, Collection<StaticAbility> statics,
|
||||||
|
boolean removeAll, boolean removeNonMana, boolean removeIntrinsic, long timestamp) {
|
||||||
|
changedCardTraits.put(timestamp, new CardTraitChanges(
|
||||||
|
spells, removedAbilities, trigger, replacements, statics, removeAll, removeNonMana, removeIntrinsic
|
||||||
|
));
|
||||||
|
// update view
|
||||||
|
updateAbilityTextForView();
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean removeChangedCardTraits(long timestamp) {
|
||||||
|
return changedCardTraits.remove(timestamp) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Map<Long, CardTraitChanges> getChangedCardTraits() {
|
||||||
|
return changedCardTraits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setChangedCardTraits(Map<Long, CardTraitChanges> changes) {
|
||||||
|
changedCardTraits.clear();
|
||||||
|
for (Entry<Long, CardTraitChanges> e : changes.entrySet()) {
|
||||||
|
changedCardTraits.put(e.getKey(), e.getValue().copy(this, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// keywords are like flying, fear, first strike, etc...
|
// keywords are like flying, fear, first strike, etc...
|
||||||
public final List<KeywordInterface> getKeywords() {
|
public final List<KeywordInterface> getKeywords() {
|
||||||
return getKeywords(currentState);
|
return getKeywords(currentState);
|
||||||
@@ -4018,11 +4076,31 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
currentState.addStaticAbility(stAb);
|
currentState.addStaticAbility(stAb);
|
||||||
return stAb;
|
return stAb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void removeStaticAbility(StaticAbility stAb) {
|
public final void removeStaticAbility(StaticAbility stAb) {
|
||||||
currentState.removeStaticAbility(stAb);
|
currentState.removeStaticAbility(stAb);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateStaticAbilities(List<StaticAbility> list, CardState state) {
|
public void updateStaticAbilities(List<StaticAbility> list, CardState state) {
|
||||||
|
boolean removeIntrinsic = false;
|
||||||
|
for (final CardTraitChanges ck : changedCardTraits.values()) {
|
||||||
|
if (ck.isRemoveIntrinsic()) {
|
||||||
|
removeIntrinsic = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (removeIntrinsic) {
|
||||||
|
list.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final CardTraitChanges ck : changedCardTraits.values()) {
|
||||||
|
if (ck.isRemoveAll()) {
|
||||||
|
list.clear();
|
||||||
|
}
|
||||||
|
list.addAll(ck.getStaticAbilities());
|
||||||
|
}
|
||||||
|
|
||||||
for (KeywordInterface kw : getUnhiddenKeywords(state)) {
|
for (KeywordInterface kw : getUnhiddenKeywords(state)) {
|
||||||
list.addAll(kw.getStaticAbilities());
|
list.addAll(kw.getStaticAbilities());
|
||||||
}
|
}
|
||||||
@@ -5641,24 +5719,35 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
return currentState.getReplacementEffects();
|
return currentState.getReplacementEffects();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setReplacementEffects(final Iterable<ReplacementEffect> res) {
|
|
||||||
currentState.clearReplacementEffects();
|
|
||||||
for (final ReplacementEffect replacementEffect : res) {
|
|
||||||
if (replacementEffect.isIntrinsic()) {
|
|
||||||
addReplacementEffect(replacementEffect.copy(this, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReplacementEffect addReplacementEffect(final ReplacementEffect replacementEffect) {
|
public ReplacementEffect addReplacementEffect(final ReplacementEffect replacementEffect) {
|
||||||
currentState.addReplacementEffect(replacementEffect);
|
currentState.addReplacementEffect(replacementEffect);
|
||||||
return replacementEffect;
|
return replacementEffect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void removeReplacementEffect(ReplacementEffect replacementEffect) {
|
public void removeReplacementEffect(ReplacementEffect replacementEffect) {
|
||||||
currentState.removeReplacementEffect(replacementEffect);
|
currentState.removeReplacementEffect(replacementEffect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateReplacementEffects(List<ReplacementEffect> list, CardState state) {
|
public void updateReplacementEffects(List<ReplacementEffect> list, CardState state) {
|
||||||
|
|
||||||
|
boolean removeIntrinsic = false;
|
||||||
|
for (final CardTraitChanges ck : changedCardTraits.values()) {
|
||||||
|
if (ck.isRemoveIntrinsic()) {
|
||||||
|
removeIntrinsic = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (removeIntrinsic) {
|
||||||
|
list.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final CardTraitChanges ck : changedCardTraits.values()) {
|
||||||
|
if (ck.isRemoveAll()) {
|
||||||
|
list.clear();
|
||||||
|
}
|
||||||
|
list.addAll(ck.getReplacements());
|
||||||
|
}
|
||||||
for (KeywordInterface kw : getUnhiddenKeywords(state)) {
|
for (KeywordInterface kw : getUnhiddenKeywords(state)) {
|
||||||
list.addAll(kw.getReplacements());
|
list.addAll(kw.getReplacements());
|
||||||
}
|
}
|
||||||
@@ -6296,27 +6385,6 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
withFlash.removeAll(timestamp);
|
withFlash.removeAll(timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unSuppressCardTraits() {
|
|
||||||
// specially reset basic land abilities
|
|
||||||
for (final SpellAbility ab : basicLandAbilities) {
|
|
||||||
if (ab != null) {
|
|
||||||
ab.setTemporarilySuppressed(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (final SpellAbility ab : getSpellAbilities()) {
|
|
||||||
ab.setTemporarilySuppressed(false);
|
|
||||||
}
|
|
||||||
for (final Trigger t : getTriggers()) {
|
|
||||||
t.setTemporarilySuppressed(false);
|
|
||||||
}
|
|
||||||
for (final StaticAbility stA : getStaticAbilities()) {
|
|
||||||
stA.setTemporarilySuppressed(false);
|
|
||||||
}
|
|
||||||
for (final ReplacementEffect rE : getReplacementEffects()) {
|
|
||||||
rE.setTemporarilySuppressed(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canBeDiscardedBy(SpellAbility sa) {
|
public boolean canBeDiscardedBy(SpellAbility sa) {
|
||||||
if (!isInZone(ZoneType.Hand)) {
|
if (!isInZone(ZoneType.Hand)) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -3758,7 +3758,6 @@ public class CardFactoryUtil {
|
|||||||
newSA.setDescription(sa.getDescription() + " (by paying " + cost.toSimpleString() + " instead of its mana cost)");
|
newSA.setDescription(sa.getDescription() + " (by paying " + cost.toSimpleString() + " instead of its mana cost)");
|
||||||
newSA.setIntrinsic(intrinsic);
|
newSA.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
newSA.setTemporary(intrinsic);
|
|
||||||
inst.addSpellAbility(newSA);
|
inst.addSpellAbility(newSA);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3788,8 +3787,6 @@ public class CardFactoryUtil {
|
|||||||
|
|
||||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||||
sa.setIntrinsic(intrinsic);
|
sa.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
} else if (keyword.equals("Aftermath") && card.getCurrentStateName().equals(CardStateName.RightSplit)) {
|
} else if (keyword.equals("Aftermath") && card.getCurrentStateName().equals(CardStateName.RightSplit)) {
|
||||||
// Aftermath does modify existing SA, and does not add new one
|
// Aftermath does modify existing SA, and does not add new one
|
||||||
@@ -3809,8 +3806,6 @@ public class CardFactoryUtil {
|
|||||||
|
|
||||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||||
sa.setIntrinsic(intrinsic);
|
sa.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
} else if (keyword.startsWith("Awaken")) {
|
} else if (keyword.startsWith("Awaken")) {
|
||||||
final String[] k = keyword.split(":");
|
final String[] k = keyword.split(":");
|
||||||
@@ -3835,8 +3830,6 @@ public class CardFactoryUtil {
|
|||||||
awakenSpell.setBasicSpell(false);
|
awakenSpell.setBasicSpell(false);
|
||||||
awakenSpell.setPayCosts(awakenCost);
|
awakenSpell.setPayCosts(awakenCost);
|
||||||
awakenSpell.setIntrinsic(intrinsic);
|
awakenSpell.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
awakenSpell.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(awakenSpell);
|
inst.addSpellAbility(awakenSpell);
|
||||||
} else if (keyword.startsWith("Bestow")) {
|
} else if (keyword.startsWith("Bestow")) {
|
||||||
final String[] params = keyword.split(":");
|
final String[] params = keyword.split(":");
|
||||||
@@ -3854,8 +3847,6 @@ public class CardFactoryUtil {
|
|||||||
sa.setStackDescription("Bestow - " + card.getName());
|
sa.setStackDescription("Bestow - " + card.getName());
|
||||||
sa.setBasicSpell(false);
|
sa.setBasicSpell(false);
|
||||||
sa.setIntrinsic(intrinsic);
|
sa.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
} else if (keyword.startsWith("Dash")) {
|
} else if (keyword.startsWith("Dash")) {
|
||||||
final String[] k = keyword.split(":");
|
final String[] k = keyword.split(":");
|
||||||
@@ -3865,8 +3856,6 @@ public class CardFactoryUtil {
|
|||||||
|
|
||||||
final SpellAbility newSA = AbilityFactory.getAbility(dashString, card);
|
final SpellAbility newSA = AbilityFactory.getAbility(dashString, card);
|
||||||
newSA.setIntrinsic(intrinsic);
|
newSA.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
newSA.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(newSA);
|
inst.addSpellAbility(newSA);
|
||||||
} else if (keyword.startsWith("Emerge")) {
|
} else if (keyword.startsWith("Emerge")) {
|
||||||
final String[] kw = keyword.split(":");
|
final String[] kw = keyword.split(":");
|
||||||
@@ -3882,8 +3871,6 @@ public class CardFactoryUtil {
|
|||||||
newSA.setPayCosts(new Cost(costStr, false));
|
newSA.setPayCosts(new Cost(costStr, false));
|
||||||
newSA.setDescription(sa.getDescription() + " (Emerge)");
|
newSA.setDescription(sa.getDescription() + " (Emerge)");
|
||||||
newSA.setIntrinsic(intrinsic);
|
newSA.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
newSA.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(newSA);
|
inst.addSpellAbility(newSA);
|
||||||
} else if (keyword.startsWith("Embalm")) {
|
} else if (keyword.startsWith("Embalm")) {
|
||||||
final String[] kw = keyword.split(":");
|
final String[] kw = keyword.split(":");
|
||||||
@@ -3896,8 +3883,6 @@ public class CardFactoryUtil {
|
|||||||
"| SpellDescription$ (" + inst.getReminderText() + ")" ;
|
"| SpellDescription$ (" + inst.getReminderText() + ")" ;
|
||||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||||
sa.setIntrinsic(intrinsic);
|
sa.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
} else if (keyword.equals("Epic")) {
|
} else if (keyword.equals("Epic")) {
|
||||||
// Epic does modify existing SA, and does not add new one
|
// Epic does modify existing SA, and does not add new one
|
||||||
@@ -3952,7 +3937,6 @@ public class CardFactoryUtil {
|
|||||||
// instantiate attach ability
|
// instantiate attach ability
|
||||||
final SpellAbility newSA = AbilityFactory.getAbility(abilityStr.toString(), card);
|
final SpellAbility newSA = AbilityFactory.getAbility(abilityStr.toString(), card);
|
||||||
newSA.setIntrinsic(intrinsic);
|
newSA.setIntrinsic(intrinsic);
|
||||||
newSA.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(newSA);
|
inst.addSpellAbility(newSA);
|
||||||
} else if (keyword.startsWith("Eternalize")) {
|
} else if (keyword.startsWith("Eternalize")) {
|
||||||
final String[] kw = keyword.split(":");
|
final String[] kw = keyword.split(":");
|
||||||
@@ -3982,8 +3966,6 @@ public class CardFactoryUtil {
|
|||||||
.append("| SpellDescription$ (").append(inst.getReminderText()).append(")");
|
.append("| SpellDescription$ (").append(inst.getReminderText()).append(")");
|
||||||
final SpellAbility sa = AbilityFactory.getAbility(sb.toString(), card);
|
final SpellAbility sa = AbilityFactory.getAbility(sb.toString(), card);
|
||||||
sa.setIntrinsic(intrinsic);
|
sa.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
} else if (keyword.startsWith("Evoke")) {
|
} else if (keyword.startsWith("Evoke")) {
|
||||||
final String[] k = keyword.split(":");
|
final String[] k = keyword.split(":");
|
||||||
@@ -4005,8 +3987,6 @@ public class CardFactoryUtil {
|
|||||||
newSA.setBasicSpell(false);
|
newSA.setBasicSpell(false);
|
||||||
newSA.setEvoke(true);
|
newSA.setEvoke(true);
|
||||||
newSA.setIntrinsic(intrinsic);
|
newSA.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
newSA.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(newSA);
|
inst.addSpellAbility(newSA);
|
||||||
} else if (keyword.startsWith("Fortify")) {
|
} else if (keyword.startsWith("Fortify")) {
|
||||||
String[] k = keyword.split(":");
|
String[] k = keyword.split(":");
|
||||||
@@ -4027,14 +4007,10 @@ public class CardFactoryUtil {
|
|||||||
|
|
||||||
// instantiate attach ability
|
// instantiate attach ability
|
||||||
final SpellAbility sa = AbilityFactory.getAbility(abilityStr.toString(), card);
|
final SpellAbility sa = AbilityFactory.getAbility(abilityStr.toString(), card);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
} else if (keyword.startsWith("Fuse") && card.getCurrentStateName().equals(CardStateName.Original)) {
|
} else if (keyword.startsWith("Fuse") && card.getCurrentStateName().equals(CardStateName.Original)) {
|
||||||
final SpellAbility sa = AbilityFactory.buildFusedAbility(card);
|
final SpellAbility sa = AbilityFactory.buildFusedAbility(card);
|
||||||
card.addSpellAbility(sa);
|
card.addSpellAbility(sa);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
} else if (keyword.startsWith("Haunt")) {
|
} else if (keyword.startsWith("Haunt")) {
|
||||||
if (!card.isCreature() && intrinsic) {
|
if (!card.isCreature() && intrinsic) {
|
||||||
@@ -4067,8 +4043,6 @@ public class CardFactoryUtil {
|
|||||||
|
|
||||||
final SpellAbility sa = AbilityFactory.getAbility(sb.toString(), card);
|
final SpellAbility sa = AbilityFactory.getAbility(sb.toString(), card);
|
||||||
sa.setIntrinsic(intrinsic);
|
sa.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
} else if (keyword.startsWith("Monstrosity")) {
|
} else if (keyword.startsWith("Monstrosity")) {
|
||||||
final String[] k = keyword.split(":");
|
final String[] k = keyword.split(":");
|
||||||
@@ -4103,8 +4077,6 @@ public class CardFactoryUtil {
|
|||||||
|
|
||||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||||
sa.setIntrinsic(intrinsic);
|
sa.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
|
|
||||||
} else if (keyword.startsWith("Morph")) {
|
} else if (keyword.startsWith("Morph")) {
|
||||||
@@ -4146,8 +4118,6 @@ public class CardFactoryUtil {
|
|||||||
|
|
||||||
SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||||
sa.setIntrinsic(intrinsic);
|
sa.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
|
|
||||||
// extra secondary effect for Commander Ninjutsu
|
// extra secondary effect for Commander Ninjutsu
|
||||||
@@ -4161,8 +4131,6 @@ public class CardFactoryUtil {
|
|||||||
|
|
||||||
sa = AbilityFactory.getAbility(effect, card);
|
sa = AbilityFactory.getAbility(effect, card);
|
||||||
sa.setIntrinsic(intrinsic);
|
sa.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
}
|
}
|
||||||
} else if (keyword.startsWith("Outlast")) {
|
} else if (keyword.startsWith("Outlast")) {
|
||||||
@@ -4187,8 +4155,6 @@ public class CardFactoryUtil {
|
|||||||
|
|
||||||
final SpellAbility sa = AbilityFactory.getAbility(abilityStr.toString(), card);
|
final SpellAbility sa = AbilityFactory.getAbility(abilityStr.toString(), card);
|
||||||
sa.setIntrinsic(intrinsic);
|
sa.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
|
|
||||||
} else if (keyword.startsWith("Prowl")) {
|
} else if (keyword.startsWith("Prowl")) {
|
||||||
@@ -4212,7 +4178,6 @@ public class CardFactoryUtil {
|
|||||||
newSA.setProwl(true);
|
newSA.setProwl(true);
|
||||||
|
|
||||||
newSA.setIntrinsic(intrinsic);
|
newSA.setIntrinsic(intrinsic);
|
||||||
newSA.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(newSA);
|
inst.addSpellAbility(newSA);
|
||||||
} else if (keyword.startsWith("Reinforce")) {
|
} else if (keyword.startsWith("Reinforce")) {
|
||||||
final String[] k = keyword.split(":");
|
final String[] k = keyword.split(":");
|
||||||
@@ -4234,8 +4199,6 @@ public class CardFactoryUtil {
|
|||||||
if (n.equals("X")) {
|
if (n.equals("X")) {
|
||||||
sa.setSVar("X", "Count$xPaid");
|
sa.setSVar("X", "Count$xPaid");
|
||||||
}
|
}
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
} else if (keyword.startsWith("Scavenge")) {
|
} else if (keyword.startsWith("Scavenge")) {
|
||||||
final String[] k = keyword.split(":");
|
final String[] k = keyword.split(":");
|
||||||
@@ -4250,8 +4213,6 @@ public class CardFactoryUtil {
|
|||||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||||
sa.setSVar("ScavengeX", "Count$CardPower");
|
sa.setSVar("ScavengeX", "Count$CardPower");
|
||||||
sa.setIntrinsic(intrinsic);
|
sa.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
|
|
||||||
} else if (keyword.startsWith("Spectacle")) {
|
} else if (keyword.startsWith("Spectacle")) {
|
||||||
@@ -4267,8 +4228,6 @@ public class CardFactoryUtil {
|
|||||||
newSA.setDescription(desc);
|
newSA.setDescription(desc);
|
||||||
|
|
||||||
newSA.setIntrinsic(intrinsic);
|
newSA.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
newSA.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(newSA);
|
inst.addSpellAbility(newSA);
|
||||||
|
|
||||||
} else if (keyword.startsWith("Surge")) {
|
} else if (keyword.startsWith("Surge")) {
|
||||||
@@ -4284,8 +4243,6 @@ public class CardFactoryUtil {
|
|||||||
newSA.setDescription(desc);
|
newSA.setDescription(desc);
|
||||||
|
|
||||||
newSA.setIntrinsic(intrinsic);
|
newSA.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
newSA.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(newSA);
|
inst.addSpellAbility(newSA);
|
||||||
|
|
||||||
} else if (keyword.startsWith("Suspend") && !keyword.equals("Suspend")) {
|
} else if (keyword.startsWith("Suspend") && !keyword.equals("Suspend")) {
|
||||||
@@ -4336,8 +4293,6 @@ public class CardFactoryUtil {
|
|||||||
suspend.setStackDescription(sbStack.toString());
|
suspend.setStackDescription(sbStack.toString());
|
||||||
|
|
||||||
suspend.getRestrictions().setZone(ZoneType.Hand);
|
suspend.getRestrictions().setZone(ZoneType.Hand);
|
||||||
|
|
||||||
suspend.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(suspend);
|
inst.addSpellAbility(suspend);
|
||||||
} else if (keyword.startsWith("Transfigure")) {
|
} else if (keyword.startsWith("Transfigure")) {
|
||||||
final String[] k = keyword.split(":");
|
final String[] k = keyword.split(":");
|
||||||
@@ -4351,8 +4306,6 @@ public class CardFactoryUtil {
|
|||||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||||
sa.setSVar("TransfigureX", "Count$CardManaCost");
|
sa.setSVar("TransfigureX", "Count$CardManaCost");
|
||||||
sa.setIntrinsic(intrinsic);
|
sa.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
} else if (keyword.startsWith("Transmute")) {
|
} else if (keyword.startsWith("Transmute")) {
|
||||||
final String[] k = keyword.split(":");
|
final String[] k = keyword.split(":");
|
||||||
@@ -4367,8 +4320,6 @@ public class CardFactoryUtil {
|
|||||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||||
sa.setSVar("TransmuteX", "Count$CardManaCost");
|
sa.setSVar("TransmuteX", "Count$CardManaCost");
|
||||||
sa.setIntrinsic(intrinsic);
|
sa.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
} else if (keyword.startsWith("Unearth")) {
|
} else if (keyword.startsWith("Unearth")) {
|
||||||
final String[] k = keyword.split(":");
|
final String[] k = keyword.split(":");
|
||||||
@@ -4383,8 +4334,6 @@ public class CardFactoryUtil {
|
|||||||
|
|
||||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||||
sa.setIntrinsic(intrinsic);
|
sa.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
|
|
||||||
} else if (keyword.endsWith(" offering")) {
|
} else if (keyword.endsWith(" offering")) {
|
||||||
@@ -4403,8 +4352,6 @@ public class CardFactoryUtil {
|
|||||||
newSA.setPayCosts(sa.getPayCosts());
|
newSA.setPayCosts(sa.getPayCosts());
|
||||||
newSA.setDescription(sa.getDescription() + " (" + offeringType + " offering)");
|
newSA.setDescription(sa.getDescription() + " (" + offeringType + " offering)");
|
||||||
newSA.setIntrinsic(intrinsic);
|
newSA.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
newSA.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(newSA);
|
inst.addSpellAbility(newSA);
|
||||||
|
|
||||||
} else if (keyword.startsWith("Crew")) {
|
} else if (keyword.startsWith("Crew")) {
|
||||||
@@ -4420,8 +4367,6 @@ public class CardFactoryUtil {
|
|||||||
|
|
||||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||||
sa.setIntrinsic(intrinsic);
|
sa.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
|
|
||||||
} else if (keyword.startsWith("Cycling")) {
|
} else if (keyword.startsWith("Cycling")) {
|
||||||
@@ -4440,8 +4385,6 @@ public class CardFactoryUtil {
|
|||||||
SpellAbility sa = AbilityFactory.getAbility(sb.toString(), card);
|
SpellAbility sa = AbilityFactory.getAbility(sb.toString(), card);
|
||||||
sa.setIsCycling(true);
|
sa.setIsCycling(true);
|
||||||
sa.setIntrinsic(intrinsic);
|
sa.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
|
|
||||||
} else if (keyword.startsWith("TypeCycling")) {
|
} else if (keyword.startsWith("TypeCycling")) {
|
||||||
@@ -4466,8 +4409,6 @@ public class CardFactoryUtil {
|
|||||||
SpellAbility sa = AbilityFactory.getAbility(sb.toString(), card);
|
SpellAbility sa = AbilityFactory.getAbility(sb.toString(), card);
|
||||||
sa.setIsCycling(true);
|
sa.setIsCycling(true);
|
||||||
sa.setIntrinsic(intrinsic);
|
sa.setIntrinsic(intrinsic);
|
||||||
|
|
||||||
sa.setTemporary(!intrinsic);
|
|
||||||
inst.addSpellAbility(sa);
|
inst.addSpellAbility(sa);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
129
forge-game/src/main/java/forge/game/card/CardTraitChanges.java
Normal file
129
forge-game/src/main/java/forge/game/card/CardTraitChanges.java
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
package forge.game.card;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import forge.game.replacement.ReplacementEffect;
|
||||||
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.game.staticability.StaticAbility;
|
||||||
|
import forge.game.trigger.Trigger;
|
||||||
|
|
||||||
|
public class CardTraitChanges implements Cloneable {
|
||||||
|
|
||||||
|
private List<Trigger> triggers = Lists.newArrayList();
|
||||||
|
private List<ReplacementEffect> replacements = Lists.newArrayList();
|
||||||
|
private List<SpellAbility> abilities = Lists.newArrayList();
|
||||||
|
private List<StaticAbility> staticAbilities = Lists.newArrayList();
|
||||||
|
|
||||||
|
private List<SpellAbility> removedAbilities = Lists.newArrayList();
|
||||||
|
|
||||||
|
private boolean removeAll;
|
||||||
|
private boolean removeNonMana;
|
||||||
|
private boolean removeIntrinsic;
|
||||||
|
|
||||||
|
public CardTraitChanges(Collection<SpellAbility> spells, Collection<SpellAbility> removedAbilities,
|
||||||
|
Collection<Trigger> trigger, Collection<ReplacementEffect> res, Collection<StaticAbility> st,
|
||||||
|
boolean removeAll, boolean removeNonMana, boolean removeIntrinsic) {
|
||||||
|
if (spells != null) {
|
||||||
|
this.abilities.addAll(spells);
|
||||||
|
}
|
||||||
|
if (removedAbilities != null) {
|
||||||
|
this.removedAbilities.addAll(removedAbilities);
|
||||||
|
}
|
||||||
|
if (trigger != null) {
|
||||||
|
this.triggers.addAll(trigger);
|
||||||
|
}
|
||||||
|
if (res != null) {
|
||||||
|
this.replacements.addAll(res);
|
||||||
|
}
|
||||||
|
if (st != null) {
|
||||||
|
this.staticAbilities.addAll(st);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.removeAll = removeAll;
|
||||||
|
this.removeNonMana = removeNonMana;
|
||||||
|
this.removeIntrinsic = removeIntrinsic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the triggers
|
||||||
|
*/
|
||||||
|
public Collection<Trigger> getTriggers() {
|
||||||
|
return triggers;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the replacements
|
||||||
|
*/
|
||||||
|
public Collection<ReplacementEffect> getReplacements() {
|
||||||
|
return replacements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the abilities
|
||||||
|
*/
|
||||||
|
public Collection<SpellAbility> getAbilities() {
|
||||||
|
return abilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the abilities
|
||||||
|
*/
|
||||||
|
public Collection<SpellAbility> getRemovedAbilities() {
|
||||||
|
return removedAbilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the staticAbilities
|
||||||
|
*/
|
||||||
|
public Collection<StaticAbility> getStaticAbilities() {
|
||||||
|
return staticAbilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRemoveAll() {
|
||||||
|
return removeAll;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRemoveNonMana() {
|
||||||
|
return removeNonMana;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRemoveIntrinsic() {
|
||||||
|
return removeIntrinsic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CardTraitChanges copy(Card host, boolean lki) {
|
||||||
|
try {
|
||||||
|
CardTraitChanges result = (CardTraitChanges) super.clone();
|
||||||
|
|
||||||
|
result.abilities = Lists.newArrayList();
|
||||||
|
for (SpellAbility sa : this.abilities) {
|
||||||
|
result.abilities.add(sa.copy(host, lki));
|
||||||
|
}
|
||||||
|
result.removedAbilities = Lists.newArrayList();
|
||||||
|
for (SpellAbility sa : this.removedAbilities) {
|
||||||
|
result.removedAbilities.add(sa.copy(host, lki));
|
||||||
|
}
|
||||||
|
|
||||||
|
result.triggers = Lists.newArrayList();
|
||||||
|
for (Trigger tr : this.triggers) {
|
||||||
|
result.triggers.add(tr.copy(host, lki));
|
||||||
|
}
|
||||||
|
|
||||||
|
result.replacements = Lists.newArrayList();
|
||||||
|
for (ReplacementEffect re : this.replacements) {
|
||||||
|
result.replacements.add(re.copy(host, lki));
|
||||||
|
}
|
||||||
|
|
||||||
|
result.staticAbilities = Lists.newArrayList();
|
||||||
|
for (StaticAbility sa : this.staticAbilities) {
|
||||||
|
result.staticAbilities.add(sa.copy(host, lki));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} catch (final Exception ex) {
|
||||||
|
throw new RuntimeException("CardTraitChanges : clone() error", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,9 +29,7 @@ import forge.game.ability.AbilityKey;
|
|||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.ApiType;
|
import forge.game.ability.ApiType;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.replacement.ReplacementEffect;
|
|
||||||
import forge.game.spellability.*;
|
import forge.game.spellability.*;
|
||||||
import forge.game.trigger.Trigger;
|
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.TextUtil;
|
import forge.util.TextUtil;
|
||||||
import forge.util.collect.FCollection;
|
import forge.util.collect.FCollection;
|
||||||
@@ -240,23 +238,6 @@ public final class CardUtil {
|
|||||||
newCopy.setType(new CardType(in.getType()));
|
newCopy.setType(new CardType(in.getType()));
|
||||||
newCopy.setToken(in.isToken());
|
newCopy.setToken(in.isToken());
|
||||||
|
|
||||||
// extra copy non Intrinsic traits
|
|
||||||
for (SpellAbility sa : in.getSpellAbilities()) {
|
|
||||||
if (!sa.isIntrinsic()) {
|
|
||||||
newCopy.addSpellAbility(sa.copy(newCopy, true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Trigger tr : in.getTriggers()) {
|
|
||||||
if (!tr.isIntrinsic()) {
|
|
||||||
newCopy.moveTrigger(tr.copy(newCopy, true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (ReplacementEffect re : in.getReplacementEffects()) {
|
|
||||||
if (!re.isIntrinsic()) {
|
|
||||||
newCopy.addReplacementEffect(re.copy(newCopy, true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// lock in the current P/T without bonus from counters
|
// lock in the current P/T without bonus from counters
|
||||||
newCopy.setBasePower(in.getCurrentPower() + in.getTempPowerBoost());
|
newCopy.setBasePower(in.getCurrentPower() + in.getTempPowerBoost());
|
||||||
newCopy.setBaseToughness(in.getCurrentToughness() + in.getTempToughnessBoost());
|
newCopy.setBaseToughness(in.getCurrentToughness() + in.getTempToughnessBoost());
|
||||||
@@ -293,6 +274,7 @@ public final class CardUtil {
|
|||||||
newCopy.setChangedCardKeywords(in.getChangedCardKeywords());
|
newCopy.setChangedCardKeywords(in.getChangedCardKeywords());
|
||||||
newCopy.setChangedCardTypes(in.getChangedCardTypesMap());
|
newCopy.setChangedCardTypes(in.getChangedCardTypesMap());
|
||||||
newCopy.setChangedCardNames(in.getChangedCardNames());
|
newCopy.setChangedCardNames(in.getChangedCardNames());
|
||||||
|
newCopy.setChangedCardTraits(in.getChangedCardTraits());
|
||||||
|
|
||||||
newCopy.copyChangedTextFrom(in);
|
newCopy.copyChangedTextFrom(in);
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ package forge.game.card.token;
|
|||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import forge.ImageKeys;
|
import forge.ImageKeys;
|
||||||
import forge.StaticData;
|
import forge.StaticData;
|
||||||
import forge.card.CardType;
|
import forge.card.CardType;
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardFactory;
|
import forge.game.card.CardFactory;
|
||||||
@@ -166,19 +166,18 @@ public class TokenInfo {
|
|||||||
Player player = controller;
|
Player player = controller;
|
||||||
Card proto = prototype;
|
Card proto = prototype;
|
||||||
|
|
||||||
final Map<String, Object> repParams = Maps.newHashMap();
|
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(player);
|
||||||
repParams.put("Affected", player);
|
repParams.put(AbilityKey.Token, prototype);
|
||||||
repParams.put("Token", prototype);
|
repParams.put(AbilityKey.TokenNum, multiplier);
|
||||||
repParams.put("TokenNum", multiplier);
|
repParams.put(AbilityKey.EffectOnly, applyMultiplier);
|
||||||
repParams.put("EffectOnly", applyMultiplier);
|
|
||||||
|
|
||||||
switch (game.getReplacementHandler().run(ReplacementType.CreateToken, repParams)) {
|
switch (game.getReplacementHandler().run(ReplacementType.CreateToken, repParams)) {
|
||||||
case NotReplaced:
|
case NotReplaced:
|
||||||
break;
|
break;
|
||||||
case Updated: {
|
case Updated: {
|
||||||
multiplier = (int) repParams.get("TokenNum");
|
multiplier = (int) repParams.get(AbilityKey.TokenNum);
|
||||||
player = (Player) repParams.get("Affected");
|
player = (Player) repParams.get(AbilityKey.Affected);
|
||||||
proto = (Card) repParams.get("Token");
|
proto = (Card) repParams.get(AbilityKey.Token);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -235,10 +235,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Replacement effects
|
// Replacement effects
|
||||||
final Map<String, Object> repRunParams = Maps.newHashMap();
|
if (game.getReplacementHandler().run(ReplacementType.SetInMotion, AbilityKey.mapFromAffected(this)) != ReplacementResult.NotReplaced) {
|
||||||
repRunParams.put("Affected", this);
|
|
||||||
|
|
||||||
if (game.getReplacementHandler().run(ReplacementType.SetInMotion, repRunParams) != ReplacementResult.NotReplaced) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,10 +400,9 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
public final boolean gainLife(int lifeGain, final Card source, final SpellAbility sa) {
|
public final boolean gainLife(int lifeGain, final Card source, final SpellAbility sa) {
|
||||||
|
|
||||||
// Run any applicable replacement effects.
|
// Run any applicable replacement effects.
|
||||||
final Map<String, Object> repParams = Maps.newHashMap();
|
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
|
||||||
repParams.put("Affected", this);
|
repParams.put(AbilityKey.LifeGained, lifeGain);
|
||||||
repParams.put("LifeGained", lifeGain);
|
repParams.put(AbilityKey.Source, source);
|
||||||
repParams.put("Source", source);
|
|
||||||
|
|
||||||
if (!canGainLife()) {
|
if (!canGainLife()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -417,8 +413,8 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
break;
|
break;
|
||||||
case Updated:
|
case Updated:
|
||||||
// check if this is still the affected player
|
// check if this is still the affected player
|
||||||
if (this.equals(repParams.get("Affected"))) {
|
if (this.equals(repParams.get(AbilityKey.Affected))) {
|
||||||
lifeGain = (int) repParams.get("LifeGained");
|
lifeGain = (int) repParams.get(AbilityKey.LifeGained);
|
||||||
// negative update means life loss
|
// negative update means life loss
|
||||||
if (lifeGain < 0) {
|
if (lifeGain < 0) {
|
||||||
this.loseLife(-lifeGain);
|
this.loseLife(-lifeGain);
|
||||||
@@ -914,18 +910,17 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Map<String, Object> repParams = Maps.newHashMap();
|
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
|
||||||
repParams.put("Affected", this);
|
repParams.put(AbilityKey.Source, source);
|
||||||
repParams.put("Source", source);
|
repParams.put(AbilityKey.CounterType, counterType);
|
||||||
repParams.put("CounterType", counterType);
|
repParams.put(AbilityKey.CounterNum, addAmount);
|
||||||
repParams.put("CounterNum", addAmount);
|
repParams.put(AbilityKey.EffectOnly, applyMultiplier);
|
||||||
repParams.put("EffectOnly", applyMultiplier);
|
|
||||||
|
|
||||||
switch (getGame().getReplacementHandler().run(ReplacementType.AddCounter, repParams)) {
|
switch (getGame().getReplacementHandler().run(ReplacementType.AddCounter, repParams)) {
|
||||||
case NotReplaced:
|
case NotReplaced:
|
||||||
break;
|
break;
|
||||||
case Updated: {
|
case Updated: {
|
||||||
addAmount = (int) repParams.get("CounterNum");
|
addAmount = (int) repParams.get(AbilityKey.CounterNum);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -1178,7 +1173,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
com.remove(eff);
|
com.remove(eff);
|
||||||
eff.setStaticAbilities(Lists.newArrayList());
|
eff.setStaticAbilities(Lists.newArrayList());
|
||||||
}
|
}
|
||||||
this.updateZoneForView(com);
|
this.updateZoneForView(com);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1276,16 +1271,15 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
|
|
||||||
public void surveil(int num, SpellAbility cause) {
|
public void surveil(int num, SpellAbility cause) {
|
||||||
|
|
||||||
final Map<String, Object> repParams = Maps.newHashMap();
|
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
|
||||||
repParams.put("Affected", this);
|
repParams.put(AbilityKey.Source, cause);
|
||||||
repParams.put("Source", cause);
|
repParams.put(AbilityKey.SurveilNum, num);
|
||||||
repParams.put("SurveilNum", num);
|
|
||||||
|
|
||||||
switch (getGame().getReplacementHandler().run(ReplacementType.Surveil, repParams)) {
|
switch (getGame().getReplacementHandler().run(ReplacementType.Surveil, repParams)) {
|
||||||
case NotReplaced:
|
case NotReplaced:
|
||||||
break;
|
break;
|
||||||
case Updated: {
|
case Updated: {
|
||||||
num = (int) repParams.get("SurveilNum");
|
num = (int) repParams.get(AbilityKey.SurveilNum);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -1346,9 +1340,8 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
final CardCollection toReveal = new CardCollection();
|
final CardCollection toReveal = new CardCollection();
|
||||||
|
|
||||||
// Replacement effects
|
// Replacement effects
|
||||||
final Map<String, Object> repRunParams = Maps.newHashMap();
|
final Map<AbilityKey, Object> repRunParams = AbilityKey.mapFromAffected(this);
|
||||||
repRunParams.put("Affected", this);
|
repRunParams.put(AbilityKey.Number, n);
|
||||||
repRunParams.put("Number", n);
|
|
||||||
|
|
||||||
if (game.getReplacementHandler().run(ReplacementType.DrawCards, repRunParams) != ReplacementResult.NotReplaced) {
|
if (game.getReplacementHandler().run(ReplacementType.DrawCards, repRunParams) != ReplacementResult.NotReplaced) {
|
||||||
return drawn;
|
return drawn;
|
||||||
@@ -1378,10 +1371,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
final PlayerZone library = getZone(ZoneType.Library);
|
final PlayerZone library = getZone(ZoneType.Library);
|
||||||
|
|
||||||
// Replacement effects
|
// Replacement effects
|
||||||
final Map<String, Object> repRunParams = Maps.newHashMap();
|
if (game.getReplacementHandler().run(ReplacementType.Draw, AbilityKey.mapFromAffected(this)) != ReplacementResult.NotReplaced) {
|
||||||
repRunParams.put("Affected", this);
|
|
||||||
|
|
||||||
if (game.getReplacementHandler().run(ReplacementType.Draw, repRunParams) != ReplacementResult.NotReplaced) {
|
|
||||||
return drawn;
|
return drawn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1556,10 +1546,9 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
// that should not trigger other Replacement again
|
// that should not trigger other Replacement again
|
||||||
if (!discardToTopOfLibrary && !discardMadness) {
|
if (!discardToTopOfLibrary && !discardMadness) {
|
||||||
// Replacement effects
|
// Replacement effects
|
||||||
final Map<String, Object> repRunParams = Maps.newHashMap();
|
final Map<AbilityKey, Object> repRunParams = AbilityKey.mapFromCard(c);
|
||||||
repRunParams.put("Card", c);
|
repRunParams.put(AbilityKey.Source, source);
|
||||||
repRunParams.put("Source", source);
|
repRunParams.put(AbilityKey.Affected, this);
|
||||||
repRunParams.put("Affected", this);
|
|
||||||
|
|
||||||
if (game.getReplacementHandler().run(ReplacementType.Discard, repRunParams) != ReplacementResult.NotReplaced) {
|
if (game.getReplacementHandler().run(ReplacementType.Discard, repRunParams) != ReplacementResult.NotReplaced) {
|
||||||
return null;
|
return null;
|
||||||
@@ -1861,10 +1850,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Replacement effects
|
// Replacement effects
|
||||||
final Map<String, Object> runParams = Maps.newHashMap();
|
if (game.getReplacementHandler().run(ReplacementType.GameLoss, AbilityKey.mapFromAffected(this)) != ReplacementResult.NotReplaced) {
|
||||||
runParams.put("Affected", this);
|
|
||||||
|
|
||||||
if (game.getReplacementHandler().run(ReplacementType.GameLoss, runParams) != ReplacementResult.NotReplaced) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ public abstract class PlayerController {
|
|||||||
Map<String, Object> params);
|
Map<String, Object> params);
|
||||||
|
|
||||||
public abstract boolean confirmPayment(CostPart costPart, String string, SpellAbility sa);
|
public abstract boolean confirmPayment(CostPart costPart, String string, SpellAbility sa);
|
||||||
public abstract ReplacementEffect chooseSingleReplacementEffect(String prompt, List<ReplacementEffect> possibleReplacers, Map<String, Object> runParams);
|
public abstract ReplacementEffect chooseSingleReplacementEffect(String prompt, List<ReplacementEffect> possibleReplacers);
|
||||||
public abstract String chooseProtectionType(String string, SpellAbility sa, List<String> choices);
|
public abstract String chooseProtectionType(String string, SpellAbility sa, List<String> choices);
|
||||||
|
|
||||||
// these 4 need some refining.
|
// these 4 need some refining.
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CounterType;
|
import forge.game.card.CounterType;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -27,20 +28,20 @@ public class ReplaceAddCounter extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<String, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
if (((int) runParams.get("CounterNum")) <= 0) {
|
if (((int) runParams.get(AbilityKey.CounterNum)) <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("EffectOnly")) {
|
if (hasParam("EffectOnly")) {
|
||||||
final Boolean effectOnly = (Boolean) runParams.get("EffectOnly");
|
final Boolean effectOnly = (Boolean) runParams.get(AbilityKey.EffectOnly);
|
||||||
if (!effectOnly) {
|
if (!effectOnly) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("ValidCard")) {
|
if (hasParam("ValidCard")) {
|
||||||
Object o = runParams.get("Affected");
|
Object o = runParams.get(AbilityKey.Affected);
|
||||||
if (!(o instanceof Card)) {
|
if (!(o instanceof Card)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -48,7 +49,7 @@ public class ReplaceAddCounter extends ReplacementEffect {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (hasParam("ValidPlayer")) {
|
} else if (hasParam("ValidPlayer")) {
|
||||||
Object o = runParams.get("Affected");
|
Object o = runParams.get(AbilityKey.Affected);
|
||||||
if (!(o instanceof Player)) {
|
if (!(o instanceof Player)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -59,7 +60,7 @@ public class ReplaceAddCounter extends ReplacementEffect {
|
|||||||
|
|
||||||
if (hasParam("ValidCounterType")) {
|
if (hasParam("ValidCounterType")) {
|
||||||
String type = getParam("ValidCounterType");
|
String type = getParam("ValidCounterType");
|
||||||
if (CounterType.getType(type) != runParams.get("CounterType")) {
|
if (CounterType.getType(type) != runParams.get(AbilityKey.CounterType)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,14 +72,14 @@ public class ReplaceAddCounter extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setReplacingObjects(Map<String, Object> runParams, SpellAbility sa) {
|
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
|
||||||
sa.setReplacingObject("CounterNum", runParams.get("CounterNum"));
|
sa.setReplacingObject(AbilityKey.CounterNum, runParams.get(AbilityKey.CounterNum));
|
||||||
sa.setReplacingObject("CounterType", ((CounterType) runParams.get("CounterType")).getName());
|
sa.setReplacingObject(AbilityKey.CounterType, ((CounterType) runParams.get(AbilityKey.CounterType)).getName());
|
||||||
Object o = runParams.get("Affected");
|
Object o = runParams.get(AbilityKey.Affected);
|
||||||
if (o instanceof Card) {
|
if (o instanceof Card) {
|
||||||
sa.setReplacingObject("Card", o);
|
sa.setReplacingObject(AbilityKey.Card, o);
|
||||||
} else if (o instanceof Player) {
|
} else if (o instanceof Player) {
|
||||||
sa.setReplacingObject("Player", o);
|
sa.setReplacingObject(AbilityKey.Player, o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
|
||||||
@@ -42,15 +43,15 @@ public class ReplaceCounter extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<String, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
final SpellAbility spellAbility = (SpellAbility) runParams.get("TgtSA");
|
final SpellAbility spellAbility = (SpellAbility) runParams.get(AbilityKey.TgtSA);
|
||||||
if (hasParam("ValidCard")) {
|
if (hasParam("ValidCard")) {
|
||||||
if (!matchesValid(runParams.get("Affected"), getParam("ValidCard").split(","), this.getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), this.getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasParam("ValidCause")) {
|
if (hasParam("ValidCause")) {
|
||||||
if (!matchesValid(runParams.get("Cause"), getParam("ValidCause").split(","), this.getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Cause), getParam("ValidCause").split(","), this.getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,8 +68,8 @@ public class ReplaceCounter extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setReplacingObjects(Map<String, Object> runParams, SpellAbility sa) {
|
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
|
||||||
sa.setReplacingObject("Card", runParams.get("Affected"));
|
sa.setReplacingObject(AbilityKey.Card, runParams.get(AbilityKey.Affected));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardFactoryUtil;
|
import forge.game.card.CardFactoryUtil;
|
||||||
@@ -46,49 +47,49 @@ public class ReplaceDamage extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<String, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
if (!(runParams.containsKey("Prevention") == (hasParam("PreventionEffect") || hasParam("Prevent")))) {
|
if (!(runParams.containsKey(AbilityKey.Prevention) == (hasParam("PreventionEffect") || hasParam("Prevent")))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (((Integer) runParams.get("DamageAmount")) == 0) {
|
if (((Integer) runParams.get(AbilityKey.DamageAmount)) == 0) {
|
||||||
// If no actual damage is dealt, there is nothing to replace
|
// If no actual damage is dealt, there is nothing to replace
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (hasParam("ValidSource")) {
|
if (hasParam("ValidSource")) {
|
||||||
String validSource = getParam("ValidSource");
|
String validSource = getParam("ValidSource");
|
||||||
validSource = AbilityUtils.applyAbilityTextChangeEffects(validSource, this);
|
validSource = AbilityUtils.applyAbilityTextChangeEffects(validSource, this);
|
||||||
if (!matchesValid(runParams.get("DamageSource"), validSource.split(","), getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.DamageSource), validSource.split(","), getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasParam("ValidTarget")) {
|
if (hasParam("ValidTarget")) {
|
||||||
String validTarget = getParam("ValidTarget");
|
String validTarget = getParam("ValidTarget");
|
||||||
validTarget = AbilityUtils.applyAbilityTextChangeEffects(validTarget, this);
|
validTarget = AbilityUtils.applyAbilityTextChangeEffects(validTarget, this);
|
||||||
if (!matchesValid(runParams.get("Affected"), validTarget.split(","), getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Affected), validTarget.split(","), getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasParam("ValidCause")) {
|
if (hasParam("ValidCause")) {
|
||||||
if (!runParams.containsKey("Cause")) {
|
if (!runParams.containsKey(AbilityKey.Cause)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
SpellAbility cause = (SpellAbility) runParams.get("Cause");
|
SpellAbility cause = (SpellAbility) runParams.get(AbilityKey.Cause);
|
||||||
String validCause = getParam("ValidCause");
|
String validCause = getParam("ValidCause");
|
||||||
validCause = AbilityUtils.applyAbilityTextChangeEffects(validCause, this);
|
validCause = AbilityUtils.applyAbilityTextChangeEffects(validCause, this);
|
||||||
if (!matchesValid(cause, validCause.split(","), getHostCard())) {
|
if (!matchesValid(cause, validCause.split(","), getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (hasParam("CauseIsSource")) {
|
if (hasParam("CauseIsSource")) {
|
||||||
if (!cause.getHostCard().equals(runParams.get("DamageSource"))) {
|
if (!cause.getHostCard().equals(runParams.get(AbilityKey.DamageSource))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasParam("RelativeToSource")) {
|
if (hasParam("RelativeToSource")) {
|
||||||
Card source = (Card) runParams.get("DamageSource");
|
Card source = (Card) runParams.get(AbilityKey.DamageSource);
|
||||||
String validRelative = getParam("RelativeToSource");
|
String validRelative = getParam("RelativeToSource");
|
||||||
validRelative = AbilityUtils.applyAbilityTextChangeEffects(validRelative, this);
|
validRelative = AbilityUtils.applyAbilityTextChangeEffects(validRelative, this);
|
||||||
if (!matchesValid(runParams.get("DamageTarget"), validRelative.split(","), source)) {
|
if (!matchesValid(runParams.get(AbilityKey.DamageTarget), validRelative.split(","), source)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,17 +104,17 @@ public class ReplaceDamage extends ReplacementEffect {
|
|||||||
intoperand = CardFactoryUtil.xCount(getHostCard(), getHostCard().getSVar(operand));
|
intoperand = CardFactoryUtil.xCount(getHostCard(), getHostCard().getSVar(operand));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Expressions.compare((Integer) runParams.get("DamageAmount"), operator, intoperand)) {
|
if (!Expressions.compare((Integer) runParams.get(AbilityKey.DamageAmount), operator, intoperand)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasParam("IsCombat")) {
|
if (hasParam("IsCombat")) {
|
||||||
if (getParam("IsCombat").equals("True")) {
|
if (getParam("IsCombat").equals("True")) {
|
||||||
if (!((Boolean) runParams.get("IsCombat"))) {
|
if (!((Boolean) runParams.get(AbilityKey.IsCombat))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((Boolean) runParams.get("IsCombat")) {
|
if ((Boolean) runParams.get(AbilityKey.IsCombat)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,10 +150,10 @@ public class ReplaceDamage extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setReplacingObjects(Map<String, Object> runParams, SpellAbility sa) {
|
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
|
||||||
sa.setReplacingObject("DamageAmount", runParams.get("DamageAmount"));
|
sa.setReplacingObject(AbilityKey.DamageAmount, runParams.get(AbilityKey.DamageAmount));
|
||||||
sa.setReplacingObject("Target", runParams.get("Affected"));
|
sa.setReplacingObject(AbilityKey.Target, runParams.get(AbilityKey.Affected));
|
||||||
sa.setReplacingObject("Source", runParams.get("DamageSource"));
|
sa.setReplacingObject(AbilityKey.Source, runParams.get(AbilityKey.DamageSource));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
|
||||||
@@ -42,23 +43,23 @@ public class ReplaceDestroy extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<String, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
if (hasParam("ValidPlayer")) {
|
if (hasParam("ValidPlayer")) {
|
||||||
if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasParam("ValidCard")) {
|
if (hasParam("ValidCard")) {
|
||||||
Card card = (Card)runParams.get("Card");
|
Card card = (Card)runParams.get(AbilityKey.Card);
|
||||||
if (!matchesValid(card, getParam("ValidCard").split(","), getHostCard())) {
|
if (!matchesValid(card, getParam("ValidCard").split(","), getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// extra check for Regeneration
|
// extra check for Regeneration
|
||||||
if (hasParam("Regeneration")) {
|
if (hasParam("Regeneration")) {
|
||||||
if (!runParams.containsKey("Regeneration")) {
|
if (!runParams.containsKey(AbilityKey.Regeneration)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(Boolean)runParams.get("Regeneration")) {
|
if (!(Boolean)runParams.get(AbilityKey.Regeneration)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!card.canBeShielded()) {
|
if (!card.canBeShielded()) {
|
||||||
@@ -71,7 +72,7 @@ public class ReplaceDestroy extends ReplacementEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasParam("ValidSource")) {
|
if (hasParam("ValidSource")) {
|
||||||
if (!matchesValid(runParams.get("Source"), getParam("ValidSource").split(","), getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Source), getParam("ValidSource").split(","), getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,8 +84,8 @@ public class ReplaceDestroy extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setReplacingObjects(Map<String, Object> runParams, SpellAbility sa) {
|
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
|
||||||
sa.setReplacingObject("Card", runParams.get("Card"));
|
sa.setReplacingObject(AbilityKey.Card, runParams.get(AbilityKey.Card));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
|
||||||
@@ -42,24 +43,24 @@ public class ReplaceDiscard extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<String, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
if (hasParam("ValidPlayer")) {
|
if (hasParam("ValidPlayer")) {
|
||||||
if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), this.getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasParam("ValidCard")) {
|
if (hasParam("ValidCard")) {
|
||||||
if (!matchesValid(runParams.get("Card"), getParam("ValidCard").split(","), this.getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Card), getParam("ValidCard").split(","), this.getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasParam("ValidSource")) {
|
if (hasParam("ValidSource")) {
|
||||||
if (!matchesValid(runParams.get("Source"), getParam("ValidSource").split(","), this.getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Source), getParam("ValidSource").split(","), this.getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasParam("DiscardFromEffect")) {
|
if (hasParam("DiscardFromEffect")) {
|
||||||
if (null == runParams.get("Source")) {
|
if (null == runParams.get(AbilityKey.Source)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,10 +72,10 @@ public class ReplaceDiscard extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setReplacingObjects(Map<String, Object> runParams, SpellAbility sa) {
|
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
|
||||||
sa.setReplacingObject("Card", runParams.get("Card"));
|
sa.setReplacingObject(AbilityKey.Card, runParams.get(AbilityKey.Card));
|
||||||
sa.setReplacingObject("Player", runParams.get("Affected"));
|
sa.setReplacingObject(AbilityKey.Player, runParams.get(AbilityKey.Affected));
|
||||||
sa.setReplacingObject("Source", runParams.get("Source"));
|
sa.setReplacingObject(AbilityKey.Source, runParams.get(AbilityKey.Source));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -44,14 +45,14 @@ public class ReplaceDraw extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<String, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
if (hasParam("ValidPlayer")) {
|
if (hasParam("ValidPlayer")) {
|
||||||
if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), this.getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasParam("NotFirstCardInDrawStep")) {
|
if (hasParam("NotFirstCardInDrawStep")) {
|
||||||
final Player p = (Player)runParams.get("Affected");
|
final Player p = (Player)runParams.get(AbilityKey.Affected);
|
||||||
if (p.numDrawnThisDrawStep() == 0
|
if (p.numDrawnThisDrawStep() == 0
|
||||||
&& this.getHostCard().getGame().getPhaseHandler().is(PhaseType.DRAW)
|
&& this.getHostCard().getGame().getPhaseHandler().is(PhaseType.DRAW)
|
||||||
&& this.getHostCard().getGame().getPhaseHandler().isPlayerTurn(p)) {
|
&& this.getHostCard().getGame().getPhaseHandler().isPlayerTurn(p)) {
|
||||||
@@ -68,7 +69,7 @@ public class ReplaceDraw extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setReplacingObjects(Map<String, Object> runParams, SpellAbility sa) {
|
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
|
||||||
sa.setReplacingObject("Player", runParams.get("Affected"));
|
sa.setReplacingObject(AbilityKey.Player, runParams.get(AbilityKey.Affected));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.util.Expressions;
|
import forge.util.Expressions;
|
||||||
@@ -43,14 +44,14 @@ public class ReplaceDrawCards extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<String, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
if (hasParam("ValidPlayer")) {
|
if (hasParam("ValidPlayer")) {
|
||||||
if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), this.getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasParam("Number")) {
|
if (hasParam("Number")) {
|
||||||
final int n = (Integer)runParams.get("Number");
|
final int n = (Integer)runParams.get(AbilityKey.Number);
|
||||||
String comparator = getParam("Number");
|
String comparator = getParam("Number");
|
||||||
final String operator = comparator.substring(0, 2);
|
final String operator = comparator.substring(0, 2);
|
||||||
final int operandValue = Integer.parseInt(comparator.substring(2));
|
final int operandValue = Integer.parseInt(comparator.substring(2));
|
||||||
@@ -68,7 +69,7 @@ public class ReplaceDrawCards extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setReplacingObjects(Map<String, Object> runParams, SpellAbility sa) {
|
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
|
||||||
sa.setReplacingObject("Player", runParams.get("Affected"));
|
sa.setReplacingObject(AbilityKey.Player, runParams.get(AbilityKey.Affected));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
|
||||||
@@ -42,22 +43,22 @@ public class ReplaceGainLife extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<String, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
if (((int)runParams.get("LifeGained")) <= 0) {
|
if (((int)runParams.get(AbilityKey.LifeGained)) <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (hasParam("ValidPlayer")) {
|
if (hasParam("ValidPlayer")) {
|
||||||
if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), this.getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasParam("ValidSource")) {
|
if (hasParam("ValidSource")) {
|
||||||
if (!matchesValid(runParams.get("Source"), getParam("ValidSource").split(","), this.getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Source), getParam("ValidSource").split(","), this.getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ("True".equals(getParam("SourceController"))) {
|
if ("True".equals(getParam("SourceController"))) {
|
||||||
if (runParams.get("Source") == null || !runParams.get("Affected").equals(((Card)runParams.get("Source")).getController())) {
|
if (runParams.get(AbilityKey.Source) == null || !runParams.get(AbilityKey.Affected).equals(((Card)runParams.get(AbilityKey.Source)).getController())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,9 +70,9 @@ public class ReplaceGainLife extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setReplacingObjects(Map<String, Object> runParams, SpellAbility sa) {
|
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
|
||||||
sa.setReplacingObject("LifeGained", runParams.get("LifeGained"));
|
sa.setReplacingObject(AbilityKey.LifeGained, runParams.get(AbilityKey.LifeGained));
|
||||||
sa.setReplacingObject("Player", runParams.get("Affected"));
|
sa.setReplacingObject(AbilityKey.Player, runParams.get(AbilityKey.Affected));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -24,9 +25,9 @@ public class ReplaceGameLoss extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<String, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
if (hasParam("ValidPlayer")) {
|
if (hasParam("ValidPlayer")) {
|
||||||
if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), this.getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
|
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -28,9 +29,9 @@ public class ReplaceMoved extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<String, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
final Player controller = getHostCard().getController();
|
final Player controller = getHostCard().getController();
|
||||||
final Card affected = (Card) runParams.get("Affected");
|
final Card affected = (Card) runParams.get(AbilityKey.Affected);
|
||||||
|
|
||||||
if (hasParam("ValidCard")) {
|
if (hasParam("ValidCard")) {
|
||||||
if (!matchesValid(affected, getParam("ValidCard").split(","), getHostCard())) {
|
if (!matchesValid(affected, getParam("ValidCard").split(","), getHostCard())) {
|
||||||
@@ -39,27 +40,27 @@ public class ReplaceMoved extends ReplacementEffect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("ValidLKI")) {
|
if (hasParam("ValidLKI")) {
|
||||||
if (!matchesValid(runParams.get("CardLKI"), getParam("ValidLKI").split(","), getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.CardLKI), getParam("ValidLKI").split(","), getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("Origin")) {
|
if (hasParam("Origin")) {
|
||||||
ZoneType zt = (ZoneType) runParams.get("Origin");
|
ZoneType zt = (ZoneType) runParams.get(AbilityKey.Origin);
|
||||||
if (!ZoneType.listValueOf(getParam("Origin")).contains(zt)) {
|
if (!ZoneType.listValueOf(getParam("Origin")).contains(zt)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("Destination")) {
|
if (hasParam("Destination")) {
|
||||||
ZoneType zt = (ZoneType) runParams.get("Destination");
|
ZoneType zt = (ZoneType) runParams.get(AbilityKey.Destination);
|
||||||
if (!ZoneType.listValueOf(getParam("Destination")).contains(zt)) {
|
if (!ZoneType.listValueOf(getParam("Destination")).contains(zt)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("ExcludeDestination")) {
|
if (hasParam("ExcludeDestination")) {
|
||||||
ZoneType zt = (ZoneType) runParams.get("Destination");
|
ZoneType zt = (ZoneType) runParams.get(AbilityKey.Destination);
|
||||||
if (ZoneType.listValueOf(getParam("ExcludeDestination")).contains(zt)) {
|
if (ZoneType.listValueOf(getParam("ExcludeDestination")).contains(zt)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -67,29 +68,29 @@ public class ReplaceMoved extends ReplacementEffect {
|
|||||||
|
|
||||||
if (hasParam("Fizzle")) {
|
if (hasParam("Fizzle")) {
|
||||||
// if Replacement look for Fizzle
|
// if Replacement look for Fizzle
|
||||||
if (!runParams.containsKey("Fizzle")) {
|
if (!runParams.containsKey(AbilityKey.Fizzle)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Boolean val = (Boolean) runParams.get("Fizzle");
|
Boolean val = (Boolean) runParams.get(AbilityKey.Fizzle);
|
||||||
if ("True".equals(getParam("Fizzle")) != val) {
|
if ("True".equals(getParam("Fizzle")) != val) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("ValidStackSa")) {
|
if (hasParam("ValidStackSa")) {
|
||||||
if (!runParams.containsKey("StackSa")) {
|
if (!runParams.containsKey(AbilityKey.StackSa)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!((SpellAbility)runParams.get("StackSa")).isValid(getParam("ValidStackSa").split(","), getHostCard().getController(), getHostCard(), null)) {
|
if (!((SpellAbility)runParams.get(AbilityKey.StackSa)).isValid(getParam("ValidStackSa").split(","), getHostCard().getController(), getHostCard(), null)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("Cause")) {
|
if (hasParam("Cause")) {
|
||||||
if (!runParams.containsKey("Cause")) {
|
if (!runParams.containsKey(AbilityKey.Cause)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
SpellAbility cause = (SpellAbility) runParams.get("Cause");
|
SpellAbility cause = (SpellAbility) runParams.get(AbilityKey.Cause);
|
||||||
if (cause == null) {
|
if (cause == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -99,8 +100,8 @@ public class ReplaceMoved extends ReplacementEffect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("NotCause")) {
|
if (hasParam("NotCause")) {
|
||||||
if (runParams.containsKey("Cause")) {
|
if (runParams.containsKey(AbilityKey.Cause)) {
|
||||||
SpellAbility cause = (SpellAbility) runParams.get("Cause");
|
SpellAbility cause = (SpellAbility) runParams.get(AbilityKey.Cause);
|
||||||
if (cause != null) {
|
if (cause != null) {
|
||||||
if (cause.isValid(getParam("NotCause").split(","), controller, getHostCard(), null)) {
|
if (cause.isValid(getParam("NotCause").split(","), controller, getHostCard(), null)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -116,10 +117,10 @@ public class ReplaceMoved extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setReplacingObjects(Map<String, Object> runParams, SpellAbility sa) {
|
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
|
||||||
sa.setReplacingObject("Card", runParams.get("Affected"));
|
sa.setReplacingObject(AbilityKey.Card, runParams.get(AbilityKey.Affected));
|
||||||
sa.setReplacingObject("CardLKI", runParams.get("CardLKI"));
|
sa.setReplacingObject(AbilityKey.CardLKI, runParams.get(AbilityKey.CardLKI));
|
||||||
sa.setReplacingObject("Cause", runParams.get("Cause"));
|
sa.setReplacingObject(AbilityKey.Cause, runParams.get(AbilityKey.Cause));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardFactoryUtil;
|
import forge.game.card.CardFactoryUtil;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
@@ -29,10 +30,10 @@ public class ReplaceProduceMana extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<String, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
//Check for tapping
|
//Check for tapping
|
||||||
if (!hasParam("NoTapCheck")) {
|
if (!hasParam("NoTapCheck")) {
|
||||||
final SpellAbility manaAbility = (SpellAbility) runParams.get("AbilityMana");
|
final SpellAbility manaAbility = (SpellAbility) runParams.get(AbilityKey.AbilityMana);
|
||||||
if (manaAbility == null || manaAbility.getRootAbility().getPayCosts() == null || !manaAbility.getRootAbility().getPayCosts().hasTapCost()) {
|
if (manaAbility == null || manaAbility.getRootAbility().getPayCosts() == null || !manaAbility.getRootAbility().getPayCosts().hasTapCost()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -48,14 +49,14 @@ public class ReplaceProduceMana extends ReplacementEffect {
|
|||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
intoperand = CardFactoryUtil.xCount(getHostCard(), getHostCard().getSVar(operand));
|
intoperand = CardFactoryUtil.xCount(getHostCard(), getHostCard().getSVar(operand));
|
||||||
}
|
}
|
||||||
int manaAmount = StringUtils.countMatches((String) runParams.get("Mana"), " ") + 1;
|
int manaAmount = StringUtils.countMatches((String) runParams.get(AbilityKey.Mana), " ") + 1;
|
||||||
if (!Expressions.compare(manaAmount, operator, intoperand)) {
|
if (!Expressions.compare(manaAmount, operator, intoperand)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("ValidCard")) {
|
if (hasParam("ValidCard")) {
|
||||||
if (!matchesValid(runParams.get("Affected"), getParam("ValidCard").split(","), this.getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), this.getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -41,9 +42,9 @@ public class ReplaceSetInMotion extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<String, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
if (hasParam("ValidPlayer")) {
|
if (hasParam("ValidPlayer")) {
|
||||||
if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
|
||||||
@@ -25,13 +26,13 @@ public class ReplaceSurveil extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.Map)
|
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.Map)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<String, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
if (((int) runParams.get("SurveilNum")) <= 0) {
|
if (((int) runParams.get(AbilityKey.SurveilNum)) <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("ValidPlayer")) {
|
if (hasParam("ValidPlayer")) {
|
||||||
if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), this.getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,9 +44,9 @@ public class ReplaceSurveil extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.Map, forge.card.spellability.SpellAbility)
|
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.Map, forge.card.spellability.SpellAbility)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setReplacingObjects(Map<String, Object> runParams, SpellAbility sa) {
|
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
|
||||||
sa.setReplacingObject("Player", runParams.get("Affected"));
|
sa.setReplacingObject(AbilityKey.Player, runParams.get(AbilityKey.Affected));
|
||||||
sa.setReplacingObject("SurveilNum", runParams.get("SurveilNum"));
|
sa.setReplacingObject(AbilityKey.SurveilNum, runParams.get(AbilityKey.SurveilNum));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
|
||||||
@@ -25,27 +26,27 @@ public class ReplaceToken extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.Map)
|
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.Map)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<String, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
if (((int) runParams.get("TokenNum")) <= 0) {
|
if (((int) runParams.get(AbilityKey.TokenNum)) <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("EffectOnly")) {
|
if (hasParam("EffectOnly")) {
|
||||||
final Boolean effectOnly = (Boolean) runParams.get("EffectOnly");
|
final Boolean effectOnly = (Boolean) runParams.get(AbilityKey.EffectOnly);
|
||||||
if (!effectOnly) {
|
if (!effectOnly) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("ValidPlayer")) {
|
if (hasParam("ValidPlayer")) {
|
||||||
if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("ValidToken")) {
|
if (hasParam("ValidToken")) {
|
||||||
if (runParams.containsKey("Token")) {
|
if (runParams.containsKey(AbilityKey.Token)) {
|
||||||
if (!matchesValid(runParams.get("Token"), getParam("ValidToken").split(","), getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Token), getParam("ValidToken").split(","), getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -61,9 +62,9 @@ public class ReplaceToken extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.Map, forge.card.spellability.SpellAbility)
|
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.Map, forge.card.spellability.SpellAbility)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setReplacingObjects(Map<String, Object> runParams, SpellAbility sa) {
|
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
|
||||||
sa.setReplacingObject("TokenNum", runParams.get("TokenNum"));
|
sa.setReplacingObject(AbilityKey.TokenNum, runParams.get(AbilityKey.TokenNum));
|
||||||
sa.setReplacingObject("Player", runParams.get("Affected"));
|
sa.setReplacingObject(AbilityKey.Player, runParams.get(AbilityKey.Affected));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
|
||||||
@@ -25,9 +26,9 @@ public class ReplaceTurnFaceUp extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<String, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
if (hasParam("ValidCard")) {
|
if (hasParam("ValidCard")) {
|
||||||
if (!matchesValid(runParams.get("Affected"), getParam("ValidCard").split(","), this.getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), this.getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,8 +39,8 @@ public class ReplaceTurnFaceUp extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setReplacingObjects(Map<String, Object> runParams, SpellAbility sa) {
|
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
|
||||||
sa.setReplacingObject("Card", runParams.get("Affected"));
|
sa.setReplacingObject(AbilityKey.Card, runParams.get(AbilityKey.Affected));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
@@ -44,14 +45,14 @@ public class ReplaceUntap extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<String, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
if (hasParam("ValidCard")) {
|
if (hasParam("ValidCard")) {
|
||||||
if (!matchesValid(runParams.get("Affected"), getParam("ValidCard").split(","), this.getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), this.getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasParam("UntapStep")) {
|
if (hasParam("UntapStep")) {
|
||||||
final Object o = runParams.get("Affected");
|
final Object o = runParams.get(AbilityKey.Affected);
|
||||||
//normally should not happen, but protect from possible crash.
|
//normally should not happen, but protect from possible crash.
|
||||||
if (!(o instanceof Card)) {
|
if (!(o instanceof Card)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -72,8 +73,8 @@ public class ReplaceUntap extends ReplacementEffect {
|
|||||||
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setReplacingObjects(Map<String, Object> runParams, SpellAbility sa) {
|
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
|
||||||
sa.setReplacingObject("Card", runParams.get("Affected"));
|
sa.setReplacingObject(AbilityKey.Card, runParams.get(AbilityKey.Affected));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package forge.game.replacement;
|
|||||||
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.TriggerReplacementBase;
|
import forge.game.TriggerReplacementBase;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
@@ -121,7 +122,7 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
|
|||||||
* the run params
|
* the run params
|
||||||
* @return true, if successful
|
* @return true, if successful
|
||||||
*/
|
*/
|
||||||
public abstract boolean canReplace(final Map<String, Object> runParams);
|
public abstract boolean canReplace (final Map<AbilityKey, Object> runParams);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -193,19 +194,16 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
|
|||||||
|
|
||||||
res.setActiveZone(validHostZones);
|
res.setActiveZone(validHostZones);
|
||||||
res.setLayer(getLayer());
|
res.setLayer(getLayer());
|
||||||
res.setTemporary(isTemporary());
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the replacing objects.
|
* Sets the replacing objects.
|
||||||
*
|
* @param runParams
|
||||||
* @param runParams
|
|
||||||
* the run params
|
* the run params
|
||||||
* @param spellAbility
|
* @param spellAbility
|
||||||
* the SpellAbility
|
|
||||||
*/
|
*/
|
||||||
public void setReplacingObjects(final Map<String, Object> runParams, final SpellAbility spellAbility) {
|
public void setReplacingObjects(final Map<AbilityKey, Object> runParams, final SpellAbility spellAbility) {
|
||||||
// Should be overridden by replacers that need it.
|
// Should be overridden by replacers that need it.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import forge.card.MagicColor;
|
|||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.GameLogEntryType;
|
import forge.game.GameLogEntryType;
|
||||||
import forge.game.ability.AbilityFactory;
|
import forge.game.ability.AbilityFactory;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardCollection;
|
import forge.game.card.CardCollection;
|
||||||
@@ -52,41 +53,17 @@ public class ReplacementHandler {
|
|||||||
|
|
||||||
//private final List<ReplacementEffect> tmpEffects = new ArrayList<ReplacementEffect>();
|
//private final List<ReplacementEffect> tmpEffects = new ArrayList<ReplacementEffect>();
|
||||||
|
|
||||||
public ReplacementResult run(ReplacementType event, final Map<String, Object> runParams) {
|
public List<ReplacementEffect> getReplacementList(final ReplacementType event, final Map<AbilityKey, Object> runParams, final ReplacementLayer layer) {
|
||||||
final Object affected = runParams.get("Affected");
|
|
||||||
Player decider = null;
|
|
||||||
|
|
||||||
// Figure out who decides which of multiple replacements to apply
|
|
||||||
// as well as whether or not to apply optional replacements.
|
|
||||||
if (affected instanceof Player) {
|
|
||||||
decider = (Player) affected;
|
|
||||||
} else {
|
|
||||||
decider = ((Card) affected).getController();
|
|
||||||
}
|
|
||||||
|
|
||||||
// try out all layer
|
|
||||||
for (ReplacementLayer layer : ReplacementLayer.values()) {
|
|
||||||
ReplacementResult res = run(event, runParams, layer, decider);
|
|
||||||
if (res != ReplacementResult.NotReplaced) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ReplacementResult.NotReplaced;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ReplacementEffect> getReplacementList(final ReplacementType event, final Map<String, Object> runParams, final ReplacementLayer layer) {
|
|
||||||
|
|
||||||
final CardCollection preList = new CardCollection();
|
final CardCollection preList = new CardCollection();
|
||||||
boolean checkAgain = false;
|
boolean checkAgain = false;
|
||||||
Card affectedLKI = null;
|
Card affectedLKI = null;
|
||||||
Card affectedCard = null;
|
Card affectedCard = null;
|
||||||
|
|
||||||
if (ReplacementType.Moved.equals(event) && ZoneType.Battlefield.equals(runParams.get("Destination"))) {
|
if (ReplacementType.Moved.equals(event) && ZoneType.Battlefield.equals(runParams.get(AbilityKey.Destination))) {
|
||||||
// if it was caused by an replacement effect, use the already calculated RE list
|
// if it was caused by an replacement effect, use the already calculated RE list
|
||||||
// otherwise the RIOT card would cause a StackError
|
// otherwise the RIOT card would cause a StackError
|
||||||
SpellAbility cause = (SpellAbility) runParams.get("Cause");
|
SpellAbility cause = (SpellAbility) runParams.get(AbilityKey.Cause);
|
||||||
if (cause != null && cause.isReplacementAbility()) {
|
if (cause != null && cause.isReplacementAbility()) {
|
||||||
final ReplacementEffect re = cause.getReplacementEffect();
|
final ReplacementEffect re = cause.getReplacementEffect();
|
||||||
// only return for same layer
|
// only return for same layer
|
||||||
@@ -96,13 +73,13 @@ public class ReplacementHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rule 614.12 Enter the Battlefield Replacement Effects look at what the card would be on the battlefield
|
// Rule 614.12 Enter the Battlefield Replacement Effects look at what the card would be on the battlefield
|
||||||
affectedCard = (Card) runParams.get("Affected");
|
affectedCard = (Card) runParams.get(AbilityKey.Affected);
|
||||||
affectedLKI = CardUtil.getLKICopy(affectedCard);
|
affectedLKI = CardUtil.getLKICopy(affectedCard);
|
||||||
affectedLKI.setLastKnownZone(affectedCard.getController().getZone(ZoneType.Battlefield));
|
affectedLKI.setLastKnownZone(affectedCard.getController().getZone(ZoneType.Battlefield));
|
||||||
preList.add(affectedLKI);
|
preList.add(affectedLKI);
|
||||||
game.getAction().checkStaticAbilities(false, Sets.newHashSet(affectedLKI), preList);
|
game.getAction().checkStaticAbilities(false, Sets.newHashSet(affectedLKI), preList);
|
||||||
checkAgain = true;
|
checkAgain = true;
|
||||||
runParams.put("Affected", affectedLKI);
|
runParams.put(AbilityKey.Affected, affectedLKI);
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<ReplacementEffect> possibleReplacers = Lists.newArrayList();
|
final List<ReplacementEffect> possibleReplacers = Lists.newArrayList();
|
||||||
@@ -157,7 +134,7 @@ public class ReplacementHandler {
|
|||||||
for (final ReplacementEffect re : affectedLKI.getReplacementEffects()) {
|
for (final ReplacementEffect re : affectedLKI.getReplacementEffects()) {
|
||||||
re.setHostCard(affectedCard);
|
re.setHostCard(affectedCard);
|
||||||
}
|
}
|
||||||
runParams.put("Affected", affectedCard);
|
runParams.put(AbilityKey.Affected, affectedCard);
|
||||||
}
|
}
|
||||||
game.getAction().checkStaticAbilities(false);
|
game.getAction().checkStaticAbilities(false);
|
||||||
}
|
}
|
||||||
@@ -171,16 +148,40 @@ public class ReplacementHandler {
|
|||||||
*
|
*
|
||||||
* @param runParams
|
* @param runParams
|
||||||
* the run params,same as for triggers.
|
* the run params,same as for triggers.
|
||||||
* @return true if the event was replaced.
|
* @return ReplacementResult, an enum that represents what happened to the replacement effect.
|
||||||
*/
|
*/
|
||||||
public ReplacementResult run(final ReplacementType event, final Map<String, Object> runParams, final ReplacementLayer layer, final Player decider) {
|
public ReplacementResult run(ReplacementType event, final Map<AbilityKey, Object> runParams) {
|
||||||
|
final Object affected = runParams.get(AbilityKey.Affected);
|
||||||
|
Player decider = null;
|
||||||
|
|
||||||
|
// Figure out who decides which of multiple replacements to apply
|
||||||
|
// as well as whether or not to apply optional replacements.
|
||||||
|
if (affected instanceof Player) {
|
||||||
|
decider = (Player) affected;
|
||||||
|
} else {
|
||||||
|
decider = ((Card) affected).getController();
|
||||||
|
}
|
||||||
|
|
||||||
|
// try out all layer
|
||||||
|
for (ReplacementLayer layer : ReplacementLayer.values()) {
|
||||||
|
ReplacementResult res = run(event, runParams, layer, decider);
|
||||||
|
if (res != ReplacementResult.NotReplaced) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReplacementResult.NotReplaced;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ReplacementResult run(final ReplacementType event, final Map<AbilityKey, Object> runParams, final ReplacementLayer layer, final Player decider) {
|
||||||
final List<ReplacementEffect> possibleReplacers = getReplacementList(event, runParams, layer);
|
final List<ReplacementEffect> possibleReplacers = getReplacementList(event, runParams, layer);
|
||||||
|
|
||||||
if (possibleReplacers.isEmpty()) {
|
if (possibleReplacers.isEmpty()) {
|
||||||
return ReplacementResult.NotReplaced;
|
return ReplacementResult.NotReplaced;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReplacementEffect chosenRE = decider.getController().chooseSingleReplacementEffect("Choose a replacement effect to apply first.", possibleReplacers, runParams);
|
ReplacementEffect chosenRE = decider.getController().chooseSingleReplacementEffect("Choose a replacement effect to apply first.", possibleReplacers);
|
||||||
|
|
||||||
possibleReplacers.remove(chosenRE);
|
possibleReplacers.remove(chosenRE);
|
||||||
|
|
||||||
@@ -213,7 +214,7 @@ public class ReplacementHandler {
|
|||||||
* @param replacementEffect
|
* @param replacementEffect
|
||||||
* the replacement effect to run
|
* the replacement effect to run
|
||||||
*/
|
*/
|
||||||
private ReplacementResult executeReplacement(final Map<String, Object> runParams,
|
private ReplacementResult executeReplacement(final Map<AbilityKey, Object> runParams,
|
||||||
final ReplacementEffect replacementEffect, final Player decider, final Game game) {
|
final ReplacementEffect replacementEffect, final Player decider, final Game game) {
|
||||||
final Map<String, String> mapParams = replacementEffect.getMapParams();
|
final Map<String, String> mapParams = replacementEffect.getMapParams();
|
||||||
|
|
||||||
@@ -237,7 +238,7 @@ public class ReplacementHandler {
|
|||||||
do {
|
do {
|
||||||
replacementEffect.setReplacingObjects(runParams, tailend);
|
replacementEffect.setReplacingObjects(runParams, tailend);
|
||||||
//set original Params to update them later
|
//set original Params to update them later
|
||||||
tailend.setReplacingObject("OriginalParams", runParams);
|
tailend.setReplacingObject(AbilityKey.OriginalParams, runParams);
|
||||||
tailend = tailend.getSubAbility();
|
tailend = tailend.getSubAbility();
|
||||||
} while(tailend != null);
|
} while(tailend != null);
|
||||||
|
|
||||||
@@ -248,7 +249,7 @@ public class ReplacementHandler {
|
|||||||
do {
|
do {
|
||||||
replacementEffect.setReplacingObjects(runParams, tailend);
|
replacementEffect.setReplacingObjects(runParams, tailend);
|
||||||
//set original Params to update them later
|
//set original Params to update them later
|
||||||
tailend.setReplacingObject("OriginalParams", runParams);
|
tailend.setReplacingObject(AbilityKey.OriginalParams, runParams);
|
||||||
tailend = tailend.getSubAbility();
|
tailend = tailend.getSubAbility();
|
||||||
} while(tailend != null);
|
} while(tailend != null);
|
||||||
}
|
}
|
||||||
@@ -275,7 +276,7 @@ public class ReplacementHandler {
|
|||||||
Card cardForUi = host.getCardForUi();
|
Card cardForUi = host.getCardForUi();
|
||||||
String effectDesc = TextUtil.fastReplace(replacementEffect.toString(), "CARDNAME", cardForUi.getName());
|
String effectDesc = TextUtil.fastReplace(replacementEffect.toString(), "CARDNAME", cardForUi.getName());
|
||||||
final String question = replacementEffect instanceof ReplaceDiscard
|
final String question = replacementEffect instanceof ReplaceDiscard
|
||||||
? TextUtil.concatWithSpace("Apply replacement effect of", cardForUi.toString(), "to", TextUtil.addSuffix(runParams.get("Card").toString(),"?\r\n"), TextUtil.enclosedParen(effectDesc))
|
? TextUtil.concatWithSpace("Apply replacement effect of", cardForUi.toString(), "to", TextUtil.addSuffix(runParams.get(AbilityKey.Card).toString(),"?\r\n"), TextUtil.enclosedParen(effectDesc))
|
||||||
: TextUtil.concatWithSpace("Apply replacement effect of", TextUtil.addSuffix(cardForUi.toString(),"?\r\n"), TextUtil.enclosedParen(effectDesc));
|
: TextUtil.concatWithSpace("Apply replacement effect of", TextUtil.addSuffix(cardForUi.toString(),"?\r\n"), TextUtil.enclosedParen(effectDesc));
|
||||||
boolean confirmed = optDecider.getController().confirmReplacementEffect(replacementEffect, effectSA, question);
|
boolean confirmed = optDecider.getController().confirmReplacementEffect(replacementEffect, effectSA, question);
|
||||||
if (!confirmed) {
|
if (!confirmed) {
|
||||||
@@ -292,9 +293,9 @@ public class ReplacementHandler {
|
|||||||
Player player = host.getController();
|
Player player = host.getController();
|
||||||
|
|
||||||
if (mapParams.containsKey("ManaReplacement")) {
|
if (mapParams.containsKey("ManaReplacement")) {
|
||||||
final SpellAbility manaAb = (SpellAbility) runParams.get("AbilityMana");
|
final SpellAbility manaAb = (SpellAbility) runParams.get(AbilityKey.AbilityMana);
|
||||||
final Player player1 = (Player) runParams.get("Player");
|
final Player player1 = (Player) runParams.get(AbilityKey.Player);
|
||||||
final String rep = (String) runParams.get("Mana");
|
final String rep = (String) runParams.get(AbilityKey.Mana);
|
||||||
// Replaced mana type
|
// Replaced mana type
|
||||||
final Card repHost = host;
|
final Card repHost = host;
|
||||||
String repType = repHost.getSVar(mapParams.get("ManaReplacement"));
|
String repType = repHost.getSVar(mapParams.get("ManaReplacement"));
|
||||||
@@ -307,8 +308,8 @@ public class ReplacementHandler {
|
|||||||
player.getController().playSpellAbilityNoStack(effectSA, true);
|
player.getController().playSpellAbilityNoStack(effectSA, true);
|
||||||
// if the spellability is a replace effect then its some new logic
|
// if the spellability is a replace effect then its some new logic
|
||||||
// if ReplacementResult is set in run params use that instead
|
// if ReplacementResult is set in run params use that instead
|
||||||
if (runParams.containsKey("ReplacementResult")) {
|
if (runParams.containsKey(AbilityKey.ReplacementResult)) {
|
||||||
return (ReplacementResult) runParams.get("ReplacementResult");
|
return (ReplacementResult) runParams.get(AbilityKey.ReplacementResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,31 +357,4 @@ public class ReplacementHandler {
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanUpTemporaryReplacements() {
|
|
||||||
game.forEachCardInGame(new Visitor<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean visit(Card c) {
|
|
||||||
List<ReplacementEffect> toRemove = Lists.newArrayList();
|
|
||||||
for (ReplacementEffect rep : c.getReplacementEffects()) {
|
|
||||||
if (rep.isTemporary()) {
|
|
||||||
toRemove.add(rep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (ReplacementEffect rep : toRemove) {
|
|
||||||
c.removeReplacementEffect(rep);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
game.forEachCardInGame(new Visitor<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean visit(Card c) {
|
|
||||||
for (int i = 0; i < c.getReplacementEffects().size(); i++) {
|
|
||||||
c.getReplacementEffects().get(i).setTemporarilySuppressed(false);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,11 +128,10 @@ public class AbilityManaPart implements java.io.Serializable {
|
|||||||
final Card source = this.getSourceCard();
|
final Card source = this.getSourceCard();
|
||||||
final ManaPool manaPool = player.getManaPool();
|
final ManaPool manaPool = player.getManaPool();
|
||||||
String afterReplace = applyManaReplacement(sa, produced);
|
String afterReplace = applyManaReplacement(sa, produced);
|
||||||
final Map<String, Object> repParams = Maps.newHashMap();
|
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(source);
|
||||||
repParams.put("Mana", afterReplace);
|
repParams.put(AbilityKey.Mana, afterReplace);
|
||||||
repParams.put("Affected", source);
|
repParams.put(AbilityKey.Player, player);
|
||||||
repParams.put("Player", player);
|
repParams.put(AbilityKey.AbilityMana, sa);
|
||||||
repParams.put("AbilityMana", sa);
|
|
||||||
if (player.getGame().getReplacementHandler().run(ReplacementType.ProduceMana, repParams) != ReplacementResult.NotReplaced) {
|
if (player.getGame().getReplacementHandler().run(ReplacementType.ProduceMana, repParams) != ReplacementResult.NotReplaced) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
|
|
||||||
private EnumMap<AbilityKey, Object> triggeringObjects = AbilityKey.newMap();
|
private EnumMap<AbilityKey, Object> triggeringObjects = AbilityKey.newMap();
|
||||||
|
|
||||||
private HashMap<String, Object> replacingObjects = Maps.newHashMap();
|
private EnumMap<AbilityKey, Object> replacingObjects = AbilityKey.newMap();
|
||||||
|
|
||||||
private List<AbilitySub> chosenList = null;
|
private List<AbilitySub> chosenList = null;
|
||||||
private CardCollection tappedForConvoke = new CardCollection();
|
private CardCollection tappedForConvoke = new CardCollection();
|
||||||
@@ -593,17 +593,15 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
triggerRemembered = Lists.newArrayList();
|
triggerRemembered = Lists.newArrayList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashMap<String, Object> getReplacingObjects() {
|
public Map<AbilityKey, Object> getReplacingObjects() {
|
||||||
return replacingObjects;
|
return replacingObjects;
|
||||||
}
|
}
|
||||||
public boolean hasReplacingObject(final String type) {
|
public Object getReplacingObject(final AbilityKey type) {
|
||||||
return replacingObjects.containsKey(type);
|
|
||||||
}
|
|
||||||
public Object getReplacingObject(final String type) {
|
|
||||||
final Object res = replacingObjects.get(type);
|
final Object res = replacingObjects.get(type);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
public void setReplacingObject(final String type, final Object o) {
|
|
||||||
|
public void setReplacingObject(final AbilityKey type, final Object o) {
|
||||||
replacingObjects.put(type, o);
|
replacingObjects.put(type, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,15 @@ public final class SpellAbilityPredicates extends CardTraitPredicates {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final Predicate<SpellAbility> isManaAbility() {
|
||||||
|
return new Predicate<SpellAbility>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(final SpellAbility sa) {
|
||||||
|
return sa.isManaAbility();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static final Predicate<SpellAbility> isIntrinsic() {
|
public static final Predicate<SpellAbility> isIntrinsic() {
|
||||||
return new Predicate<SpellAbility>() {
|
return new Predicate<SpellAbility>() {
|
||||||
|
|||||||
@@ -159,14 +159,14 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("RemoveAllAbilities") || hasParam("GainsAbilitiesOf")) {
|
if (hasParam("RemoveAllAbilities") || hasParam("GainsAbilitiesOf")) {
|
||||||
layers.add(StaticAbilityLayer.ABILITIES1);
|
layers.add(StaticAbilityLayer.ABILITIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("AddKeyword") || hasParam("AddAbility")
|
if (hasParam("AddKeyword") || hasParam("AddAbility")
|
||||||
|| hasParam("AddTrigger") || hasParam("RemoveTriggers")
|
|| hasParam("AddTrigger") || hasParam("RemoveTriggers")
|
||||||
|| hasParam("RemoveKeyword") || hasParam("AddReplacementEffects")
|
|| hasParam("RemoveKeyword") || hasParam("AddReplacementEffects")
|
||||||
|| hasParam("AddStaticAbility") || hasParam("AddSVar")) {
|
|| hasParam("AddStaticAbility") || hasParam("AddSVar")) {
|
||||||
layers.add(StaticAbilityLayer.ABILITIES2);
|
layers.add(StaticAbilityLayer.ABILITIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("CharacteristicDefining")) {
|
if (hasParam("CharacteristicDefining")) {
|
||||||
@@ -183,7 +183,7 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
|
|||||||
if (hasParam("AddHiddenKeyword")) {
|
if (hasParam("AddHiddenKeyword")) {
|
||||||
// special rule for can't have or gain
|
// special rule for can't have or gain
|
||||||
if (getParam("AddHiddenKeyword").contains("can't have or gain")) {
|
if (getParam("AddHiddenKeyword").contains("can't have or gain")) {
|
||||||
layers.add(StaticAbilityLayer.ABILITIES1);
|
layers.add(StaticAbilityLayer.ABILITIES);
|
||||||
}
|
}
|
||||||
layers.add(StaticAbilityLayer.RULES);
|
layers.add(StaticAbilityLayer.RULES);
|
||||||
}
|
}
|
||||||
@@ -259,14 +259,14 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final CardCollectionView applyContinuousAbilityBefore(final StaticAbilityLayer layer, final CardCollectionView preList) {
|
public final CardCollectionView applyContinuousAbilityBefore(final StaticAbilityLayer layer, final CardCollectionView preList) {
|
||||||
if (!shouldApplyContinuousAbility(layer, false)) {
|
if (!shouldApplyContinuousAbility(layer)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return StaticAbilityContinuous.applyContinuousAbility(this, layer, preList);
|
return StaticAbilityContinuous.applyContinuousAbility(this, layer, preList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final CardCollectionView applyContinuousAbility(final StaticAbilityLayer layer, final CardCollectionView affected) {
|
public final CardCollectionView applyContinuousAbility(final StaticAbilityLayer layer, final CardCollectionView affected) {
|
||||||
if (!shouldApplyContinuousAbility(layer, true)) {
|
if (!shouldApplyContinuousAbility(layer)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return StaticAbilityContinuous.applyContinuousAbility(this, affected, layer);
|
return StaticAbilityContinuous.applyContinuousAbility(this, affected, layer);
|
||||||
@@ -286,14 +286,8 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
|
|||||||
* affects the specified layer, it's not suppressed, and its
|
* affects the specified layer, it's not suppressed, and its
|
||||||
* conditions are fulfilled.
|
* conditions are fulfilled.
|
||||||
*/
|
*/
|
||||||
private boolean shouldApplyContinuousAbility(final StaticAbilityLayer layer, final boolean ignoreTempSuppression) {
|
private boolean shouldApplyContinuousAbility(final StaticAbilityLayer layer) {
|
||||||
final boolean isSuppressed;
|
return getParam("Mode").equals("Continuous") && layers.contains(layer) && !isSuppressed() && this.checkConditions();
|
||||||
if (ignoreTempSuppression) {
|
|
||||||
isSuppressed = this.isNonTempSuppressed();
|
|
||||||
} else {
|
|
||||||
isSuppressed = this.isSuppressed();
|
|
||||||
}
|
|
||||||
return getParam("Mode").equals("Continuous") && layers.contains(layer) && !isSuppressed && this.checkConditions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply the ability if it has the right mode
|
// apply the ability if it has the right mode
|
||||||
|
|||||||
@@ -122,7 +122,6 @@ public final class StaticAbilityContinuous {
|
|||||||
String addColors = null;
|
String addColors = null;
|
||||||
String[] addTriggers = null;
|
String[] addTriggers = null;
|
||||||
String[] addStatics = null;
|
String[] addStatics = null;
|
||||||
List<SpellAbility> addFullAbs = null;
|
|
||||||
boolean removeAllAbilities = false;
|
boolean removeAllAbilities = false;
|
||||||
boolean removeIntrinsicAbilities = false;
|
boolean removeIntrinsicAbilities = false;
|
||||||
boolean removeNonMana = false;
|
boolean removeNonMana = false;
|
||||||
@@ -187,7 +186,7 @@ public final class StaticAbilityContinuous {
|
|||||||
toughnessBonus = AbilityUtils.calculateAmount(hostCard, addT, stAb, true);
|
toughnessBonus = AbilityUtils.calculateAmount(hostCard, addT, stAb, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer == StaticAbilityLayer.ABILITIES2 && params.containsKey("AddKeyword")) {
|
if (layer == StaticAbilityLayer.ABILITIES && params.containsKey("AddKeyword")) {
|
||||||
addKeywords = params.get("AddKeyword").split(" & ");
|
addKeywords = params.get("AddKeyword").split(" & ");
|
||||||
final Iterable<String> chosencolors = hostCard.getChosenColors();
|
final Iterable<String> chosencolors = hostCard.getChosenColors();
|
||||||
for (final String color : chosencolors) {
|
for (final String color : chosencolors) {
|
||||||
@@ -222,31 +221,31 @@ public final class StaticAbilityContinuous {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((layer == StaticAbilityLayer.RULES || layer == StaticAbilityLayer.ABILITIES1) && params.containsKey("AddHiddenKeyword")) {
|
if ((layer == StaticAbilityLayer.RULES || layer == StaticAbilityLayer.ABILITIES) && params.containsKey("AddHiddenKeyword")) {
|
||||||
// can't have or gain, need to be applyed in ABILITIES1
|
// can't have or gain, need to be applyed in ABILITIES1
|
||||||
for (String k : params.get("AddHiddenKeyword").split(" & ")) {
|
for (String k : params.get("AddHiddenKeyword").split(" & ")) {
|
||||||
if ( (k.contains("can't have or gain")) == (layer == StaticAbilityLayer.ABILITIES1))
|
if ( (k.contains("can't have or gain")) == (layer == StaticAbilityLayer.ABILITIES))
|
||||||
addHiddenKeywords.add(k);
|
addHiddenKeywords.add(k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer == StaticAbilityLayer.ABILITIES2 && params.containsKey("RemoveKeyword")) {
|
if (layer == StaticAbilityLayer.ABILITIES && params.containsKey("RemoveKeyword")) {
|
||||||
removeKeywords = params.get("RemoveKeyword").split(" & ");
|
removeKeywords = params.get("RemoveKeyword").split(" & ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer == StaticAbilityLayer.ABILITIES1 && params.containsKey("RemoveAllAbilities")) {
|
if (layer == StaticAbilityLayer.ABILITIES && params.containsKey("RemoveAllAbilities")) {
|
||||||
removeAllAbilities = true;
|
removeAllAbilities = true;
|
||||||
if (params.containsKey("ExceptManaAbilities")) {
|
if (params.containsKey("ExceptManaAbilities")) {
|
||||||
removeNonMana = true;
|
removeNonMana = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// do this in type layer too in case of blood moon
|
// do this in type layer too in case of blood moon
|
||||||
if ((layer == StaticAbilityLayer.ABILITIES1 || layer == StaticAbilityLayer.TYPE)
|
if ((layer == StaticAbilityLayer.TYPE)
|
||||||
&& params.containsKey("RemoveIntrinsicAbilities")) {
|
&& params.containsKey("RemoveIntrinsicAbilities")) {
|
||||||
removeIntrinsicAbilities = true;
|
removeIntrinsicAbilities = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer == StaticAbilityLayer.ABILITIES2 && params.containsKey("AddAbility")) {
|
if (layer == StaticAbilityLayer.ABILITIES && params.containsKey("AddAbility")) {
|
||||||
final String[] sVars = params.get("AddAbility").split(" & ");
|
final String[] sVars = params.get("AddAbility").split(" & ");
|
||||||
for (int i = 0; i < sVars.length; i++) {
|
for (int i = 0; i < sVars.length; i++) {
|
||||||
sVars[i] = hostCard.getSVar(sVars[i]);
|
sVars[i] = hostCard.getSVar(sVars[i]);
|
||||||
@@ -254,7 +253,7 @@ public final class StaticAbilityContinuous {
|
|||||||
addAbilities = sVars;
|
addAbilities = sVars;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer == StaticAbilityLayer.ABILITIES2 && params.containsKey("AddReplacementEffects")) {
|
if (layer == StaticAbilityLayer.ABILITIES && params.containsKey("AddReplacementEffects")) {
|
||||||
final String[] sVars = params.get("AddReplacementEffects").split(" & ");
|
final String[] sVars = params.get("AddReplacementEffects").split(" & ");
|
||||||
for (int i = 0; i < sVars.length; i++) {
|
for (int i = 0; i < sVars.length; i++) {
|
||||||
sVars[i] = hostCard.getSVar(sVars[i]);
|
sVars[i] = hostCard.getSVar(sVars[i]);
|
||||||
@@ -262,7 +261,7 @@ public final class StaticAbilityContinuous {
|
|||||||
addReplacements = sVars;
|
addReplacements = sVars;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer == StaticAbilityLayer.ABILITIES2 && params.containsKey("AddSVar")) {
|
if (layer == StaticAbilityLayer.ABILITIES && params.containsKey("AddSVar")) {
|
||||||
addSVars = params.get("AddSVar").split(" & ");
|
addSVars = params.get("AddSVar").split(" & ");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,7 +338,7 @@ public final class StaticAbilityContinuous {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer == StaticAbilityLayer.ABILITIES2) {
|
if (layer == StaticAbilityLayer.ABILITIES) {
|
||||||
if (params.containsKey("AddTrigger")) {
|
if (params.containsKey("AddTrigger")) {
|
||||||
final String[] sVars = params.get("AddTrigger").split(" & ");
|
final String[] sVars = params.get("AddTrigger").split(" & ");
|
||||||
for (int i = 0; i < sVars.length; i++) {
|
for (int i = 0; i < sVars.length; i++) {
|
||||||
@@ -357,45 +356,6 @@ public final class StaticAbilityContinuous {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer == StaticAbilityLayer.ABILITIES1 && params.containsKey("GainsAbilitiesOf")) {
|
|
||||||
final String[] valids = params.get("GainsAbilitiesOf").split(",");
|
|
||||||
List<ZoneType> validZones;
|
|
||||||
final boolean loyaltyAB = params.containsKey("GainsLoyaltyAbilities");
|
|
||||||
if (params.containsKey("GainsAbilitiesOfZones")) {
|
|
||||||
validZones = ZoneType.listValueOf(params.get("GainsAbilitiesOfZones"));
|
|
||||||
} else {
|
|
||||||
validZones = ImmutableList.of(ZoneType.Battlefield);
|
|
||||||
}
|
|
||||||
|
|
||||||
CardCollectionView cardsIGainedAbilitiesFrom = game.getCardsIn(validZones);
|
|
||||||
cardsIGainedAbilitiesFrom = CardLists.getValidCards(cardsIGainedAbilitiesFrom, valids, hostCard.getController(), hostCard, null);
|
|
||||||
|
|
||||||
if (cardsIGainedAbilitiesFrom.size() > 0) {
|
|
||||||
addFullAbs = Lists.newArrayList();
|
|
||||||
|
|
||||||
for (Card c : cardsIGainedAbilitiesFrom) {
|
|
||||||
for (SpellAbility sa : c.getSpellAbilities()) {
|
|
||||||
if (sa instanceof AbilityActivated) {
|
|
||||||
if (loyaltyAB && !sa.isPwAbility()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SpellAbility newSA = sa.copy(hostCard, false);
|
|
||||||
if (params.containsKey("GainsAbilitiesLimitPerTurn")) {
|
|
||||||
newSA.setRestrictions(sa.getRestrictions());
|
|
||||||
newSA.getRestrictions().setLimitToCheck(params.get("GainsAbilitiesLimitPerTurn"));
|
|
||||||
}
|
|
||||||
newSA.setOriginalHost(c);
|
|
||||||
newSA.setOriginalAbility(sa); // need to be set to get the Once Per turn Clause correct
|
|
||||||
newSA.setGrantorStatic(stAb);
|
|
||||||
newSA.setIntrinsic(false);
|
|
||||||
newSA.setTemporary(true);
|
|
||||||
addFullAbs.add(newSA);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (layer == StaticAbilityLayer.RULES) {
|
if (layer == StaticAbilityLayer.RULES) {
|
||||||
// These fall under Rule changes, as they don't fit any other category
|
// These fall under Rule changes, as they don't fit any other category
|
||||||
if (params.containsKey("MayLookAt")) {
|
if (params.containsKey("MayLookAt")) {
|
||||||
@@ -444,7 +404,6 @@ public final class StaticAbilityContinuous {
|
|||||||
if (addStatics != null) {
|
if (addStatics != null) {
|
||||||
for (String s : addStatics) {
|
for (String s : addStatics) {
|
||||||
StaticAbility stat = p.addStaticAbility(hostCard, s);
|
StaticAbility stat = p.addStaticAbility(hostCard, s);
|
||||||
stat.setTemporary(true);
|
|
||||||
stat.setIntrinsic(false);
|
stat.setIntrinsic(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -582,38 +541,117 @@ public final class StaticAbilityContinuous {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addFullAbs != null) {
|
if (layer == StaticAbilityLayer.ABILITIES) {
|
||||||
for (final SpellAbility ab : addFullAbs) {
|
|
||||||
affectedCard.addSpellAbility(ab, false);
|
List<SpellAbility> addedAbilities = Lists.newArrayList();
|
||||||
|
List<ReplacementEffect> addedReplacementEffects = Lists.newArrayList();
|
||||||
|
List<Trigger> addedTrigger = Lists.newArrayList();
|
||||||
|
List<StaticAbility> addedStaticAbility = Lists.newArrayList();
|
||||||
|
// add abilities
|
||||||
|
if (addAbilities != null) {
|
||||||
|
for (String abilty : addAbilities) {
|
||||||
|
if (abilty.contains("CardManaCost")) {
|
||||||
|
abilty = TextUtil.fastReplace(abilty, "CardManaCost", affectedCard.getManaCost().getShortString());
|
||||||
|
} else if (abilty.contains("ConvertedManaCost")) {
|
||||||
|
final String costcmc = Integer.toString(affectedCard.getCMC());
|
||||||
|
abilty = TextUtil.fastReplace(abilty, "ConvertedManaCost", costcmc);
|
||||||
|
}
|
||||||
|
if (abilty.startsWith("AB") || abilty.startsWith("ST")) { // grant the ability
|
||||||
|
final SpellAbility sa = AbilityFactory.getAbility(abilty, affectedCard);
|
||||||
|
sa.setIntrinsic(false);
|
||||||
|
sa.setOriginalHost(hostCard);
|
||||||
|
addedAbilities.add(sa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.containsKey("GainsAbilitiesOf")) {
|
||||||
|
final String[] valids = params.get("GainsAbilitiesOf").split(",");
|
||||||
|
List<ZoneType> validZones;
|
||||||
|
final boolean loyaltyAB = params.containsKey("GainsLoyaltyAbilities");
|
||||||
|
if (params.containsKey("GainsAbilitiesOfZones")) {
|
||||||
|
validZones = ZoneType.listValueOf(params.get("GainsAbilitiesOfZones"));
|
||||||
|
} else {
|
||||||
|
validZones = ImmutableList.of(ZoneType.Battlefield);
|
||||||
|
}
|
||||||
|
|
||||||
|
CardCollectionView cardsIGainedAbilitiesFrom = game.getCardsIn(validZones);
|
||||||
|
cardsIGainedAbilitiesFrom = CardLists.getValidCards(cardsIGainedAbilitiesFrom, valids, hostCard.getController(), hostCard, null);
|
||||||
|
|
||||||
|
for (Card c : cardsIGainedAbilitiesFrom) {
|
||||||
|
for (SpellAbility sa : c.getSpellAbilities()) {
|
||||||
|
if (sa instanceof AbilityActivated) {
|
||||||
|
if (loyaltyAB && !sa.isPwAbility()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
SpellAbility newSA = sa.copy(affectedCard, false);
|
||||||
|
if (params.containsKey("GainsAbilitiesLimitPerTurn")) {
|
||||||
|
newSA.setRestrictions(sa.getRestrictions());
|
||||||
|
newSA.getRestrictions().setLimitToCheck(params.get("GainsAbilitiesLimitPerTurn"));
|
||||||
|
}
|
||||||
|
newSA.setOriginalHost(c);
|
||||||
|
newSA.setOriginalAbility(sa); // need to be set to get the Once Per turn Clause correct
|
||||||
|
newSA.setGrantorStatic(stAb);
|
||||||
|
newSA.setIntrinsic(false);
|
||||||
|
addedAbilities.add(newSA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add Replacement effects
|
||||||
|
if (addReplacements != null) {
|
||||||
|
for (String rep : addReplacements) {
|
||||||
|
final ReplacementEffect actualRep = ReplacementHandler.parseReplacement(rep, affectedCard, false);
|
||||||
|
actualRep.setIntrinsic(false);
|
||||||
|
addedReplacementEffects.add(actualRep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add triggers
|
||||||
|
if (addTriggers != null) {
|
||||||
|
for (final String trigger : addTriggers) {
|
||||||
|
final Trigger actualTrigger = TriggerHandler.parseTrigger(trigger, affectedCard, false);
|
||||||
|
// if the trigger has Execute param, which most trigger gained by Static Abilties should have
|
||||||
|
// turn them into SpellAbility object before adding to card
|
||||||
|
// with that the TargetedCard does not need the Svars added to them anymore
|
||||||
|
// but only do it if the trigger doesn't already have a overriding ability
|
||||||
|
if (actualTrigger.hasParam("Execute") && actualTrigger.getOverridingAbility() == null) {
|
||||||
|
SpellAbility sa = AbilityFactory.getAbility(hostCard, actualTrigger.getParam("Execute"));
|
||||||
|
// set hostcard there so when the card is added to trigger, it doesn't make a copy of it
|
||||||
|
sa.setHostCard(affectedCard);
|
||||||
|
// set OriginalHost to get the owner of this static ability
|
||||||
|
sa.setOriginalHost(hostCard);
|
||||||
|
// set overriding ability to the trigger
|
||||||
|
actualTrigger.setOverridingAbility(sa);
|
||||||
|
}
|
||||||
|
actualTrigger.setIntrinsic(false);
|
||||||
|
addedTrigger.add(actualTrigger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add static abilities
|
||||||
|
if (addStatics != null) {
|
||||||
|
for (String s : addStatics) {
|
||||||
|
if (s.contains("ConvertedManaCost")) {
|
||||||
|
final String costcmc = Integer.toString(affectedCard.getCMC());
|
||||||
|
s = TextUtil.fastReplace(s, "ConvertedManaCost", costcmc);
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticAbility stat = new StaticAbility(s, affectedCard);
|
||||||
|
stat.setIntrinsic(false);
|
||||||
|
addedStaticAbility.add(stat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!addedAbilities.isEmpty() || addReplacements != null || addTriggers != null || addStatics != null
|
||||||
|
|| removeAllAbilities) {
|
||||||
|
affectedCard.addChangedCardTraits(addedAbilities, null, addedTrigger, addedReplacementEffects, addedStaticAbility, removeAllAbilities, removeNonMana, false, hostCard.getTimestamp());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add abilities
|
if (layer == StaticAbilityLayer.TYPE && removeIntrinsicAbilities) {
|
||||||
if (addAbilities != null) {
|
affectedCard.addChangedCardTraits(null, null, null, null, null, false, false, removeIntrinsicAbilities, hostCard.getTimestamp());
|
||||||
for (String abilty : addAbilities) {
|
|
||||||
if (abilty.contains("CardManaCost")) {
|
|
||||||
abilty = TextUtil.fastReplace(abilty, "CardManaCost", affectedCard.getManaCost().getShortString());
|
|
||||||
} else if (abilty.contains("ConvertedManaCost")) {
|
|
||||||
final String costcmc = Integer.toString(affectedCard.getCMC());
|
|
||||||
abilty = TextUtil.fastReplace(abilty, "ConvertedManaCost", costcmc);
|
|
||||||
}
|
|
||||||
if (abilty.startsWith("AB") || abilty.startsWith("ST")) { // grant the ability
|
|
||||||
final SpellAbility sa = AbilityFactory.getAbility(abilty, affectedCard);
|
|
||||||
sa.setTemporary(true);
|
|
||||||
sa.setIntrinsic(false);
|
|
||||||
sa.setOriginalHost(hostCard);
|
|
||||||
affectedCard.addSpellAbility(sa, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add Replacement effects
|
|
||||||
if (addReplacements != null) {
|
|
||||||
for (String rep : addReplacements) {
|
|
||||||
final ReplacementEffect actualRep = ReplacementHandler.parseReplacement(rep, affectedCard, false);
|
|
||||||
actualRep.setIntrinsic(false);
|
|
||||||
affectedCard.addReplacementEffect(actualRep).setTemporary(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add Types
|
// add Types
|
||||||
@@ -628,81 +666,6 @@ public final class StaticAbilityContinuous {
|
|||||||
affectedCard.addColor(addColors, !overwriteColors, hostCard.getTimestamp());
|
affectedCard.addColor(addColors, !overwriteColors, hostCard.getTimestamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
// add triggers
|
|
||||||
if (addTriggers != null) {
|
|
||||||
for (final String trigger : addTriggers) {
|
|
||||||
final Trigger actualTrigger = TriggerHandler.parseTrigger(trigger, affectedCard, false);
|
|
||||||
// if the trigger has Execute param, which most trigger gained by Static Abilties should have
|
|
||||||
// turn them into SpellAbility object before adding to card
|
|
||||||
// with that the TargetedCard does not need the Svars added to them anymore
|
|
||||||
// but only do it if the trigger doesn't already have a overriding ability
|
|
||||||
if (actualTrigger.hasParam("Execute") && actualTrigger.getOverridingAbility() == null) {
|
|
||||||
SpellAbility sa = AbilityFactory.getAbility(hostCard, actualTrigger.getParam("Execute"));
|
|
||||||
// set hostcard there so when the card is added to trigger, it doesn't make a copy of it
|
|
||||||
sa.setHostCard(affectedCard);
|
|
||||||
// set OriginalHost to get the owner of this static ability
|
|
||||||
sa.setOriginalHost(hostCard);
|
|
||||||
// set overriding ability to the trigger
|
|
||||||
actualTrigger.setOverridingAbility(sa);
|
|
||||||
}
|
|
||||||
actualTrigger.setIntrinsic(false);
|
|
||||||
affectedCard.addTrigger(actualTrigger).setTemporary(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add static abilities
|
|
||||||
if (addStatics != null) {
|
|
||||||
for (String s : addStatics) {
|
|
||||||
if (s.contains("ConvertedManaCost")) {
|
|
||||||
final String costcmc = Integer.toString(affectedCard.getCMC());
|
|
||||||
s = TextUtil.fastReplace(s, "ConvertedManaCost", costcmc);
|
|
||||||
}
|
|
||||||
|
|
||||||
StaticAbility stat = affectedCard.addStaticAbility(s);
|
|
||||||
stat.setTemporary(true);
|
|
||||||
stat.setIntrinsic(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove triggers
|
|
||||||
if ((layer == StaticAbilityLayer.ABILITIES2 && (params.containsKey("RemoveTriggers"))
|
|
||||||
|| removeAllAbilities || removeIntrinsicAbilities)) {
|
|
||||||
for (final Trigger trigger : affectedCard.getTriggers()) {
|
|
||||||
if (removeAllAbilities || (removeIntrinsicAbilities && trigger.isIntrinsic())) {
|
|
||||||
trigger.setTemporarilySuppressed(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove activated and static abilities
|
|
||||||
if (removeAllAbilities || removeIntrinsicAbilities) {
|
|
||||||
if (removeNonMana) { // Blood Sun
|
|
||||||
for (final SpellAbility mana : affectedCard.getNonManaAbilities()) {
|
|
||||||
if (removeAllAbilities
|
|
||||||
|| (removeIntrinsicAbilities && mana.isIntrinsic() && !mana.isBasicLandAbility())) {
|
|
||||||
mana.setTemporarilySuppressed(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (final SpellAbility ab : affectedCard.getSpellAbilities()) {
|
|
||||||
if (removeAllAbilities
|
|
||||||
|| (removeIntrinsicAbilities && ab.isIntrinsic() && !ab.isBasicLandAbility())) {
|
|
||||||
ab.setTemporarilySuppressed(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (final StaticAbility stA : affectedCard.getStaticAbilities()) {
|
|
||||||
if (removeAllAbilities || (removeIntrinsicAbilities && stA.isIntrinsic())) {
|
|
||||||
stA.setTemporarilySuppressed(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (final ReplacementEffect rE : affectedCard.getReplacementEffects()) {
|
|
||||||
if (removeAllAbilities || (removeIntrinsicAbilities && rE.isIntrinsic())) {
|
|
||||||
rE.setTemporarilySuppressed(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (layer == StaticAbilityLayer.RULES) {
|
if (layer == StaticAbilityLayer.RULES) {
|
||||||
if (params.containsKey("Goad")) {
|
if (params.containsKey("Goad")) {
|
||||||
affectedCard.addGoad(se.getTimestamp(), hostCard.getController());
|
affectedCard.addGoad(se.getTimestamp(), hostCard.getController());
|
||||||
@@ -765,11 +728,11 @@ public final class StaticAbilityContinuous {
|
|||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
addIgnore.setTemporary(true);
|
|
||||||
addIgnore.setIntrinsic(false);
|
addIgnore.setIntrinsic(false);
|
||||||
addIgnore.setApi(ApiType.InternalIgnoreEffect);
|
addIgnore.setApi(ApiType.InternalIgnoreEffect);
|
||||||
addIgnore.setDescription(cost + " Ignore the effect until end of turn.");
|
addIgnore.setDescription(cost + " Ignore the effect until end of turn.");
|
||||||
sourceCard.addSpellAbility(addIgnore);
|
sourceCard.addChangedCardTraits(ImmutableList.of(addIgnore), null, null, null, null, false, false, false, sourceCard.getTimestamp());
|
||||||
|
|
||||||
final GameCommand removeIgnore = new GameCommand() {
|
final GameCommand removeIgnore = new GameCommand() {
|
||||||
private static final long serialVersionUID = -5415775215053216360L;
|
private static final long serialVersionUID = -5415775215053216360L;
|
||||||
|
|||||||
@@ -18,11 +18,8 @@ public enum StaticAbilityLayer {
|
|||||||
/** Layer 5 for color-changing effects. */
|
/** Layer 5 for color-changing effects. */
|
||||||
COLOR,
|
COLOR,
|
||||||
|
|
||||||
/** Layer 6 for ability-removing and -copying effects. */
|
/** Layer 6 for ability effects. */
|
||||||
ABILITIES1,
|
ABILITIES,
|
||||||
|
|
||||||
/** Layer 6 for ability-granting effects. */
|
|
||||||
ABILITIES2,
|
|
||||||
|
|
||||||
/** Layer 7a for characteristic-defining power/toughness effects. */
|
/** Layer 7a for characteristic-defining power/toughness effects. */
|
||||||
CHARACTERISTIC,
|
CHARACTERISTIC,
|
||||||
@@ -37,5 +34,5 @@ public enum StaticAbilityLayer {
|
|||||||
RULES;
|
RULES;
|
||||||
|
|
||||||
public final static ImmutableList<StaticAbilityLayer> CONTINUOUS_LAYERS =
|
public final static ImmutableList<StaticAbilityLayer> CONTINUOUS_LAYERS =
|
||||||
ImmutableList.of(COPY, CONTROL, TEXT, TYPE, COLOR, ABILITIES1, ABILITIES2, CHARACTERISTIC, SETPT, MODIFYPT, RULES);
|
ImmutableList.of(COPY, CONTROL, TEXT, TYPE, COLOR, ABILITIES, CHARACTERISTIC, SETPT, MODIFYPT, RULES);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -561,7 +561,6 @@ public abstract class Trigger extends TriggerReplacementBase {
|
|||||||
copy.setTriggerPhases(Lists.newArrayList(validPhases));
|
copy.setTriggerPhases(Lists.newArrayList(validPhases));
|
||||||
}
|
}
|
||||||
copy.setActiveZone(validHostZones);
|
copy.setActiveZone(validHostZones);
|
||||||
copy.setTemporary(isTemporary());
|
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,42 +67,6 @@ public class TriggerHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final void cleanUpTemporaryTriggers() {
|
public final void cleanUpTemporaryTriggers() {
|
||||||
game.forEachCardInGame(new Visitor<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean visit(Card c) {
|
|
||||||
boolean changed = false;
|
|
||||||
List<Trigger> toRemove = Lists.newArrayList();
|
|
||||||
for (Trigger t : c.getTriggers()) {
|
|
||||||
if (t.isTemporary()) {
|
|
||||||
toRemove.add(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Trigger t : toRemove) {
|
|
||||||
changed = true;
|
|
||||||
c.removeTrigger(t);
|
|
||||||
}
|
|
||||||
if (changed) {
|
|
||||||
c.updateStateForView();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
game.forEachCardInGame(new Visitor<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean visit(Card c) {
|
|
||||||
boolean changed = false;
|
|
||||||
for (int i = 0; i < c.getTriggers().size(); i++) {
|
|
||||||
if (c.getTriggers().get(i).isSuppressed()) {
|
|
||||||
c.getTriggers().get(i).setTemporarilySuppressed(false);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (changed) {
|
|
||||||
c.updateStateForView();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean hasDelayedTriggers() {
|
public final boolean hasDelayedTriggers() {
|
||||||
@@ -699,9 +663,6 @@ public class TriggerHandler {
|
|||||||
Player p = regtrig.getHostCard().getController();
|
Player p = regtrig.getHostCard().getController();
|
||||||
p.getZone(ZoneType.Command).remove(regtrig.getHostCard());
|
p.getZone(ZoneType.Command).remove(regtrig.getHostCard());
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
regtrig.getHostCard().removeTrigger(regtrig);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -506,7 +506,7 @@ public class PlayerControllerForTests extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReplacementEffect chooseSingleReplacementEffect(String prompt, List<ReplacementEffect> possibleReplacers, Map<String, Object> runParams) {
|
public ReplacementEffect chooseSingleReplacementEffect(String prompt, List<ReplacementEffect> possibleReplacers) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return Iterables.getFirst(possibleReplacers, null);
|
return Iterables.getFirst(possibleReplacers, null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ Myrd
|
|||||||
nefigah
|
nefigah
|
||||||
OgreBattlecruiser
|
OgreBattlecruiser
|
||||||
pfps
|
pfps
|
||||||
|
Ryan1729
|
||||||
Seravy
|
Seravy
|
||||||
Sirspud
|
Sirspud
|
||||||
Sloth
|
Sloth
|
||||||
|
|||||||
17
forge-gui/res/puzzle/PS_ELD0.pzl
Normal file
17
forge-gui/res/puzzle/PS_ELD0.pzl
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
[metadata]
|
||||||
|
Name:Possibility Storm - Throne of Eldraine #00 (Pre-release Puzzle)
|
||||||
|
URL:http://www.possibilitystorm.com/wp-content/uploads/2019/10/130.-ELD001.jpg
|
||||||
|
Goal:Win
|
||||||
|
Turns:1
|
||||||
|
Difficulty:Uncommon
|
||||||
|
Description:Win this turn.
|
||||||
|
[state]
|
||||||
|
humanlife=20
|
||||||
|
ailife=12
|
||||||
|
turn=1
|
||||||
|
activeplayer=human
|
||||||
|
activephase=MAIN1
|
||||||
|
humanhand=Giant Opportunity;Mirrormade;Curious Pair;Frogify
|
||||||
|
humanbattlefield=Witch's Oven;Wicked Wolf;Maraleaf Rider;Oko, Thief of Crowns|Counters:LOYALTY=6;Forest;Forest;Forest;Island;Island;Island
|
||||||
|
aibattlefield=Wojek Bodyguard;Loyal Pegasus
|
||||||
|
humanprecast=Oko, Thief of Crowns:1
|
||||||
@@ -1,13 +1,10 @@
|
|||||||
package forge.match.input;
|
package forge.match.input;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Queue;
|
|
||||||
|
|
||||||
import forge.GuiBase;
|
import forge.GuiBase;
|
||||||
import forge.game.GameActionUtil;
|
import forge.game.GameActionUtil;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.spellability.SpellAbilityView;
|
import forge.game.spellability.SpellAbilityView;
|
||||||
import forge.util.TextUtil;
|
import forge.util.TextUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -363,11 +360,11 @@ public abstract class InputPayMana extends InputSyncronizedBase {
|
|||||||
final Card source = am.getHostCard();
|
final Card source = am.getHostCard();
|
||||||
final Player activator = am.getActivatingPlayer();
|
final Player activator = am.getActivatingPlayer();
|
||||||
final Game g = source.getGame();
|
final Game g = source.getGame();
|
||||||
final HashMap<String, Object> repParams = new HashMap<>();
|
final Map<AbilityKey, Object> repParams = AbilityKey.newMap();
|
||||||
repParams.put("Mana", m.getOrigProduced());
|
repParams.put(AbilityKey.Mana, m.getOrigProduced());
|
||||||
repParams.put("Affected", source);
|
repParams.put(AbilityKey.Affected, source);
|
||||||
repParams.put("Player", activator);
|
repParams.put(AbilityKey.Player, activator);
|
||||||
repParams.put("AbilityMana", am);
|
repParams.put(AbilityKey.AbilityMana, am);
|
||||||
|
|
||||||
for (final Player p : g.getPlayers()) {
|
for (final Player p : g.getPlayers()) {
|
||||||
for (final Card crd : p.getAllCards()) {
|
for (final Card crd : p.getAllCards()) {
|
||||||
|
|||||||
@@ -1587,7 +1587,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReplacementEffect chooseSingleReplacementEffect(final String prompt,
|
public ReplacementEffect chooseSingleReplacementEffect(final String prompt,
|
||||||
final List<ReplacementEffect> possibleReplacers, final Map<String, Object> runParams) {
|
final List<ReplacementEffect> possibleReplacers) {
|
||||||
final ReplacementEffect first = possibleReplacers.get(0);
|
final ReplacementEffect first = possibleReplacers.get(0);
|
||||||
if (possibleReplacers.size() == 1) {
|
if (possibleReplacers.size() == 1) {
|
||||||
return first;
|
return first;
|
||||||
|
|||||||
Reference in New Issue
Block a user