mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 11:18:01 +00:00
Merge branch 'cardTraitsReworkAnimate' into 'master'
Card: CardTraits are now not added to Card/State anymore but uses timestamp Closes #1165, #1120, #955, and #573 See merge request core-developers/forge!2216
This commit is contained in:
@@ -1266,7 +1266,7 @@ public class ComputerUtil {
|
||||
public static boolean preventRunAwayActivations(final SpellAbility sa) {
|
||||
int activations = sa.getActivationsThisTurn();
|
||||
|
||||
if (sa.isTemporary()) {
|
||||
if (!sa.isIntrinsic()) {
|
||||
return MyRandom.getRandom().nextFloat() >= .95; // Abilities created by static abilities have no memory
|
||||
}
|
||||
|
||||
|
||||
@@ -1128,14 +1128,14 @@ public class ComputerUtilCard {
|
||||
// assume it either benefits the player or disrupts the opponent
|
||||
for (final StaticAbility stAb : c.getStaticAbilities()) {
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!priority) {
|
||||
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
|
||||
priority = true;
|
||||
break;
|
||||
|
||||
@@ -467,26 +467,19 @@ public class AnimateAi extends SpellAbilityAi {
|
||||
|
||||
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
|
||||
final List<SpellAbility> removedAbilities = Lists.newArrayList();
|
||||
boolean clearAbilities = sa.hasParam("OverwriteAbilities");
|
||||
boolean clearSpells = sa.hasParam("OverwriteSpells");
|
||||
boolean removeAll = sa.hasParam("RemoveAllAbilities");
|
||||
boolean removeIntrinsic = sa.hasParam("RemoveIntrinsicAbilities");
|
||||
|
||||
if (clearAbilities || clearSpells || removeAll) {
|
||||
for (final SpellAbility ab : card.getSpellAbilities()) {
|
||||
if (removeAll
|
||||
|| (ab.isIntrinsic() && removeIntrinsic && !ab.isBasicLandAbility())
|
||||
|| (ab.isAbility() && clearAbilities)
|
||||
|| (ab.isSpell() && clearSpells)) {
|
||||
card.removeSpellAbility(ab);
|
||||
removedAbilities.add(ab);
|
||||
}
|
||||
}
|
||||
if (clearSpells) {
|
||||
removedAbilities.addAll(Lists.newArrayList(card.getSpells()));
|
||||
}
|
||||
|
||||
if (sa.hasParam("RemoveThisAbility") && !removedAbilities.contains(sa)) {
|
||||
removedAbilities.add(sa);
|
||||
}
|
||||
|
||||
// give abilities
|
||||
@@ -494,9 +487,7 @@ public class AnimateAi extends SpellAbilityAi {
|
||||
if (abilities.size() > 0) {
|
||||
for (final String s : abilities) {
|
||||
final String actualAbility = source.getSVar(s);
|
||||
final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, source);
|
||||
addedAbilities.add(grantedAbility);
|
||||
card.addSpellAbility(grantedAbility);
|
||||
addedAbilities.add(AbilityFactory.getAbility(actualAbility, card));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,8 +496,8 @@ public class AnimateAi extends SpellAbilityAi {
|
||||
if (triggers.size() > 0) {
|
||||
for (final String s : triggers) {
|
||||
final String actualTrigger = source.getSVar(s);
|
||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, source, false);
|
||||
addedTriggers.add(card.addTrigger(parsedTrigger));
|
||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, card, false);
|
||||
addedTriggers.add(parsedTrigger);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,24 +506,28 @@ public class AnimateAi extends SpellAbilityAi {
|
||||
if (replacements.size() > 0) {
|
||||
for (final String s : replacements) {
|
||||
final String actualReplacement = source.getSVar(s);
|
||||
final ReplacementEffect parsedReplacement = ReplacementHandler.parseReplacement(actualReplacement,
|
||||
source, false);
|
||||
addedReplacements.add(card.addReplacementEffect(parsedReplacement));
|
||||
final ReplacementEffect parsedReplacement = ReplacementHandler.parseReplacement(actualReplacement, card, false);
|
||||
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 : card.getTriggers()) {
|
||||
if (removeIntrinsic && !trigger.isIntrinsic()) {
|
||||
continue;
|
||||
}
|
||||
trigger.setSuppressed(true);
|
||||
removedTriggers.add(trigger);
|
||||
// give static abilities (should only be used by cards to give
|
||||
// itself a static ability)
|
||||
final List<StaticAbility> addedStaticAbilities = Lists.newArrayList();
|
||||
if (stAbs.size() > 0) {
|
||||
for (final String s : stAbs) {
|
||||
final String actualAbility = source.getSVar(s);
|
||||
addedStaticAbilities.add(new StaticAbility(actualAbility, card));
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
// itself a static ability)
|
||||
if (stAbs.size() > 0) {
|
||||
@@ -560,30 +555,6 @@ public class AnimateAi extends SpellAbilityAi {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,15 +38,9 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView {
|
||||
/** The is intrinsic. */
|
||||
protected boolean intrinsic;
|
||||
|
||||
/** The temporary. */
|
||||
protected boolean temporary = false;
|
||||
|
||||
/** The suppressed. */
|
||||
protected boolean suppressed = false;
|
||||
|
||||
/** The temporarily suppressed. */
|
||||
protected boolean temporarilySuppressed = false;
|
||||
|
||||
protected Map<String, String> sVars = 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()
|
||||
.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>
|
||||
@@ -196,26 +172,12 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView {
|
||||
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.
|
||||
*
|
||||
* @return true, if is suppressed
|
||||
*/
|
||||
public final boolean isSuppressed() {
|
||||
return (this.suppressed || this.temporarilySuppressed);
|
||||
}
|
||||
|
||||
protected final boolean isNonTempSuppressed() {
|
||||
return this.suppressed;
|
||||
}
|
||||
|
||||
|
||||
@@ -760,8 +760,6 @@ public class GameAction {
|
||||
|
||||
// remove old effects
|
||||
game.getStaticEffects().clearStaticEffects(affectedCards);
|
||||
game.getTriggerHandler().cleanUpTemporaryTriggers();
|
||||
game.getReplacementHandler().cleanUpTemporaryReplacements();
|
||||
|
||||
for (final Player p : game.getPlayers()) {
|
||||
if (!game.getStack().isFrozen()) {
|
||||
@@ -779,17 +777,11 @@ public class GameAction {
|
||||
public boolean visit(final Card c) {
|
||||
// need to get Card from preList if able
|
||||
final Card co = preList.get(c);
|
||||
List<StaticAbility> toRemove = Lists.newArrayList();
|
||||
for (StaticAbility stAb : co.getStaticAbilities()) {
|
||||
if (stAb.isTemporary()) {
|
||||
toRemove.add(stAb);
|
||||
} else if (stAb.getParam("Mode").equals("Continuous")) {
|
||||
if (stAb.getParam("Mode").equals("Continuous")) {
|
||||
staticAbilities.add(stAb);
|
||||
}
|
||||
}
|
||||
for (StaticAbility stAb : toRemove) {
|
||||
co.removeStaticAbility(stAb);
|
||||
}
|
||||
if (!co.getStaticCommandList().isEmpty()) {
|
||||
staticList.add(co);
|
||||
}
|
||||
|
||||
@@ -23,8 +23,6 @@ import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardCollectionView;
|
||||
import forge.game.card.CardUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.AbilityStatic;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.staticability.StaticAbility;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -236,11 +234,7 @@ public class StaticEffect {
|
||||
}
|
||||
|
||||
if (hasParam("IgnoreEffectCost")) {
|
||||
for (final SpellAbility s : getSource().getSpellAbilities()) {
|
||||
if (s instanceof AbilityStatic && s.isTemporary()) {
|
||||
getSource().removeSpellAbility(s);
|
||||
}
|
||||
}
|
||||
getSource().removeChangedCardTraits(getTimestamp());
|
||||
}
|
||||
|
||||
// modify players
|
||||
@@ -273,22 +267,12 @@ public class StaticEffect {
|
||||
// the view is updated in GameAction#checkStaticAbilities to avoid flickering
|
||||
|
||||
// remove keywords
|
||||
// TODO regular keywords currently don't try to use keyword multiplier
|
||||
// (Although nothing uses it at this time)
|
||||
if (hasParam("AddKeyword") || hasParam("RemoveKeyword")
|
||||
|| hasParam("RemoveAllAbilities")) {
|
||||
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) {
|
||||
for (final String k : addHiddenKeywords) {
|
||||
affectedCard.removeHiddenExtrinsicKeyword(k);
|
||||
@@ -296,8 +280,10 @@ public class StaticEffect {
|
||||
}
|
||||
|
||||
// remove abilities
|
||||
if (hasParam("RemoveAllAbilities") || hasParam("RemoveIntrinsicAbilities")) {
|
||||
affectedCard.unSuppressCardTraits();
|
||||
if (hasParam("AddAbility") || hasParam("GainsAbilitiesOf")
|
||||
|| hasParam("AddTrigger") || hasParam("AddStaticAbility") || hasParam("AddReplacementEffects")
|
||||
|| hasParam("RemoveAllAbilities") || hasParam("RemoveIntrinsicAbilities")) {
|
||||
affectedCard.removeChangedCardTraits(getTimestamp());
|
||||
}
|
||||
|
||||
// remove Types
|
||||
|
||||
@@ -80,4 +80,13 @@ public class StaticEffects {
|
||||
public Iterable<StaticEffect> getEffects() {
|
||||
return staticEffects.values();
|
||||
}
|
||||
|
||||
public boolean removeStaticEffect(final StaticAbility staticAbility) {
|
||||
final StaticEffect currentEffect = staticEffects.remove(staticAbility);
|
||||
if (currentEffect == null) {
|
||||
return false;
|
||||
}
|
||||
currentEffect.remove();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,19 +14,15 @@ import forge.game.player.Player;
|
||||
import forge.game.replacement.ReplacementEffect;
|
||||
import forge.game.replacement.ReplacementHandler;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.staticability.StaticAbility;
|
||||
import forge.game.trigger.Trigger;
|
||||
import forge.game.trigger.TriggerHandler;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.collect.FCollectionView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
public class AnimateAllEffect extends AnimateEffectBase {
|
||||
|
||||
@Override
|
||||
@@ -160,30 +156,16 @@ public class AnimateAllEffect extends AnimateEffectBase {
|
||||
final String actualAbility = host.getSVar(s);
|
||||
final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, c);
|
||||
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
|
||||
final List<ReplacementEffect> addedReplacements = new ArrayList<>();
|
||||
if (replacements.size() > 0) {
|
||||
for (final String s : replacements) {
|
||||
final String actualReplacement = host.getSVar(s);
|
||||
final ReplacementEffect parsedReplacement = ReplacementHandler.parseReplacement(actualReplacement, c, false);
|
||||
addedReplacements.add(c.addReplacementEffect(parsedReplacement));
|
||||
addedReplacements.add(parsedReplacement);
|
||||
}
|
||||
}
|
||||
// Grant triggers
|
||||
@@ -192,45 +174,12 @@ public class AnimateAllEffect extends AnimateEffectBase {
|
||||
for (final String s : triggers) {
|
||||
final String actualTrigger = host.getSVar(s);
|
||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, c, false);
|
||||
addedTriggers.add(c.addTrigger(parsedTrigger));
|
||||
addedTriggers.add(parsedTrigger);
|
||||
}
|
||||
}
|
||||
|
||||
// suppress triggers from the animated card
|
||||
final List<Trigger> removedTriggers = new ArrayList<>();
|
||||
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);
|
||||
}
|
||||
if (!addedAbilities.isEmpty() || !addedTriggers.isEmpty() || !addedReplacements.isEmpty()) {
|
||||
c.addChangedCardTraits(addedAbilities, null, addedTriggers, addedReplacements, null, removeAll, false, removeIntrinsic, timestamp);
|
||||
}
|
||||
|
||||
// give sVars
|
||||
@@ -247,27 +196,8 @@ public class AnimateAllEffect extends AnimateEffectBase {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
doUnanimate(c, sa, finalDesc, hiddenKeywords,
|
||||
addedAbilities, addedTriggers, addedReplacements,
|
||||
ImmutableList.of(), timestamp);
|
||||
doUnanimate(c, sa, hiddenKeywords, 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));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -162,25 +162,15 @@ public class AnimateEffect extends AnimateEffectBase {
|
||||
|
||||
// remove abilities
|
||||
final List<SpellAbility> removedAbilities = Lists.newArrayList();
|
||||
boolean clearAbilities = sa.hasParam("OverwriteAbilities");
|
||||
boolean clearSpells = sa.hasParam("OverwriteSpells");
|
||||
boolean removeAll = sa.hasParam("RemoveAllAbilities");
|
||||
boolean removeIntrinsic = sa.hasParam("RemoveIntrinsicAbilities");
|
||||
|
||||
if (clearAbilities || clearSpells || removeAll) {
|
||||
for (final SpellAbility ab : c.getSpellAbilities()) {
|
||||
if (removeAll
|
||||
|| (ab.isIntrinsic() && removeIntrinsic && !ab.isBasicLandAbility())
|
||||
|| (ab.isAbility() && clearAbilities)
|
||||
|| (ab.isSpell() && clearSpells)) {
|
||||
ab.setTemporarilySuppressed(true);
|
||||
removedAbilities.add(ab);
|
||||
}
|
||||
}
|
||||
if (clearSpells) {
|
||||
removedAbilities.addAll(Lists.newArrayList(c.getSpells()));
|
||||
}
|
||||
|
||||
if (sa.hasParam("RemoveThisAbility") && !removedAbilities.contains(sa)) {
|
||||
c.removeSpellAbility(sa);
|
||||
removedAbilities.add(sa);
|
||||
}
|
||||
|
||||
@@ -189,9 +179,7 @@ public class AnimateEffect extends AnimateEffectBase {
|
||||
if (abilities.size() > 0) {
|
||||
for (final String s : abilities) {
|
||||
final String actualAbility = source.getSVar(s);
|
||||
final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, c);
|
||||
addedAbilities.add(grantedAbility);
|
||||
c.addSpellAbility(grantedAbility);
|
||||
addedAbilities.add(AbilityFactory.getAbility(actualAbility, c));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +189,7 @@ public class AnimateEffect extends AnimateEffectBase {
|
||||
for (final String s : triggers) {
|
||||
final String actualTrigger = source.getSVar(s);
|
||||
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) {
|
||||
final String actualReplacement = source.getSVar(s);
|
||||
final ReplacementEffect parsedReplacement = ReplacementHandler.parseReplacement(actualReplacement, c, false);
|
||||
addedReplacements.add(c.addReplacementEffect(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);
|
||||
addedReplacements.add(parsedReplacement);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +209,7 @@ public class AnimateEffect extends AnimateEffectBase {
|
||||
if (stAbs.size() > 0) {
|
||||
for (final String s : stAbs) {
|
||||
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
|
||||
if (animateRemembered != null) {
|
||||
for (final Object o : AbilityUtils.getDefinedObjects(source, animateRemembered, sa)) {
|
||||
@@ -287,35 +239,40 @@ public class AnimateEffect extends AnimateEffectBase {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
doUnanimate(c, sa, finalDesc, hiddenKeywords,
|
||||
addedAbilities, addedTriggers, addedReplacements,
|
||||
addedStaticAbilities, timestamp);
|
||||
doUnanimate(c, sa, hiddenKeywords, timestamp);
|
||||
|
||||
c.removeChangedName(timestamp);
|
||||
c.updateStateForView();
|
||||
|
||||
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 (sa.hasParam("UntilEndOfCombat")) {
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -20,10 +20,8 @@ package forge.game.ability.effects;
|
||||
import forge.card.CardType;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.replacement.ReplacementEffect;
|
||||
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.staticability.StaticAbility;
|
||||
import forge.game.trigger.Trigger;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
||||
@@ -128,14 +126,8 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
||||
* @param timestamp
|
||||
* a long.
|
||||
*/
|
||||
static void doUnanimate(final Card c, SpellAbility sa, final String colorDesc,
|
||||
final List<String> hiddenKeywords, final List<SpellAbility> addedAbilities,
|
||||
final List<Trigger> addedTriggers, final List<ReplacementEffect> addedReplacements,
|
||||
final List<StaticAbility> addedStaticAbilities, final long timestamp) {
|
||||
|
||||
if (sa.hasParam("LastsIndefinitely")) {
|
||||
return;
|
||||
}
|
||||
static void doUnanimate(final Card c, SpellAbility sa,
|
||||
final List<String> hiddenKeywords, final long timestamp) {
|
||||
|
||||
c.removeNewPT(timestamp);
|
||||
|
||||
@@ -144,26 +136,12 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
||||
c.removeChangedCardTypes(timestamp);
|
||||
c.removeColor(timestamp);
|
||||
|
||||
c.removeChangedCardTraits(timestamp);
|
||||
|
||||
for (final String k : hiddenKeywords) {
|
||||
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
|
||||
if (!c.isCreature()) {
|
||||
c.unEquipAllCards();
|
||||
|
||||
@@ -58,7 +58,7 @@ public abstract class RegenerateBaseEffect extends SpellAbilityEffect {
|
||||
+ " | TriggerDescription$ " + trigSA.getDescription();
|
||||
final Trigger trigger = TriggerHandler.parseTrigger(trigStr, eff, true);
|
||||
trigger.setOverridingAbility(trigSA);
|
||||
eff.moveTrigger(trigger);
|
||||
eff.addTrigger(trigger);
|
||||
}
|
||||
|
||||
// Copy text changes
|
||||
|
||||
@@ -55,7 +55,6 @@ public class RestartGameEffect extends SpellAbilityEffect {
|
||||
forge.game.trigger.Trigger.resetIDs();
|
||||
TriggerHandler trigHandler = game.getTriggerHandler();
|
||||
trigHandler.clearDelayedTrigger();
|
||||
trigHandler.cleanUpTemporaryTriggers();
|
||||
trigHandler.suppressMode(TriggerType.ChangesZone);
|
||||
|
||||
game.getStack().reset();
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package forge.game.card;
|
||||
|
||||
import com.esotericsoftware.minlog.Log;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.*;
|
||||
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 NavigableMap<Long, String> changedCardNames = 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 NavigableMap<Long, CardCloneStates> clonedStates = Maps.newTreeMap();
|
||||
private final NavigableMap<Long, CardCloneStates> textChangeStates = Maps.newTreeMap();
|
||||
@@ -1012,28 +1014,15 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
public final FCollectionView<Trigger> 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) {
|
||||
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);
|
||||
return t;
|
||||
}
|
||||
@Deprecated
|
||||
public final void removeTrigger(final Trigger t) {
|
||||
currentState.removeTrigger(t);
|
||||
}
|
||||
@Deprecated
|
||||
public final void removeTrigger(final Trigger t, final CardStateName state) {
|
||||
getState(state).removeTrigger(t);
|
||||
}
|
||||
@@ -1050,6 +1039,25 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
}
|
||||
|
||||
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)) {
|
||||
list.addAll(kw.getTriggers());
|
||||
}
|
||||
@@ -2379,10 +2387,12 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public final void removeSpellAbility(final SpellAbility a) {
|
||||
removeSpellAbility(a, true);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public final void removeSpellAbility(final SpellAbility a, final boolean updateView) {
|
||||
if (currentState.removeSpellAbility(a) && updateView) {
|
||||
currentState.getView().updateAbilityText(this, currentState);
|
||||
@@ -2408,15 +2418,44 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
}
|
||||
|
||||
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
|
||||
if (mana == null || mana == true) {
|
||||
if (null == mana || true == mana) {
|
||||
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
|
||||
// need CardStateView#getState or might crash in StackOverflow
|
||||
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()) {
|
||||
if (sa.isManifestUp() || sa.isMorphUp()) {
|
||||
list.add(sa);
|
||||
@@ -2729,14 +2768,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.
|
||||
* 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.
|
||||
* 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.
|
||||
* 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
|
||||
* 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
|
||||
*
|
||||
* 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,
|
||||
* 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
|
||||
* 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
|
||||
* 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 (controller != null) {
|
||||
@@ -3589,6 +3628,31 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
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...
|
||||
public final List<KeywordInterface> getKeywords() {
|
||||
return getKeywords(currentState);
|
||||
@@ -4018,11 +4082,31 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
currentState.addStaticAbility(stAb);
|
||||
return stAb;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public final void removeStaticAbility(StaticAbility stAb) {
|
||||
currentState.removeStaticAbility(stAb);
|
||||
}
|
||||
|
||||
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)) {
|
||||
list.addAll(kw.getStaticAbilities());
|
||||
}
|
||||
@@ -5641,24 +5725,35 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
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) {
|
||||
currentState.addReplacementEffect(replacementEffect);
|
||||
return replacementEffect;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void removeReplacementEffect(ReplacementEffect replacementEffect) {
|
||||
currentState.removeReplacementEffect(replacementEffect);
|
||||
}
|
||||
|
||||
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)) {
|
||||
list.addAll(kw.getReplacements());
|
||||
}
|
||||
@@ -6296,27 +6391,6 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
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) {
|
||||
if (!isInZone(ZoneType.Hand)) {
|
||||
return false;
|
||||
|
||||
@@ -3758,7 +3758,6 @@ public class CardFactoryUtil {
|
||||
newSA.setDescription(sa.getDescription() + " (by paying " + cost.toSimpleString() + " instead of its mana cost)");
|
||||
newSA.setIntrinsic(intrinsic);
|
||||
|
||||
newSA.setTemporary(intrinsic);
|
||||
inst.addSpellAbility(newSA);
|
||||
|
||||
}
|
||||
@@ -3788,8 +3787,6 @@ public class CardFactoryUtil {
|
||||
|
||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
} else if (keyword.equals("Aftermath") && card.getCurrentStateName().equals(CardStateName.RightSplit)) {
|
||||
// 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);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
} else if (keyword.startsWith("Awaken")) {
|
||||
final String[] k = keyword.split(":");
|
||||
@@ -3835,8 +3830,6 @@ public class CardFactoryUtil {
|
||||
awakenSpell.setBasicSpell(false);
|
||||
awakenSpell.setPayCosts(awakenCost);
|
||||
awakenSpell.setIntrinsic(intrinsic);
|
||||
|
||||
awakenSpell.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(awakenSpell);
|
||||
} else if (keyword.startsWith("Bestow")) {
|
||||
final String[] params = keyword.split(":");
|
||||
@@ -3854,8 +3847,6 @@ public class CardFactoryUtil {
|
||||
sa.setStackDescription("Bestow - " + card.getName());
|
||||
sa.setBasicSpell(false);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
} else if (keyword.startsWith("Dash")) {
|
||||
final String[] k = keyword.split(":");
|
||||
@@ -3865,8 +3856,6 @@ public class CardFactoryUtil {
|
||||
|
||||
final SpellAbility newSA = AbilityFactory.getAbility(dashString, card);
|
||||
newSA.setIntrinsic(intrinsic);
|
||||
|
||||
newSA.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(newSA);
|
||||
} else if (keyword.startsWith("Emerge")) {
|
||||
final String[] kw = keyword.split(":");
|
||||
@@ -3882,8 +3871,6 @@ public class CardFactoryUtil {
|
||||
newSA.setPayCosts(new Cost(costStr, false));
|
||||
newSA.setDescription(sa.getDescription() + " (Emerge)");
|
||||
newSA.setIntrinsic(intrinsic);
|
||||
|
||||
newSA.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(newSA);
|
||||
} else if (keyword.startsWith("Embalm")) {
|
||||
final String[] kw = keyword.split(":");
|
||||
@@ -3896,8 +3883,6 @@ public class CardFactoryUtil {
|
||||
"| SpellDescription$ (" + inst.getReminderText() + ")" ;
|
||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
} else if (keyword.equals("Epic")) {
|
||||
// Epic does modify existing SA, and does not add new one
|
||||
@@ -3952,7 +3937,6 @@ public class CardFactoryUtil {
|
||||
// instantiate attach ability
|
||||
final SpellAbility newSA = AbilityFactory.getAbility(abilityStr.toString(), card);
|
||||
newSA.setIntrinsic(intrinsic);
|
||||
newSA.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(newSA);
|
||||
} else if (keyword.startsWith("Eternalize")) {
|
||||
final String[] kw = keyword.split(":");
|
||||
@@ -3982,8 +3966,6 @@ public class CardFactoryUtil {
|
||||
.append("| SpellDescription$ (").append(inst.getReminderText()).append(")");
|
||||
final SpellAbility sa = AbilityFactory.getAbility(sb.toString(), card);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
} else if (keyword.startsWith("Evoke")) {
|
||||
final String[] k = keyword.split(":");
|
||||
@@ -4005,8 +3987,6 @@ public class CardFactoryUtil {
|
||||
newSA.setBasicSpell(false);
|
||||
newSA.setEvoke(true);
|
||||
newSA.setIntrinsic(intrinsic);
|
||||
|
||||
newSA.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(newSA);
|
||||
} else if (keyword.startsWith("Fortify")) {
|
||||
String[] k = keyword.split(":");
|
||||
@@ -4027,14 +4007,10 @@ public class CardFactoryUtil {
|
||||
|
||||
// instantiate attach ability
|
||||
final SpellAbility sa = AbilityFactory.getAbility(abilityStr.toString(), card);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
} else if (keyword.startsWith("Fuse") && card.getCurrentStateName().equals(CardStateName.Original)) {
|
||||
final SpellAbility sa = AbilityFactory.buildFusedAbility(card);
|
||||
card.addSpellAbility(sa);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
} else if (keyword.startsWith("Haunt")) {
|
||||
if (!card.isCreature() && intrinsic) {
|
||||
@@ -4067,8 +4043,6 @@ public class CardFactoryUtil {
|
||||
|
||||
final SpellAbility sa = AbilityFactory.getAbility(sb.toString(), card);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
} else if (keyword.startsWith("Monstrosity")) {
|
||||
final String[] k = keyword.split(":");
|
||||
@@ -4103,8 +4077,6 @@ public class CardFactoryUtil {
|
||||
|
||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
|
||||
} else if (keyword.startsWith("Morph")) {
|
||||
@@ -4146,8 +4118,6 @@ public class CardFactoryUtil {
|
||||
|
||||
SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
|
||||
// extra secondary effect for Commander Ninjutsu
|
||||
@@ -4161,8 +4131,6 @@ public class CardFactoryUtil {
|
||||
|
||||
sa = AbilityFactory.getAbility(effect, card);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
}
|
||||
} else if (keyword.startsWith("Outlast")) {
|
||||
@@ -4187,8 +4155,6 @@ public class CardFactoryUtil {
|
||||
|
||||
final SpellAbility sa = AbilityFactory.getAbility(abilityStr.toString(), card);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
|
||||
} else if (keyword.startsWith("Prowl")) {
|
||||
@@ -4212,7 +4178,6 @@ public class CardFactoryUtil {
|
||||
newSA.setProwl(true);
|
||||
|
||||
newSA.setIntrinsic(intrinsic);
|
||||
newSA.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(newSA);
|
||||
} else if (keyword.startsWith("Reinforce")) {
|
||||
final String[] k = keyword.split(":");
|
||||
@@ -4234,8 +4199,6 @@ public class CardFactoryUtil {
|
||||
if (n.equals("X")) {
|
||||
sa.setSVar("X", "Count$xPaid");
|
||||
}
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
} else if (keyword.startsWith("Scavenge")) {
|
||||
final String[] k = keyword.split(":");
|
||||
@@ -4250,8 +4213,6 @@ public class CardFactoryUtil {
|
||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||
sa.setSVar("ScavengeX", "Count$CardPower");
|
||||
sa.setIntrinsic(intrinsic);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
|
||||
} else if (keyword.startsWith("Spectacle")) {
|
||||
@@ -4267,8 +4228,6 @@ public class CardFactoryUtil {
|
||||
newSA.setDescription(desc);
|
||||
|
||||
newSA.setIntrinsic(intrinsic);
|
||||
|
||||
newSA.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(newSA);
|
||||
|
||||
} else if (keyword.startsWith("Surge")) {
|
||||
@@ -4284,8 +4243,6 @@ public class CardFactoryUtil {
|
||||
newSA.setDescription(desc);
|
||||
|
||||
newSA.setIntrinsic(intrinsic);
|
||||
|
||||
newSA.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(newSA);
|
||||
|
||||
} else if (keyword.startsWith("Suspend") && !keyword.equals("Suspend")) {
|
||||
@@ -4336,8 +4293,6 @@ public class CardFactoryUtil {
|
||||
suspend.setStackDescription(sbStack.toString());
|
||||
|
||||
suspend.getRestrictions().setZone(ZoneType.Hand);
|
||||
|
||||
suspend.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(suspend);
|
||||
} else if (keyword.startsWith("Transfigure")) {
|
||||
final String[] k = keyword.split(":");
|
||||
@@ -4351,8 +4306,6 @@ public class CardFactoryUtil {
|
||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||
sa.setSVar("TransfigureX", "Count$CardManaCost");
|
||||
sa.setIntrinsic(intrinsic);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
} else if (keyword.startsWith("Transmute")) {
|
||||
final String[] k = keyword.split(":");
|
||||
@@ -4367,8 +4320,6 @@ public class CardFactoryUtil {
|
||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||
sa.setSVar("TransmuteX", "Count$CardManaCost");
|
||||
sa.setIntrinsic(intrinsic);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
} else if (keyword.startsWith("Unearth")) {
|
||||
final String[] k = keyword.split(":");
|
||||
@@ -4383,8 +4334,6 @@ public class CardFactoryUtil {
|
||||
|
||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
|
||||
} else if (keyword.endsWith(" offering")) {
|
||||
@@ -4403,8 +4352,6 @@ public class CardFactoryUtil {
|
||||
newSA.setPayCosts(sa.getPayCosts());
|
||||
newSA.setDescription(sa.getDescription() + " (" + offeringType + " offering)");
|
||||
newSA.setIntrinsic(intrinsic);
|
||||
|
||||
newSA.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(newSA);
|
||||
|
||||
} else if (keyword.startsWith("Crew")) {
|
||||
@@ -4420,8 +4367,6 @@ public class CardFactoryUtil {
|
||||
|
||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
|
||||
} else if (keyword.startsWith("Cycling")) {
|
||||
@@ -4440,8 +4385,6 @@ public class CardFactoryUtil {
|
||||
SpellAbility sa = AbilityFactory.getAbility(sb.toString(), card);
|
||||
sa.setIsCycling(true);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
|
||||
} else if (keyword.startsWith("TypeCycling")) {
|
||||
@@ -4466,8 +4409,6 @@ public class CardFactoryUtil {
|
||||
SpellAbility sa = AbilityFactory.getAbility(sb.toString(), card);
|
||||
sa.setIsCycling(true);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
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.ApiType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.replacement.ReplacementEffect;
|
||||
import forge.game.spellability.*;
|
||||
import forge.game.trigger.Trigger;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.TextUtil;
|
||||
import forge.util.collect.FCollection;
|
||||
@@ -240,23 +238,6 @@ public final class CardUtil {
|
||||
newCopy.setType(new CardType(in.getType()));
|
||||
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
|
||||
newCopy.setBasePower(in.getCurrentPower() + in.getTempPowerBoost());
|
||||
newCopy.setBaseToughness(in.getCurrentToughness() + in.getTempToughnessBoost());
|
||||
@@ -293,6 +274,7 @@ public final class CardUtil {
|
||||
newCopy.setChangedCardKeywords(in.getChangedCardKeywords());
|
||||
newCopy.setChangedCardTypes(in.getChangedCardTypesMap());
|
||||
newCopy.setChangedCardNames(in.getChangedCardNames());
|
||||
newCopy.setChangedCardTraits(in.getChangedCardTraits());
|
||||
|
||||
newCopy.copyChangedTextFrom(in);
|
||||
|
||||
|
||||
@@ -1178,7 +1178,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
com.remove(eff);
|
||||
eff.setStaticAbilities(Lists.newArrayList());
|
||||
}
|
||||
this.updateZoneForView(com);
|
||||
this.updateZoneForView(com);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -193,7 +193,6 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
|
||||
|
||||
res.setActiveZone(validHostZones);
|
||||
res.setLayer(getLayer());
|
||||
res.setTemporary(isTemporary());
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -356,31 +356,4 @@ public class ReplacementHandler {
|
||||
|
||||
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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
return new Predicate<SpellAbility>() {
|
||||
|
||||
@@ -159,14 +159,14 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
|
||||
}
|
||||
|
||||
if (hasParam("RemoveAllAbilities") || hasParam("GainsAbilitiesOf")) {
|
||||
layers.add(StaticAbilityLayer.ABILITIES1);
|
||||
layers.add(StaticAbilityLayer.ABILITIES);
|
||||
}
|
||||
|
||||
if (hasParam("AddKeyword") || hasParam("AddAbility")
|
||||
|| hasParam("AddTrigger") || hasParam("RemoveTriggers")
|
||||
|| hasParam("RemoveKeyword") || hasParam("AddReplacementEffects")
|
||||
|| hasParam("AddStaticAbility") || hasParam("AddSVar")) {
|
||||
layers.add(StaticAbilityLayer.ABILITIES2);
|
||||
layers.add(StaticAbilityLayer.ABILITIES);
|
||||
}
|
||||
|
||||
if (hasParam("CharacteristicDefining")) {
|
||||
@@ -183,7 +183,7 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
|
||||
if (hasParam("AddHiddenKeyword")) {
|
||||
// special rule for 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);
|
||||
}
|
||||
@@ -259,14 +259,14 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
|
||||
}
|
||||
|
||||
public final CardCollectionView applyContinuousAbilityBefore(final StaticAbilityLayer layer, final CardCollectionView preList) {
|
||||
if (!shouldApplyContinuousAbility(layer, false)) {
|
||||
if (!shouldApplyContinuousAbility(layer)) {
|
||||
return null;
|
||||
}
|
||||
return StaticAbilityContinuous.applyContinuousAbility(this, layer, preList);
|
||||
}
|
||||
|
||||
public final CardCollectionView applyContinuousAbility(final StaticAbilityLayer layer, final CardCollectionView affected) {
|
||||
if (!shouldApplyContinuousAbility(layer, true)) {
|
||||
if (!shouldApplyContinuousAbility(layer)) {
|
||||
return null;
|
||||
}
|
||||
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
|
||||
* conditions are fulfilled.
|
||||
*/
|
||||
private boolean shouldApplyContinuousAbility(final StaticAbilityLayer layer, final boolean ignoreTempSuppression) {
|
||||
final boolean isSuppressed;
|
||||
if (ignoreTempSuppression) {
|
||||
isSuppressed = this.isNonTempSuppressed();
|
||||
} else {
|
||||
isSuppressed = this.isSuppressed();
|
||||
}
|
||||
return getParam("Mode").equals("Continuous") && layers.contains(layer) && !isSuppressed && this.checkConditions();
|
||||
private boolean shouldApplyContinuousAbility(final StaticAbilityLayer layer) {
|
||||
return getParam("Mode").equals("Continuous") && layers.contains(layer) && !isSuppressed() && this.checkConditions();
|
||||
}
|
||||
|
||||
// apply the ability if it has the right mode
|
||||
|
||||
@@ -122,7 +122,6 @@ public final class StaticAbilityContinuous {
|
||||
String addColors = null;
|
||||
String[] addTriggers = null;
|
||||
String[] addStatics = null;
|
||||
List<SpellAbility> addFullAbs = null;
|
||||
boolean removeAllAbilities = false;
|
||||
boolean removeIntrinsicAbilities = false;
|
||||
boolean removeNonMana = false;
|
||||
@@ -187,7 +186,7 @@ public final class StaticAbilityContinuous {
|
||||
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(" & ");
|
||||
final Iterable<String> chosencolors = hostCard.getChosenColors();
|
||||
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
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (layer == StaticAbilityLayer.ABILITIES2 && params.containsKey("RemoveKeyword")) {
|
||||
if (layer == StaticAbilityLayer.ABILITIES && params.containsKey("RemoveKeyword")) {
|
||||
removeKeywords = params.get("RemoveKeyword").split(" & ");
|
||||
}
|
||||
|
||||
if (layer == StaticAbilityLayer.ABILITIES1 && params.containsKey("RemoveAllAbilities")) {
|
||||
if (layer == StaticAbilityLayer.ABILITIES && params.containsKey("RemoveAllAbilities")) {
|
||||
removeAllAbilities = true;
|
||||
if (params.containsKey("ExceptManaAbilities")) {
|
||||
removeNonMana = true;
|
||||
}
|
||||
}
|
||||
// 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")) {
|
||||
removeIntrinsicAbilities = true;
|
||||
}
|
||||
|
||||
if (layer == StaticAbilityLayer.ABILITIES2 && params.containsKey("AddAbility")) {
|
||||
if (layer == StaticAbilityLayer.ABILITIES && params.containsKey("AddAbility")) {
|
||||
final String[] sVars = params.get("AddAbility").split(" & ");
|
||||
for (int i = 0; i < sVars.length; i++) {
|
||||
sVars[i] = hostCard.getSVar(sVars[i]);
|
||||
@@ -254,7 +253,7 @@ public final class StaticAbilityContinuous {
|
||||
addAbilities = sVars;
|
||||
}
|
||||
|
||||
if (layer == StaticAbilityLayer.ABILITIES2 && params.containsKey("AddReplacementEffects")) {
|
||||
if (layer == StaticAbilityLayer.ABILITIES && params.containsKey("AddReplacementEffects")) {
|
||||
final String[] sVars = params.get("AddReplacementEffects").split(" & ");
|
||||
for (int i = 0; i < sVars.length; i++) {
|
||||
sVars[i] = hostCard.getSVar(sVars[i]);
|
||||
@@ -262,7 +261,7 @@ public final class StaticAbilityContinuous {
|
||||
addReplacements = sVars;
|
||||
}
|
||||
|
||||
if (layer == StaticAbilityLayer.ABILITIES2 && params.containsKey("AddSVar")) {
|
||||
if (layer == StaticAbilityLayer.ABILITIES && params.containsKey("AddSVar")) {
|
||||
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")) {
|
||||
final String[] sVars = params.get("AddTrigger").split(" & ");
|
||||
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) {
|
||||
// These fall under Rule changes, as they don't fit any other category
|
||||
if (params.containsKey("MayLookAt")) {
|
||||
@@ -444,7 +404,6 @@ public final class StaticAbilityContinuous {
|
||||
if (addStatics != null) {
|
||||
for (String s : addStatics) {
|
||||
StaticAbility stat = p.addStaticAbility(hostCard, s);
|
||||
stat.setTemporary(true);
|
||||
stat.setIntrinsic(false);
|
||||
}
|
||||
}
|
||||
@@ -582,38 +541,117 @@ public final class StaticAbilityContinuous {
|
||||
}
|
||||
}
|
||||
|
||||
if (addFullAbs != null) {
|
||||
for (final SpellAbility ab : addFullAbs) {
|
||||
affectedCard.addSpellAbility(ab, false);
|
||||
if (layer == StaticAbilityLayer.ABILITIES) {
|
||||
|
||||
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 (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.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);
|
||||
}
|
||||
if (layer == StaticAbilityLayer.TYPE && removeIntrinsicAbilities) {
|
||||
affectedCard.addChangedCardTraits(null, null, null, null, null, false, false, removeIntrinsicAbilities, hostCard.getTimestamp());
|
||||
}
|
||||
|
||||
// add Types
|
||||
@@ -628,81 +666,6 @@ public final class StaticAbilityContinuous {
|
||||
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 (params.containsKey("Goad")) {
|
||||
affectedCard.addGoad(se.getTimestamp(), hostCard.getController());
|
||||
@@ -765,11 +728,11 @@ public final class StaticAbilityContinuous {
|
||||
}
|
||||
|
||||
};
|
||||
addIgnore.setTemporary(true);
|
||||
|
||||
addIgnore.setIntrinsic(false);
|
||||
addIgnore.setApi(ApiType.InternalIgnoreEffect);
|
||||
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() {
|
||||
private static final long serialVersionUID = -5415775215053216360L;
|
||||
|
||||
@@ -18,11 +18,8 @@ public enum StaticAbilityLayer {
|
||||
/** Layer 5 for color-changing effects. */
|
||||
COLOR,
|
||||
|
||||
/** Layer 6 for ability-removing and -copying effects. */
|
||||
ABILITIES1,
|
||||
|
||||
/** Layer 6 for ability-granting effects. */
|
||||
ABILITIES2,
|
||||
/** Layer 6 for ability effects. */
|
||||
ABILITIES,
|
||||
|
||||
/** Layer 7a for characteristic-defining power/toughness effects. */
|
||||
CHARACTERISTIC,
|
||||
@@ -37,5 +34,5 @@ public enum StaticAbilityLayer {
|
||||
RULES;
|
||||
|
||||
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.setActiveZone(validHostZones);
|
||||
copy.setTemporary(isTemporary());
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,42 +67,6 @@ public class TriggerHandler {
|
||||
}
|
||||
|
||||
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() {
|
||||
@@ -699,9 +663,6 @@ public class TriggerHandler {
|
||||
Player p = regtrig.getHostCard().getController();
|
||||
p.getZone(ZoneType.Command).remove(regtrig.getHostCard());
|
||||
}
|
||||
else {
|
||||
regtrig.getHostCard().removeTrigger(regtrig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user