mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
Merge branch 'bloodyCardTraits' into 'master'
CardTaits: make cardtraits inside LKI has the same id's as the in the original See merge request core-developers/forge!197
This commit is contained in:
@@ -2466,7 +2466,7 @@ public class ComputerUtilCombat {
|
|||||||
for (SpellAbility sa : original.getSpellAbilities()) {
|
for (SpellAbility sa : original.getSpellAbilities()) {
|
||||||
if (sa.getApi() == ApiType.SetState && ComputerUtilCost.canPayCost(sa, original.getController())) {
|
if (sa.getApi() == ApiType.SetState && ComputerUtilCost.canPayCost(sa, original.getController())) {
|
||||||
Card transformed = CardUtil.getLKICopy(original);
|
Card transformed = CardUtil.getLKICopy(original);
|
||||||
transformed.getCurrentState().copyFrom(original, original.getAlternateState());
|
transformed.getCurrentState().copyFrom(original.getAlternateState(), true);
|
||||||
transformed.updateStateForView();
|
transformed.updateStateForView();
|
||||||
return transformed;
|
return transformed;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,9 +88,9 @@ public class ChooseCardNameAi extends SpellAbilityAi {
|
|||||||
Card copy = CardUtil.getLKICopy(card);
|
Card copy = CardUtil.getLKICopy(card);
|
||||||
// for calcing i need only one split side
|
// for calcing i need only one split side
|
||||||
if (isOther) {
|
if (isOther) {
|
||||||
copy.getCurrentState().copyFrom(card, card.getState(CardStateName.RightSplit));
|
copy.getCurrentState().copyFrom(card.getState(CardStateName.RightSplit), true);
|
||||||
} else {
|
} else {
|
||||||
copy.getCurrentState().copyFrom(card, card.getState(CardStateName.LeftSplit));
|
copy.getCurrentState().copyFrom(card.getState(CardStateName.LeftSplit), true);
|
||||||
}
|
}
|
||||||
copy.updateStateForView();
|
copy.updateStateForView();
|
||||||
|
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ public class SetStateAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
// need a copy for evaluation
|
// need a copy for evaluation
|
||||||
Card transformed = CardUtil.getLKICopy(card);
|
Card transformed = CardUtil.getLKICopy(card);
|
||||||
transformed.getCurrentState().copyFrom(card, card.getAlternateState());
|
transformed.getCurrentState().copyFrom(card.getAlternateState(), true);
|
||||||
transformed.updateStateForView();
|
transformed.updateStateForView();
|
||||||
|
|
||||||
// TODO: compareCards assumes that a creature will transform into a creature. Need to improve this
|
// TODO: compareCards assumes that a creature will transform into a creature. Need to improve this
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import forge.game.phase.PhaseHandler;
|
|||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.player.RegisteredPlayer;
|
import forge.game.player.RegisteredPlayer;
|
||||||
import forge.game.spellability.AbilityActivated;
|
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.spellability.SpellAbilityRestriction;
|
import forge.game.spellability.SpellAbilityRestriction;
|
||||||
import forge.game.spellability.SpellAbilityStackInstance;
|
import forge.game.spellability.SpellAbilityStackInstance;
|
||||||
@@ -263,15 +262,8 @@ public class GameCopier {
|
|||||||
newCard.addStaticAbility(stAb);
|
newCard.addStaticAbility(stAb);
|
||||||
}
|
}
|
||||||
for (SpellAbility sa : c.getSpellAbilities()) {
|
for (SpellAbility sa : c.getSpellAbilities()) {
|
||||||
SpellAbility saCopy;
|
SpellAbility saCopy = sa.copy(newCard, true);
|
||||||
|
|
||||||
if (sa instanceof AbilityActivated) {
|
|
||||||
saCopy = ((AbilityActivated)sa).getCopy();
|
|
||||||
} else {
|
|
||||||
saCopy = sa.copy();
|
|
||||||
}
|
|
||||||
if (saCopy != null) {
|
if (saCopy != null) {
|
||||||
saCopy.setHostCard(newCard);
|
|
||||||
newCard.addSpellAbility(saCopy);
|
newCard.addSpellAbility(saCopy);
|
||||||
} else {
|
} else {
|
||||||
System.err.println(sa.toString());
|
System.err.println(sa.toString());
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ public final class GameActionUtil {
|
|||||||
alternatives.add(newSA);
|
alternatives.add(newSA);
|
||||||
}
|
}
|
||||||
if (sa.hasParam("Equip") && sa instanceof AbilityActivated && keyword.equals("EquipInstantSpeed")) {
|
if (sa.hasParam("Equip") && sa instanceof AbilityActivated && keyword.equals("EquipInstantSpeed")) {
|
||||||
final SpellAbility newSA = ((AbilityActivated) sa).getCopy();
|
final SpellAbility newSA = sa.copy();
|
||||||
SpellAbilityRestriction sar = newSA.getRestrictions();
|
SpellAbilityRestriction sar = newSA.getRestrictions();
|
||||||
sar.setSorcerySpeed(false);
|
sar.setSorcerySpeed(false);
|
||||||
sar.setInstantSpeed(true);
|
sar.setInstantSpeed(true);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import forge.game.zone.ZoneType;
|
|||||||
/**
|
/**
|
||||||
* Created by Hellfish on 2014-02-09.
|
* Created by Hellfish on 2014-02-09.
|
||||||
*/
|
*/
|
||||||
public abstract class TriggerReplacementBase extends CardTraitBase {
|
public abstract class TriggerReplacementBase extends CardTraitBase implements IIdentifiable, Cloneable {
|
||||||
protected EnumSet<ZoneType> validHostZones;
|
protected EnumSet<ZoneType> validHostZones;
|
||||||
|
|
||||||
/** The overriding ability. */
|
/** The overriding ability. */
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import forge.game.ability.effects.ChangeZoneEffect;
|
|||||||
import forge.game.ability.effects.ManaEffect;
|
import forge.game.ability.effects.ManaEffect;
|
||||||
import forge.game.ability.effects.ManaReflectedEffect;
|
import forge.game.ability.effects.ManaReflectedEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardFactory;
|
|
||||||
import forge.game.cost.Cost;
|
import forge.game.cost.Cost;
|
||||||
import forge.game.spellability.AbilityActivated;
|
import forge.game.spellability.AbilityActivated;
|
||||||
import forge.game.spellability.AbilityManaPart;
|
import forge.game.spellability.AbilityManaPart;
|
||||||
@@ -41,17 +40,6 @@ public class AbilityApiBased extends AbilityActivated {
|
|||||||
return effect.getStackDescriptionWithSubs(mapParams, this);
|
return effect.getStackDescriptionWithSubs(mapParams, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see forge.card.spellability.AbilityActivated#getCopy()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public AbilityActivated getCopy() {
|
|
||||||
TargetRestrictions tgt = getTargetRestrictions() == null ? null : new TargetRestrictions(getTargetRestrictions());
|
|
||||||
AbilityActivated res = new AbilityApiBased(api, getHostCard(), getPayCosts(), tgt, mapParams);
|
|
||||||
CardFactory.copySpellAbility(this, res, getHostCard());
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see forge.card.spellability.SpellAbility#resolve()
|
* @see forge.card.spellability.SpellAbility#resolve()
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ public class CharmEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
for (AbilitySub sub : chosen) {
|
for (AbilitySub sub : chosen) {
|
||||||
// Clone the chosen, just in case the some subAb gets chosen multiple times
|
// Clone the chosen, just in case the some subAb gets chosen multiple times
|
||||||
AbilitySub clone = (AbilitySub)sub.getCopy();
|
AbilitySub clone = (AbilitySub)sub.copy();
|
||||||
|
|
||||||
// update ActivatingPlayer
|
// update ActivatingPlayer
|
||||||
clone.setActivatingPlayer(sa.getActivatingPlayer());
|
clone.setActivatingPlayer(sa.getActivatingPlayer());
|
||||||
|
|||||||
@@ -141,6 +141,10 @@ public class PumpEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see forge.game.ability.SpellAbilityEffect#getStackDescription(forge.game.spellability.SpellAbility)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected String getStackDescription(final SpellAbility sa) {
|
protected String getStackDescription(final SpellAbility sa) {
|
||||||
|
|
||||||
|
|||||||
@@ -822,17 +822,18 @@ 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) {
|
public final void setTriggers(final Iterable<Trigger> trigs, boolean intrinsicOnly) {
|
||||||
final FCollection<Trigger> copyList = new FCollection<>();
|
final FCollection<Trigger> copyList = new FCollection<>();
|
||||||
for (final Trigger t : trigs) {
|
for (final Trigger t : trigs) {
|
||||||
if (!intrinsicOnly || t.isIntrinsic()) {
|
if (!intrinsicOnly || t.isIntrinsic()) {
|
||||||
copyList.add(t.getCopyForHostCard(this));
|
copyList.add(t.copy(this, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentState.setTriggers(copyList);
|
currentState.setTriggers(copyList);
|
||||||
}
|
}
|
||||||
public final Trigger addTrigger(final Trigger t) {
|
public final Trigger addTrigger(final Trigger t) {
|
||||||
final Trigger newtrig = t.getCopyForHostCard(this);
|
final Trigger newtrig = t.copy(this, false);
|
||||||
currentState.addTrigger(newtrig);
|
currentState.addTrigger(newtrig);
|
||||||
return newtrig;
|
return newtrig;
|
||||||
}
|
}
|
||||||
@@ -5171,16 +5172,14 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
currentState.clearReplacementEffects();
|
currentState.clearReplacementEffects();
|
||||||
for (final ReplacementEffect replacementEffect : res) {
|
for (final ReplacementEffect replacementEffect : res) {
|
||||||
if (replacementEffect.isIntrinsic()) {
|
if (replacementEffect.isIntrinsic()) {
|
||||||
addReplacementEffect(replacementEffect);
|
addReplacementEffect(replacementEffect.copy(this, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReplacementEffect addReplacementEffect(final ReplacementEffect replacementEffect) {
|
public ReplacementEffect addReplacementEffect(final ReplacementEffect replacementEffect) {
|
||||||
final ReplacementEffect replacementEffectCopy = replacementEffect.getCopy(); // doubtful - every caller provides a newly parsed instance, why copy?
|
currentState.addReplacementEffect(replacementEffect);
|
||||||
replacementEffectCopy.setHostCard(this);
|
return replacementEffect;
|
||||||
currentState.addReplacementEffect(replacementEffectCopy);
|
|
||||||
return replacementEffectCopy;
|
|
||||||
}
|
}
|
||||||
public void removeReplacementEffect(ReplacementEffect replacementEffect) {
|
public void removeReplacementEffect(ReplacementEffect replacementEffect) {
|
||||||
currentState.removeReplacementEffect(replacementEffect);
|
currentState.removeReplacementEffect(replacementEffect);
|
||||||
@@ -5192,6 +5191,17 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasReplacementEffect(final ReplacementEffect re) {
|
||||||
|
return currentState.hasReplacementEffect(re);
|
||||||
|
}
|
||||||
|
public boolean hasReplacementEffect(final int id) {
|
||||||
|
return currentState.hasReplacementEffect(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReplacementEffect getReplacementEffect(final int id) {
|
||||||
|
return currentState.getReplacementEffect(id);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns what zone this card was cast from (from what zone it was moved to the stack).
|
* Returns what zone this card was cast from (from what zone it was moved to the stack).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -184,21 +184,10 @@ public class CardFactory {
|
|||||||
c.setCopiedSpell(true);
|
c.setCopiedSpell(true);
|
||||||
|
|
||||||
final SpellAbility copySA;
|
final SpellAbility copySA;
|
||||||
if (sa instanceof AbilityActivated) {
|
if (sa.isTrigger()) {
|
||||||
copySA = ((AbilityActivated)sa).getCopy();
|
|
||||||
copySA.setHostCard(original);
|
|
||||||
}
|
|
||||||
else if (sa.isTrigger()) {
|
|
||||||
copySA = getCopiedTriggeredAbility(sa);
|
copySA = getCopiedTriggeredAbility(sa);
|
||||||
}
|
} else {
|
||||||
else {
|
copySA = sa.copy(c, false);
|
||||||
copySA = sa.copy();
|
|
||||||
AbilitySub subSA = copySA.getSubAbility();
|
|
||||||
while (subSA != null) {
|
|
||||||
subSA.setCopied(true);
|
|
||||||
subSA = subSA.getSubAbility();
|
|
||||||
}
|
|
||||||
copySA.setHostCard(c);
|
|
||||||
}
|
}
|
||||||
c.getCurrentState().setNonManaAbilities(copySA);
|
c.getCurrentState().setNonManaAbilities(copySA);
|
||||||
copySA.setCopied(true);
|
copySA.setCopied(true);
|
||||||
@@ -577,27 +566,28 @@ public class CardFactory {
|
|||||||
to.addAlternateState(toState, updateView);
|
to.addAlternateState(toState, updateView);
|
||||||
}
|
}
|
||||||
final CardState toCharacteristics = to.getState(toState), fromCharacteristics = from.getState(fromState);
|
final CardState toCharacteristics = to.getState(toState), fromCharacteristics = from.getState(fromState);
|
||||||
toCharacteristics.copyFrom(from, fromCharacteristics);
|
toCharacteristics.copyFrom(fromCharacteristics, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void copySpellAbility(SpellAbility from, SpellAbility to, final Card host) {
|
public static void copySpellAbility(SpellAbility from, SpellAbility to, final Card host, final boolean lki) {
|
||||||
if (from.getActivatingPlayer() != null) {
|
|
||||||
to.setActivatingPlayer(from.getActivatingPlayer());
|
if (from.getTargetRestrictions() != null) {
|
||||||
|
to.setTargetRestrictions(from.getTargetRestrictions());
|
||||||
}
|
}
|
||||||
to.setDescription(from.getOriginalDescription());
|
to.setDescription(from.getOriginalDescription());
|
||||||
to.setStackDescription(from.getOriginalStackDescription());
|
to.setStackDescription(from.getOriginalStackDescription());
|
||||||
|
|
||||||
if (from.getSubAbility() != null) {
|
if (from.getSubAbility() != null) {
|
||||||
to.setSubAbility(from.getSubAbility().getCopy(host));
|
to.setSubAbility((AbilitySub) from.getSubAbility().copy(host, lki));
|
||||||
}
|
}
|
||||||
for (Map.Entry<String, AbilitySub> e : from.getAdditionalAbilities().entrySet()) {
|
for (Map.Entry<String, AbilitySub> e : from.getAdditionalAbilities().entrySet()) {
|
||||||
to.setAdditionalAbility(e.getKey(), e.getValue().getCopy(host));
|
to.setAdditionalAbility(e.getKey(), (AbilitySub) e.getValue().copy(host, lki));
|
||||||
}
|
}
|
||||||
for (Map.Entry<String, List<AbilitySub>> e : from.getAdditionalAbilityLists().entrySet()) {
|
for (Map.Entry<String, List<AbilitySub>> e : from.getAdditionalAbilityLists().entrySet()) {
|
||||||
to.setAdditionalAbilityList(e.getKey(), Lists.transform(e.getValue(), new Function<AbilitySub, AbilitySub>() {
|
to.setAdditionalAbilityList(e.getKey(), Lists.transform(e.getValue(), new Function<AbilitySub, AbilitySub>() {
|
||||||
@Override
|
@Override
|
||||||
public AbilitySub apply(AbilitySub input) {
|
public AbilitySub apply(AbilitySub input) {
|
||||||
return input.getCopy(host);
|
return (AbilitySub) input.copy(host, lki);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -608,6 +598,11 @@ public class CardFactory {
|
|||||||
to.setConditions((SpellAbilityCondition) from.getConditions().copy());
|
to.setConditions((SpellAbilityCondition) from.getConditions().copy());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// do this after other abilties are copied
|
||||||
|
if (from.getActivatingPlayer() != null) {
|
||||||
|
to.setActivatingPlayer(from.getActivatingPlayer(), lki);
|
||||||
|
}
|
||||||
|
|
||||||
for (String sVar : from.getSVars()) {
|
for (String sVar : from.getSVars()) {
|
||||||
to.setSVar(sVar, from.getSVar(sVar));
|
to.setSVar(sVar, from.getSVar(sVar));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,10 +170,10 @@ public class CardState extends GameObject {
|
|||||||
public final boolean hasIntrinsicKeyword(String k) {
|
public final boolean hasIntrinsicKeyword(String k) {
|
||||||
return intrinsicKeywords.contains(k);
|
return intrinsicKeywords.contains(k);
|
||||||
}
|
}
|
||||||
public final void setIntrinsicKeywords(final Iterable<KeywordInterface> intrinsicKeyword0) {
|
public final void setIntrinsicKeywords(final Iterable<KeywordInterface> intrinsicKeyword0, final boolean lki) {
|
||||||
intrinsicKeywords.clear();
|
intrinsicKeywords.clear();
|
||||||
for (KeywordInterface k : intrinsicKeyword0) {
|
for (KeywordInterface k : intrinsicKeyword0) {
|
||||||
intrinsicKeywords.insert(k.copy(card));
|
intrinsicKeywords.insert(k.copy(card, lki));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,6 +367,24 @@ public class CardState extends GameObject {
|
|||||||
return getReplacementEffects().contains(re);
|
return getReplacementEffects().contains(re);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final boolean hasReplacementEffect(final int id) {
|
||||||
|
for (final ReplacementEffect r : getReplacementEffects()) {
|
||||||
|
if (id == r.getId()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final ReplacementEffect getReplacementEffect(final int id) {
|
||||||
|
for (final ReplacementEffect r : getReplacementEffects()) {
|
||||||
|
if (id == r.getId()) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public final Map<String, String> getSVars() {
|
public final Map<String, String> getSVars() {
|
||||||
return sVars;
|
return sVars;
|
||||||
}
|
}
|
||||||
@@ -406,7 +424,7 @@ public class CardState extends GameObject {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void copyFrom(final Card c, final CardState source) {
|
public final void copyFrom(final CardState source, final boolean lki) {
|
||||||
// Makes a "deeper" copy of a CardState object
|
// Makes a "deeper" copy of a CardState object
|
||||||
setName(source.getName());
|
setName(source.getName());
|
||||||
setType(source.type);
|
setType(source.type);
|
||||||
@@ -419,36 +437,30 @@ public class CardState extends GameObject {
|
|||||||
manaAbilities.clear();
|
manaAbilities.clear();
|
||||||
for (SpellAbility sa : source.manaAbilities) {
|
for (SpellAbility sa : source.manaAbilities) {
|
||||||
if (sa.isIntrinsic()) {
|
if (sa.isIntrinsic()) {
|
||||||
SpellAbility saCopy = sa.copy();
|
manaAbilities.add(sa.copy(card, lki));
|
||||||
saCopy.setHostCard(card); // update HostCard
|
|
||||||
manaAbilities.add(saCopy);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nonManaAbilities.clear();
|
nonManaAbilities.clear();
|
||||||
for (SpellAbility sa : source.nonManaAbilities) {
|
for (SpellAbility sa : source.nonManaAbilities) {
|
||||||
if (sa.isIntrinsic()) {
|
if (sa.isIntrinsic()) {
|
||||||
SpellAbility saCopy = sa.copy();
|
nonManaAbilities.add(sa.copy(card, lki));
|
||||||
saCopy.setHostCard(card); // update HostCard
|
|
||||||
nonManaAbilities.add(saCopy);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setIntrinsicKeywords(source.intrinsicKeywords.getValues());
|
setIntrinsicKeywords(source.intrinsicKeywords.getValues(), lki);
|
||||||
setImageKey(source.getImageKey());
|
setImageKey(source.getImageKey());
|
||||||
setRarity(source.rarity);
|
setRarity(source.rarity);
|
||||||
setSetCode(source.setCode);
|
setSetCode(source.setCode);
|
||||||
|
|
||||||
triggers.clear();
|
triggers.clear();
|
||||||
for (Trigger tr : source.triggers) {
|
for (Trigger tr : source.triggers) {
|
||||||
triggers.add(tr.getCopyForHostCard(card));
|
triggers.add(tr.copy(card, lki));
|
||||||
}
|
}
|
||||||
|
|
||||||
replacementEffects.clear();
|
replacementEffects.clear();
|
||||||
for (ReplacementEffect re : source.replacementEffects) {
|
for (ReplacementEffect re : source.replacementEffects) {
|
||||||
ReplacementEffect reCopy = re.getCopy();
|
replacementEffects.add(re.copy(card, lki));
|
||||||
reCopy.setHostCard(card);
|
|
||||||
replacementEffects.add(reCopy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
staticAbilities.clear();
|
staticAbilities.clear();
|
||||||
@@ -456,7 +468,6 @@ public class CardState extends GameObject {
|
|||||||
StaticAbility saCopy = new StaticAbility(sa, this.card);
|
StaticAbility saCopy = new StaticAbility(sa, this.card);
|
||||||
staticAbilities.add(saCopy);
|
staticAbilities.add(saCopy);
|
||||||
}
|
}
|
||||||
view.updateKeywords(c, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -211,19 +211,18 @@ public final class CardUtil {
|
|||||||
// used for the purpose of cards that care about the zone the card was known to be in last
|
// used for the purpose of cards that care about the zone the card was known to be in last
|
||||||
newCopy.setLastKnownZone(in.getLastKnownZone());
|
newCopy.setLastKnownZone(in.getLastKnownZone());
|
||||||
|
|
||||||
newCopy.getCurrentState().copyFrom(in, in.getState(in.getCurrentStateName()));
|
newCopy.getCurrentState().copyFrom(in.getState(in.getCurrentStateName()), true);
|
||||||
|
|
||||||
if (in.isCloned()) {
|
if (in.isCloned()) {
|
||||||
newCopy.addAlternateState(CardStateName.Cloner, false);
|
newCopy.addAlternateState(CardStateName.Cloner, false);
|
||||||
newCopy.getState(CardStateName.Cloner).copyFrom(in, in.getState(CardStateName.Cloner));
|
newCopy.getState(CardStateName.Cloner).copyFrom(in.getState(CardStateName.Cloner), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
newCopy.setType(new CardType(in.getType()));
|
newCopy.setType(new CardType(in.getType()));
|
||||||
newCopy.setToken(in.isToken());
|
newCopy.setToken(in.isToken());
|
||||||
newCopy.setTriggers(in.getTriggers(), false);
|
newCopy.setTriggers(in.getTriggers(), false);
|
||||||
for (SpellAbility sa : in.getSpellAbilities()) {
|
for (SpellAbility sa : in.getSpellAbilities()) {
|
||||||
newCopy.addSpellAbility(sa);
|
newCopy.addSpellAbility(sa.copy(newCopy, true));
|
||||||
sa.setHostCard(in);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// lock in the current P/T without bonus from counters
|
// lock in the current P/T without bonus from counters
|
||||||
@@ -263,6 +262,11 @@ public final class CardUtil {
|
|||||||
|
|
||||||
newCopy.setMeldedWith(in.getMeldedWith());
|
newCopy.setMeldedWith(in.getMeldedWith());
|
||||||
|
|
||||||
|
// update keyword cache on all states
|
||||||
|
for (CardStateName s : newCopy.getStates()) {
|
||||||
|
newCopy.updateKeywordsCache(newCopy.getState(s));
|
||||||
|
}
|
||||||
|
|
||||||
return newCopy;
|
return newCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -167,6 +167,17 @@ public class KeywordCollection implements Iterable<String>, Serializable {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
sb.append(map.values());
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public KeywordCollectionView getView() {
|
public KeywordCollectionView getView() {
|
||||||
if (view == null) {
|
if (view == null) {
|
||||||
view = new KeywordCollectionView();
|
view = new KeywordCollectionView();
|
||||||
|
|||||||
@@ -180,26 +180,23 @@ public abstract class KeywordInstance<T extends KeywordInstance<?>> implements K
|
|||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see forge.game.keyword.KeywordInterface#copy()
|
* @see forge.game.keyword.KeywordInterface#copy()
|
||||||
*/
|
*/
|
||||||
public KeywordInterface copy(final Card host) {
|
public KeywordInterface copy(final Card host, final boolean lki) {
|
||||||
try {
|
try {
|
||||||
KeywordInstance<?> result = (KeywordInstance<?>) super.clone();
|
KeywordInstance<?> result = (KeywordInstance<?>) super.clone();
|
||||||
|
|
||||||
result.abilities = Lists.newArrayList();
|
result.abilities = Lists.newArrayList();
|
||||||
for (SpellAbility sa : this.abilities) {
|
for (SpellAbility sa : this.abilities) {
|
||||||
SpellAbility saCopy = sa.copy(host);
|
result.abilities.add(sa.copy(host, lki));
|
||||||
result.abilities.add(saCopy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result.triggers = Lists.newArrayList();
|
result.triggers = Lists.newArrayList();
|
||||||
for (Trigger tr : this.triggers) {
|
for (Trigger tr : this.triggers) {
|
||||||
result.triggers.add(tr.getCopyForHostCard(host));
|
result.triggers.add(tr.copy(host, lki));
|
||||||
}
|
}
|
||||||
|
|
||||||
result.replacements = Lists.newArrayList();
|
result.replacements = Lists.newArrayList();
|
||||||
for (ReplacementEffect re : this.replacements) {
|
for (ReplacementEffect re : this.replacements) {
|
||||||
ReplacementEffect reCopy = re.getCopy();
|
result.replacements.add(re.copy(host, lki));
|
||||||
reCopy.setHostCard(host);
|
|
||||||
result.replacements.add(reCopy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result.staticAbilities = Lists.newArrayList();
|
result.staticAbilities = Lists.newArrayList();
|
||||||
@@ -212,4 +209,12 @@ public abstract class KeywordInstance<T extends KeywordInstance<?>> implements K
|
|||||||
throw new RuntimeException("KeywordInstance : clone() error, " + ex);
|
throw new RuntimeException("KeywordInstance : clone() error, " + ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.getOriginal();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,5 +49,5 @@ public interface KeywordInterface extends Cloneable {
|
|||||||
*/
|
*/
|
||||||
public Collection<StaticAbility> getStaticAbilities();
|
public Collection<StaticAbility> getStaticAbilities();
|
||||||
|
|
||||||
public KeywordInterface copy(final Card host);
|
public KeywordInterface copy(final Card host, final boolean lki);
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,16 @@
|
|||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CardCollection;
|
||||||
|
import forge.game.card.CardUtil;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Write javadoc for this type.
|
* TODO: Write javadoc for this type.
|
||||||
*
|
*
|
||||||
@@ -60,8 +64,9 @@ public class ReplaceMoved extends ReplacementEffect {
|
|||||||
|
|
||||||
if (hasParam("Destination")) {
|
if (hasParam("Destination")) {
|
||||||
matchedZone = false;
|
matchedZone = false;
|
||||||
|
ZoneType zt = (ZoneType) runParams.get("Destination");
|
||||||
for(ZoneType z : ZoneType.listValueOf(getParam("Destination"))) {
|
for(ZoneType z : ZoneType.listValueOf(getParam("Destination"))) {
|
||||||
if(z == (ZoneType) runParams.get("Destination"))
|
if(z == zt)
|
||||||
matchedZone = true;
|
matchedZone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,6 +74,20 @@ public class ReplaceMoved extends ReplacementEffect {
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (zt.equals(ZoneType.Battlefield)) {
|
||||||
|
// would be an etb replacement effect that enters the battlefield
|
||||||
|
Card lki = CardUtil.getLKICopy((Card) runParams.get("Affected"));
|
||||||
|
lki.setLastKnownZone(lki.getController().getZone(zt));
|
||||||
|
|
||||||
|
CardCollection preList = new CardCollection(lki);
|
||||||
|
getHostCard().getGame().getAction().checkStaticAbilities(false, Sets.newHashSet(lki), preList);
|
||||||
|
|
||||||
|
// check if when entering the battlefield would still has this RE or is suppressed
|
||||||
|
if (!lki.hasReplacementEffect(this) || lki.getReplacementEffect(getId()).isSuppressed()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("ExcludeDestination")) {
|
if (hasParam("ExcludeDestination")) {
|
||||||
|
|||||||
@@ -19,11 +19,9 @@ package forge.game.replacement;
|
|||||||
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.TriggerReplacementBase;
|
import forge.game.TriggerReplacementBase;
|
||||||
import forge.game.ability.AbilityApiBased;
|
|
||||||
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;
|
||||||
import forge.game.spellability.AbilitySub;
|
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.util.TextUtil;
|
import forge.util.TextUtil;
|
||||||
|
|
||||||
@@ -35,12 +33,37 @@ import java.util.Map;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class ReplacementEffect extends TriggerReplacementBase {
|
public abstract class ReplacementEffect extends TriggerReplacementBase {
|
||||||
|
private static int maxId = 0;
|
||||||
|
private static int nextId() { return ++maxId; }
|
||||||
|
|
||||||
|
/** The ID. */
|
||||||
|
private int id;
|
||||||
|
|
||||||
private ReplacementLayer layer = ReplacementLayer.None;
|
private ReplacementLayer layer = ReplacementLayer.None;
|
||||||
|
|
||||||
/** The has run. */
|
/** The has run. */
|
||||||
private boolean hasRun = false;
|
private boolean hasRun = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the id.
|
||||||
|
*
|
||||||
|
* @return the id
|
||||||
|
*/
|
||||||
|
public int getId() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* setID.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* a int.
|
||||||
|
*/
|
||||||
|
public final void setId(final int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Checks for run.
|
* Checks for run.
|
||||||
*
|
*
|
||||||
@@ -59,6 +82,7 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
|
|||||||
* the host
|
* the host
|
||||||
*/
|
*/
|
||||||
public ReplacementEffect(final Map<String, String> map, final Card host, final boolean intrinsic) {
|
public ReplacementEffect(final Map<String, String> map, final Card host, final boolean intrinsic) {
|
||||||
|
this.id = nextId();
|
||||||
this.intrinsic = intrinsic;
|
this.intrinsic = intrinsic;
|
||||||
originalMapParams.putAll(map);
|
originalMapParams.putAll(map);
|
||||||
mapParams.putAll(map);
|
mapParams.putAll(map);
|
||||||
@@ -133,32 +157,27 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
|
|||||||
*
|
*
|
||||||
* @return the copy
|
* @return the copy
|
||||||
*/
|
*/
|
||||||
public final ReplacementEffect getCopy() {
|
public final ReplacementEffect copy(final Card host, final boolean lki) {
|
||||||
final ReplacementType rt = ReplacementType.getTypeFor(this);
|
final ReplacementEffect res = (ReplacementEffect) clone();
|
||||||
final ReplacementEffect res = rt.createReplacement(mapParams, hostCard, intrinsic);
|
|
||||||
final SpellAbility overridingAbility = this.getOverridingAbility();
|
|
||||||
if (overridingAbility != null) {
|
|
||||||
final SpellAbility overridingAbilityCopy;
|
|
||||||
if (overridingAbility instanceof AbilityApiBased) {
|
|
||||||
overridingAbilityCopy = ((AbilityApiBased) overridingAbility).getCopy();
|
|
||||||
} else if (overridingAbility instanceof AbilitySub) {
|
|
||||||
overridingAbilityCopy = ((AbilitySub) overridingAbility).getCopy();
|
|
||||||
} else {
|
|
||||||
System.err.println("Overriding ability of " + hostCard + " of unexpected type " + overridingAbility.getClass());
|
|
||||||
overridingAbilityCopy = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (overridingAbilityCopy != null) {
|
|
||||||
overridingAbilityCopy.setHostCard(hostCard);
|
|
||||||
res.setOverridingAbility(overridingAbilityCopy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
res.setActiveZone(validHostZones);
|
|
||||||
res.setLayer(getLayer());
|
|
||||||
res.setTemporary(isTemporary());
|
|
||||||
for (String key : getSVars()) {
|
for (String key : getSVars()) {
|
||||||
res.setSVar(key, getSVar(key));
|
res.setSVar(key, getSVar(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final SpellAbility sa = this.getOverridingAbility();
|
||||||
|
if (sa != null) {
|
||||||
|
final SpellAbility overridingAbilityCopy = sa.copy(host, lki);
|
||||||
|
if (overridingAbilityCopy != null) {
|
||||||
|
res.setOverridingAbility(overridingAbilityCopy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lki) {
|
||||||
|
res.setId(nextId());
|
||||||
|
}
|
||||||
|
|
||||||
|
res.setActiveZone(validHostZones);
|
||||||
|
res.setLayer(getLayer());
|
||||||
|
res.setTemporary(isTemporary());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,6 +225,29 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public final Object clone() {
|
||||||
|
try {
|
||||||
|
return super.clone();
|
||||||
|
} catch (final Exception ex) {
|
||||||
|
throw new RuntimeException("ReplacementEffect : clone() error, " + ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public final boolean equals(final Object o) {
|
||||||
|
if (!(o instanceof ReplacementEffect)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.getId() == ((ReplacementEffect) o).getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return 42 * (42 + this.getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,21 +61,12 @@ public class ReplacementHandler {
|
|||||||
decider = ((Card) affected).getController();
|
decider = ((Card) affected).getController();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReplacementResult res = run(runParams, ReplacementLayer.Control, decider);
|
// try out all layer
|
||||||
if (res != ReplacementResult.NotReplaced) {
|
for (ReplacementLayer layer : ReplacementLayer.values()) {
|
||||||
return res;
|
ReplacementResult res = run(runParams, layer, decider);
|
||||||
}
|
if (res != ReplacementResult.NotReplaced) {
|
||||||
res = run(runParams, ReplacementLayer.Copy, decider);
|
return res;
|
||||||
if (res != ReplacementResult.NotReplaced) {
|
}
|
||||||
return res;
|
|
||||||
}
|
|
||||||
res = run(runParams, ReplacementLayer.Other, decider);
|
|
||||||
if (res != ReplacementResult.NotReplaced) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
res = run(runParams, ReplacementLayer.None, decider);
|
|
||||||
if (res != ReplacementResult.NotReplaced) {
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReplacementResult.NotReplaced;
|
return ReplacementResult.NotReplaced;
|
||||||
|
|||||||
@@ -32,16 +32,6 @@ public enum ReplacementType {
|
|||||||
clasz = cls;
|
clasz = cls;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ReplacementType getTypeFor(ReplacementEffect e) {
|
|
||||||
final Class<? extends ReplacementEffect> cls = e.getClass();
|
|
||||||
for (final ReplacementType v : ReplacementType.values()) {
|
|
||||||
if (v.clasz.equals(cls)) {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ReplacementType smartValueOf(String value) {
|
public static ReplacementType smartValueOf(String value) {
|
||||||
final String valToCompate = value.trim();
|
final String valToCompate = value.trim();
|
||||||
for (final ReplacementType v : ReplacementType.values()) {
|
for (final ReplacementType v : ReplacementType.values()) {
|
||||||
|
|||||||
@@ -72,10 +72,6 @@ public abstract class AbilityActivated extends SpellAbility implements java.io.S
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract AbilityActivated getCopy(); /* {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public boolean canPlay() {
|
public boolean canPlay() {
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import forge.game.ability.effects.ChangeZoneEffect;
|
|||||||
import forge.game.ability.effects.ManaEffect;
|
import forge.game.ability.effects.ManaEffect;
|
||||||
import forge.game.ability.effects.ManaReflectedEffect;
|
import forge.game.ability.effects.ManaReflectedEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardFactory;
|
|
||||||
import forge.game.cost.Cost;
|
import forge.game.cost.Cost;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -102,16 +101,6 @@ public final class AbilitySub extends SpellAbility implements java.io.Serializab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbilitySub getCopy() {
|
|
||||||
return getCopy(getHostCard());
|
|
||||||
}
|
|
||||||
public AbilitySub getCopy(Card host) {
|
|
||||||
TargetRestrictions t = getTargetRestrictions() == null ? null : new TargetRestrictions(getTargetRestrictions());
|
|
||||||
AbilitySub res = new AbilitySub(api, host, t, mapParams);
|
|
||||||
CardFactory.copySpellAbility(this, res, host);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getStackDescription() {
|
public String getStackDescription() {
|
||||||
return effect.getStackDescriptionWithSubs(mapParams, this);
|
return effect.getStackDescriptionWithSubs(mapParams, this);
|
||||||
|
|||||||
@@ -313,24 +313,25 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
return activatingPlayer;
|
return activatingPlayer;
|
||||||
}
|
}
|
||||||
public void setActivatingPlayer(final Player player) {
|
public void setActivatingPlayer(final Player player) {
|
||||||
|
setActivatingPlayer(player, false);
|
||||||
|
}
|
||||||
|
public void setActivatingPlayer(final Player player, final boolean lki) {
|
||||||
// trickle down activating player
|
// trickle down activating player
|
||||||
activatingPlayer = player;
|
activatingPlayer = player;
|
||||||
if (subAbility != null) {
|
if (subAbility != null) {
|
||||||
subAbility.setActivatingPlayer(player);
|
subAbility.setActivatingPlayer(player, lki);
|
||||||
}
|
}
|
||||||
for (AbilitySub sa : additionalAbilities.values()) {
|
for (AbilitySub sa : additionalAbilities.values()) {
|
||||||
if (sa.getActivatingPlayer() != player) {
|
sa.setActivatingPlayer(player, lki);
|
||||||
sa.setActivatingPlayer(player);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (List<AbilitySub> list : additionalAbilityLists.values()) {
|
for (List<AbilitySub> list : additionalAbilityLists.values()) {
|
||||||
for (AbilitySub sa : list) {
|
for (AbilitySub sa : list) {
|
||||||
if (sa.getActivatingPlayer() != player) {
|
sa.setActivatingPlayer(player, lki);
|
||||||
sa.setActivatingPlayer(player);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
view.updateCanPlay(this, false);
|
if (!lki) {
|
||||||
|
view.updateCanPlay(this, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player getDeltrigActivatingPlayer() {
|
public Player getDeltrigActivatingPlayer() {
|
||||||
@@ -789,17 +790,18 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SpellAbility copy() {
|
public SpellAbility copy() {
|
||||||
return copy(hostCard);
|
return copy(hostCard, false);
|
||||||
}
|
}
|
||||||
public SpellAbility copy(Card host) {
|
public SpellAbility copy(Card host, final boolean lki) {
|
||||||
SpellAbility clone = null;
|
SpellAbility clone = null;
|
||||||
try {
|
try {
|
||||||
clone = (SpellAbility) clone();
|
clone = (SpellAbility) clone();
|
||||||
clone.id = nextId();
|
clone.id = lki ? id : nextId();
|
||||||
clone.view = new SpellAbilityView(clone);
|
clone.view = new SpellAbilityView(clone);
|
||||||
|
|
||||||
// dont use setHostCard to not trigger the not copied parts yet
|
// dont use setHostCard to not trigger the not copied parts yet
|
||||||
clone.hostCard = host;
|
clone.hostCard = host;
|
||||||
if (host != null && host.getGame() != null) {
|
if (!lki && host != null && host.getGame() != null) {
|
||||||
host.getGame().addSpellAbility(clone);
|
host.getGame().addSpellAbility(clone);
|
||||||
}
|
}
|
||||||
// need to clone the maps too so they can be changed
|
// need to clone the maps too so they can be changed
|
||||||
@@ -808,8 +810,11 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
|
|
||||||
clone.triggeringObjects = Maps.newHashMap(this.triggeringObjects);
|
clone.triggeringObjects = Maps.newHashMap(this.triggeringObjects);
|
||||||
|
|
||||||
|
if (getPayCosts() != null) {
|
||||||
|
clone.setPayCosts(getPayCosts().copy());
|
||||||
|
}
|
||||||
// run special copy Ability to make a deep copy
|
// run special copy Ability to make a deep copy
|
||||||
CardFactory.copySpellAbility(this, clone, host);
|
CardFactory.copySpellAbility(this, clone, host, lki);
|
||||||
} catch (final CloneNotSupportedException e) {
|
} catch (final CloneNotSupportedException e) {
|
||||||
System.err.println(e);
|
System.err.println(e);
|
||||||
}
|
}
|
||||||
@@ -1109,6 +1114,9 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
}
|
}
|
||||||
public void setCopied(boolean isCopied0) {
|
public void setCopied(boolean isCopied0) {
|
||||||
isCopied = isCopied0;
|
isCopied = isCopied0;
|
||||||
|
if (this.getSubAbility() != null) {
|
||||||
|
this.getSubAbility().setCopied(isCopied0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -369,12 +369,12 @@ public final class StaticAbilityContinuous {
|
|||||||
cardsIGainedAbilitiesFrom = CardLists.getValidCards(cardsIGainedAbilitiesFrom, valids, hostCard.getController(), hostCard, null);
|
cardsIGainedAbilitiesFrom = CardLists.getValidCards(cardsIGainedAbilitiesFrom, valids, hostCard.getController(), hostCard, null);
|
||||||
|
|
||||||
if (cardsIGainedAbilitiesFrom.size() > 0) {
|
if (cardsIGainedAbilitiesFrom.size() > 0) {
|
||||||
addFullAbs = new ArrayList<SpellAbility>();
|
addFullAbs = Lists.newArrayList();
|
||||||
|
|
||||||
for (Card c : cardsIGainedAbilitiesFrom) {
|
for (Card c : cardsIGainedAbilitiesFrom) {
|
||||||
for (SpellAbility sa : c.getSpellAbilities()) {
|
for (SpellAbility sa : c.getSpellAbilities()) {
|
||||||
if (sa instanceof AbilityActivated) {
|
if (sa instanceof AbilityActivated) {
|
||||||
SpellAbility newSA = ((AbilityActivated) sa).getCopy();
|
SpellAbility newSA = sa.copy(hostCard, false);
|
||||||
if (params.containsKey("GainsAbilitiesLimitPerTurn")) {
|
if (params.containsKey("GainsAbilitiesLimitPerTurn")) {
|
||||||
newSA.setRestrictions(sa.getRestrictions());
|
newSA.setRestrictions(sa.getRestrictions());
|
||||||
newSA.getRestrictions().setLimitToCheck(params.get("GainsAbilitiesLimitPerTurn"));
|
newSA.getRestrictions().setLimitToCheck(params.get("GainsAbilitiesLimitPerTurn"));
|
||||||
@@ -382,7 +382,6 @@ public final class StaticAbilityContinuous {
|
|||||||
newSA.setOriginalHost(c);
|
newSA.setOriginalHost(c);
|
||||||
newSA.setIntrinsic(false);
|
newSA.setIntrinsic(false);
|
||||||
newSA.setTemporary(true);
|
newSA.setTemporary(true);
|
||||||
newSA.setHostCard(hostCard);
|
|
||||||
addFullAbs.add(newSA);
|
addFullAbs.add(newSA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import forge.game.phase.PhaseHandler;
|
|||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.Ability;
|
import forge.game.spellability.Ability;
|
||||||
import forge.game.spellability.AbilitySub;
|
|
||||||
import forge.game.spellability.OptionalCost;
|
import forge.game.spellability.OptionalCost;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
@@ -49,9 +48,8 @@ import forge.util.TextUtil;
|
|||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public abstract class Trigger extends TriggerReplacementBase {
|
public abstract class Trigger extends TriggerReplacementBase {
|
||||||
|
private static int maxId = 0;
|
||||||
/** Constant <code>nextID=0</code>. */
|
private static int nextId() { return ++maxId; }
|
||||||
private static int nextID = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -59,23 +57,12 @@ public abstract class Trigger extends TriggerReplacementBase {
|
|||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public static void resetIDs() {
|
public static void resetIDs() {
|
||||||
Trigger.nextID = 50000;
|
Trigger.maxId = 50000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The ID. */
|
/** The ID. */
|
||||||
private int id = Trigger.nextID++;
|
private int id;
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* setID.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* a int.
|
|
||||||
*/
|
|
||||||
public final void setID(final int id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The run params. */
|
/** The run params. */
|
||||||
private Map<String, Object> runParams;
|
private Map<String, Object> runParams;
|
||||||
@@ -131,9 +118,10 @@ public abstract class Trigger extends TriggerReplacementBase {
|
|||||||
* the intrinsic
|
* the intrinsic
|
||||||
*/
|
*/
|
||||||
public Trigger(final Map<String, String> params, final Card host, final boolean intrinsic) {
|
public Trigger(final Map<String, String> params, final Card host, final boolean intrinsic) {
|
||||||
|
this.id = nextId();
|
||||||
this.intrinsic = intrinsic;
|
this.intrinsic = intrinsic;
|
||||||
|
|
||||||
this.setRunParams(new HashMap<String, Object>());
|
this.setRunParams(Maps.newHashMap());
|
||||||
this.originalMapParams.putAll(params);
|
this.originalMapParams.putAll(params);
|
||||||
this.mapParams.putAll(params);
|
this.mapParams.putAll(params);
|
||||||
this.setHostCard(host);
|
this.setHostCard(host);
|
||||||
@@ -469,6 +457,18 @@ public abstract class Trigger extends TriggerReplacementBase {
|
|||||||
return this.id;
|
return this.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* setID.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* a int.
|
||||||
|
*/
|
||||||
|
public final void setId(final int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
private Ability triggeredSA;
|
private Ability triggeredSA;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -516,32 +516,24 @@ public abstract class Trigger extends TriggerReplacementBase {
|
|||||||
mode = triggerType;
|
mode = triggerType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final Trigger copy(Card newHost, boolean lki) {
|
||||||
|
final Trigger copy = (Trigger) clone();
|
||||||
|
|
||||||
public final Trigger getCopyForHostCard(Card newHost) {
|
copy.originalMapParams.putAll(originalMapParams);
|
||||||
final TriggerType tt = TriggerType.getTypeFor(this);
|
copy.mapParams.putAll(originalMapParams);
|
||||||
final Trigger copy = tt.createTrigger(originalMapParams, newHost, intrinsic);
|
copy.setHostCard(newHost);
|
||||||
|
|
||||||
if (this.getOverridingAbility() != null) {
|
if (getOverridingAbility() != null) {
|
||||||
SpellAbility old = this.getOverridingAbility();
|
copy.setOverridingAbility(getOverridingAbility().copy(newHost, lki));
|
||||||
SpellAbility sa = old;
|
|
||||||
// try to copy it if newHost is not the wanted host
|
|
||||||
final Card oldHost = old.getHostCard();
|
|
||||||
if (!newHost.equals(oldHost)) {
|
|
||||||
if (old instanceof AbilitySub) {
|
|
||||||
sa = ((AbilitySub)old).getCopy();
|
|
||||||
sa.setHostCard(newHost);
|
|
||||||
}
|
|
||||||
} else if (newHost != oldHost) {
|
|
||||||
//host would be the same, but different state?
|
|
||||||
sa.setHostCard(newHost);
|
|
||||||
}
|
|
||||||
copy.setOverridingAbility(sa);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2015-03-07 Removing the ID copying which makes copied triggers Identical to each other when removing
|
if (!lki) {
|
||||||
//copy.setID(this.getId());
|
copy.setId(nextId());
|
||||||
copy.setMode(this.getMode());
|
}
|
||||||
copy.setTriggerPhases(this.validPhases);
|
|
||||||
|
if (validPhases != null) {
|
||||||
|
copy.setTriggerPhases(Lists.newArrayList(validPhases));
|
||||||
|
}
|
||||||
copy.setActiveZone(validHostZones);
|
copy.setActiveZone(validHostZones);
|
||||||
copy.setTemporary(isTemporary());
|
copy.setTemporary(isTemporary());
|
||||||
return copy;
|
return copy;
|
||||||
@@ -572,4 +564,14 @@ public abstract class Trigger extends TriggerReplacementBase {
|
|||||||
{
|
{
|
||||||
this.numberTurnActivations = 0;
|
this.numberTurnActivations = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public final Object clone() {
|
||||||
|
try {
|
||||||
|
return super.clone();
|
||||||
|
} catch (final Exception ex) {
|
||||||
|
throw new RuntimeException("Trigger : clone() error, " + ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,11 +86,9 @@ public enum TriggerType {
|
|||||||
Untaps(TriggerUntaps.class),
|
Untaps(TriggerUntaps.class),
|
||||||
Vote(TriggerVote.class);
|
Vote(TriggerVote.class);
|
||||||
|
|
||||||
private final Class<? extends Trigger> classTrigger;
|
|
||||||
private final Constructor<? extends Trigger> constructor;
|
private final Constructor<? extends Trigger> constructor;
|
||||||
|
|
||||||
private TriggerType(Class<? extends Trigger> clasz) {
|
private TriggerType(Class<? extends Trigger> clasz) {
|
||||||
classTrigger = clasz;
|
|
||||||
constructor = findConstructor(clasz);
|
constructor = findConstructor(clasz);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,16 +121,6 @@ public enum TriggerType {
|
|||||||
throw new RuntimeException("Element " + value + " not found in TriggerType enum");
|
throw new RuntimeException("Element " + value + " not found in TriggerType enum");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TriggerType getTypeFor(Trigger t) {
|
|
||||||
final Class<? extends Trigger> cls = t.getClass();
|
|
||||||
for (final TriggerType v : TriggerType.values()) {
|
|
||||||
if (v.classTrigger.equals(cls)) {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Write javadoc for this method.
|
* TODO: Write javadoc for this method.
|
||||||
* @param mapParams
|
* @param mapParams
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
Name:Clifftop Retreat
|
Name:Clifftop Retreat
|
||||||
ManaCost:no cost
|
ManaCost:no cost
|
||||||
Types:Land
|
Types:Land
|
||||||
R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | Description$ CARDNAME enters the battlefield tapped unless you control a Mountain or a Plains.
|
K:ETBReplacement:Other:LandTapped
|
||||||
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ ETBCheckSVar | ConditionSVarCompare$ EQ0 | References$ ETBCheckSVar | SubAbility$ MoveToPlay
|
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Mountain.YouCtrl,Plains.YouCtrl | ConditionCompare$ EQ0 | SpellDescription$ CARDNAME enters the battlefield tapped unless you control a Mountain or a Plains.
|
||||||
SVar:MoveToPlay:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Battlefield | Defined$ ReplacedCard
|
|
||||||
SVar:ETBCheckSVar:Count$Valid Mountain.YouCtrl,Plains.YouCtrl
|
|
||||||
A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R} to your mana pool.
|
||||||
A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add {W} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add {W} to your mana pool.
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/clifftop_retreat.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/clifftop_retreat.jpg
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
Name:Dragonskull Summit
|
Name:Dragonskull Summit
|
||||||
ManaCost:no cost
|
ManaCost:no cost
|
||||||
Types:Land
|
Types:Land
|
||||||
R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | Description$ CARDNAME enters the battlefield tapped unless you control a Swamp or a Mountain.
|
K:ETBReplacement:Other:LandTapped
|
||||||
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ ETBCheckSVar | ConditionSVarCompare$ EQ0 | References$ ETBCheckSVar | SubAbility$ MoveToPlay
|
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Swamp.YouCtrl,Mountain.YouCtrl | ConditionCompare$ EQ0 | SpellDescription$ CARDNAME enters the battlefield tapped unless you control a Swamp or a Mountain.
|
||||||
SVar:MoveToPlay:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Battlefield | Defined$ ReplacedCard
|
|
||||||
SVar:ETBCheckSVar:Count$Valid Swamp.YouCtrl,Mountain.YouCtrl
|
|
||||||
A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B} to your mana pool.
|
||||||
A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R} to your mana pool.
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/dragonskull_summit.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/dragonskull_summit.jpg
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
Name:Drowned Catacomb
|
Name:Drowned Catacomb
|
||||||
ManaCost:no cost
|
ManaCost:no cost
|
||||||
Types:Land
|
Types:Land
|
||||||
R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | Description$ CARDNAME enters the battlefield tapped unless you control an Island or a Swamp.
|
K:ETBReplacement:Other:LandTapped
|
||||||
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ ETBCheckSVar | ConditionSVarCompare$ EQ0 | References$ ETBCheckSVar | SubAbility$ MoveToPlay
|
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Island.YouCtrl,Swamp.YouCtrl | ConditionCompare$ EQ0 | SpellDescription$ CARDNAME enters the battlefield tapped unless you control an Island or a Swamp.
|
||||||
SVar:MoveToPlay:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Battlefield | Defined$ ReplacedCard
|
|
||||||
SVar:ETBCheckSVar:Count$Valid Island.YouCtrl,Swamp.YouCtrl
|
|
||||||
A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U} to your mana pool.
|
||||||
A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B} to your mana pool.
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/drowned_catacomb.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/drowned_catacomb.jpg
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
Name:Glacial Fortress
|
Name:Glacial Fortress
|
||||||
ManaCost:no cost
|
ManaCost:no cost
|
||||||
Types:Land
|
Types:Land
|
||||||
R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | Description$ CARDNAME enters the battlefield tapped unless you control a Plains or an Island.
|
K:ETBReplacement:Other:LandTapped
|
||||||
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ ETBCheckSVar | ConditionSVarCompare$ EQ0 | References$ ETBCheckSVar | SubAbility$ MoveToPlay
|
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Plains.YouCtrl,Island.YouCtrl | ConditionCompare$ EQ0 | SpellDescription$ CARDNAME enters the battlefield tapped unless you control a Plains or an Island.
|
||||||
SVar:MoveToPlay:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Battlefield | Defined$ ReplacedCard
|
|
||||||
SVar:ETBCheckSVar:Count$Valid Island.YouCtrl,Plains.YouCtrl
|
|
||||||
A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add {W} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add {W} to your mana pool.
|
||||||
A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U} to your mana pool.
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/glacial_fortress.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/glacial_fortress.jpg
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
Name:Hinterland Harbor
|
Name:Hinterland Harbor
|
||||||
ManaCost:no cost
|
ManaCost:no cost
|
||||||
Types:Land
|
Types:Land
|
||||||
R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | Description$ CARDNAME enters the battlefield tapped unless you control a Forest or an Island.
|
K:ETBReplacement:Other:LandTapped
|
||||||
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ ETBCheckSVar | ConditionSVarCompare$ EQ0 | References$ ETBCheckSVar | SubAbility$ MoveToPlay
|
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Forest.YouCtrl,Island.YouCtrl | ConditionCompare$ EQ0 | SpellDescription$ CARDNAME enters the battlefield tapped unless you control a Forest or an Island.
|
||||||
SVar:MoveToPlay:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Battlefield | Defined$ ReplacedCard
|
|
||||||
SVar:ETBCheckSVar:Count$Valid Island.YouCtrl,Forest.YouCtrl
|
|
||||||
A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G} to your mana pool.
|
||||||
A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U} to your mana pool.
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/hinterland_harbor.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/hinterland_harbor.jpg
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
Name:Isolated Chapel
|
Name:Isolated Chapel
|
||||||
ManaCost:no cost
|
ManaCost:no cost
|
||||||
Types:Land
|
Types:Land
|
||||||
R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | Description$ CARDNAME enters the battlefield tapped unless you control a Plains or a Swamp.
|
K:ETBReplacement:Other:LandTapped
|
||||||
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ ETBCheckSVar | ConditionSVarCompare$ EQ0 | References$ ETBCheckSVar | SubAbility$ MoveToPlay
|
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Plains.YouCtrl,Swamp.YouCtrl | ConditionCompare$ EQ0 | SpellDescription$ CARDNAME enters the battlefield tapped unless you control a Plains or a Swamp.
|
||||||
SVar:MoveToPlay:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Battlefield | Defined$ ReplacedCard
|
|
||||||
SVar:ETBCheckSVar:Count$Valid Plains.YouCtrl,Swamp.YouCtrl
|
|
||||||
A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add {W} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add {W} to your mana pool.
|
||||||
A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B} to your mana pool.
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/isolated_chapel.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/isolated_chapel.jpg
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
Name:Rootbound Crag
|
Name:Rootbound Crag
|
||||||
ManaCost:no cost
|
ManaCost:no cost
|
||||||
Types:Land
|
Types:Land
|
||||||
R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | Description$ CARDNAME enters the battlefield tapped unless you control a Mountain or a Forest.
|
K:ETBReplacement:Other:LandTapped
|
||||||
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ ETBCheckSVar | ConditionSVarCompare$ EQ0 | References$ ETBCheckSVar | SubAbility$ MoveToPlay
|
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Mountain.YouCtrl,Forest.YouCtrl | ConditionCompare$ EQ0 | SpellDescription$ CARDNAME enters the battlefield tapped unless you control a Mountain or a Forest.
|
||||||
SVar:MoveToPlay:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Battlefield | Defined$ ReplacedCard
|
|
||||||
SVar:ETBCheckSVar:Count$Valid Mountain.YouCtrl,Forest.YouCtrl
|
|
||||||
A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R} to your mana pool.
|
||||||
A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G} to your mana pool.
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/rootbound_crag.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/rootbound_crag.jpg
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
Name:Sulfur Falls
|
Name:Sulfur Falls
|
||||||
ManaCost:no cost
|
ManaCost:no cost
|
||||||
Types:Land
|
Types:Land
|
||||||
R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | Description$ CARDNAME enters the battlefield tapped unless you control an Island or a Mountain.
|
K:ETBReplacement:Other:LandTapped
|
||||||
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ ETBCheckSVar | ConditionSVarCompare$ EQ0 | References$ ETBCheckSVar | SubAbility$ MoveToPlay
|
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Island.YouCtrl,Mountain.YouCtrl | ConditionCompare$ EQ0 | SpellDescription$ CARDNAME enters the battlefield tapped unless you control an Island or a Mountain.
|
||||||
SVar:MoveToPlay:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Battlefield | Defined$ ReplacedCard
|
|
||||||
SVar:ETBCheckSVar:Count$Valid Mountain.YouCtrl,Island.YouCtrl
|
|
||||||
A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U} to your mana pool.
|
||||||
A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R} to your mana pool.
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/sulfur_falls.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/sulfur_falls.jpg
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
Name:Sunpetal Grove
|
Name:Sunpetal Grove
|
||||||
ManaCost:no cost
|
ManaCost:no cost
|
||||||
Types:Land
|
Types:Land
|
||||||
R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | Description$ CARDNAME enters the battlefield tapped unless you control a Forest or a Plains.
|
K:ETBReplacement:Other:LandTapped
|
||||||
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ ETBCheckSVar | ConditionSVarCompare$ EQ0 | References$ ETBCheckSVar | SubAbility$ MoveToPlay
|
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Forest.YouCtrl,Plains.YouCtrl | ConditionCompare$ EQ0 | SpellDescription$ CARDNAME enters the battlefield tapped unless you control a Forest or a Plains.
|
||||||
SVar:MoveToPlay:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Battlefield | Defined$ ReplacedCard
|
|
||||||
SVar:ETBCheckSVar:Count$Valid Forest.YouCtrl,Plains.YouCtrl
|
|
||||||
A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add {W} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add {W} to your mana pool.
|
||||||
A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G} to your mana pool.
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/sunpetal_grove.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/sunpetal_grove.jpg
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
Name:Woodland Cemetery
|
Name:Woodland Cemetery
|
||||||
ManaCost:no cost
|
ManaCost:no cost
|
||||||
Types:Land
|
Types:Land
|
||||||
R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | Description$ CARDNAME enters the battlefield tapped unless you control a Swamp or a Forest.
|
K:ETBReplacement:Other:LandTapped
|
||||||
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ ETBCheckSVar | ConditionSVarCompare$ EQ0 | References$ ETBCheckSVar | SubAbility$ MoveToPlay
|
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Swamp.YouCtrl,Forest.YouCtrl | ConditionCompare$ EQ0 | SpellDescription$ CARDNAME enters the battlefield tapped unless you control a Swamp or a Forest.
|
||||||
SVar:MoveToPlay:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Battlefield | Defined$ ReplacedCard
|
|
||||||
SVar:ETBCheckSVar:Count$Valid Swamp.YouCtrl,Forest.YouCtrl
|
|
||||||
A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B} to your mana pool.
|
||||||
A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G} to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G} to your mana pool.
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/woodland_cemetery.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/woodland_cemetery.jpg
|
||||||
|
|||||||
Reference in New Issue
Block a user