diff --git a/res/cardsfolder/s/spellskite.txt b/res/cardsfolder/s/spellskite.txt index aea2e726d20..5319b567ff6 100644 --- a/res/cardsfolder/s/spellskite.txt +++ b/res/cardsfolder/s/spellskite.txt @@ -2,6 +2,6 @@ Name:Spellskite ManaCost:2 Types:Artifact Creature Horror PT:0/4 -A:AB$ ChangeTargets | Cost$ PU | TargetType$ Spell,Activated,Triggered | ValidTgts$ Card | SpellSkite$ True | SpellDescription$ Change a target of target spell or ability to CARDNAME. +A:AB$ ChangeTargets | Cost$ PU | TargetType$ Spell,Activated,Triggered | ValidTgts$ Card | Defined$ Self | ChangeSingleTarget$ True | SpellDescription$ Change a target of target spell or ability to Spellskite. SVar:Picture:http://www.wizards.com/global/images/magic/general/spellskite.jpg Oracle:{UP}: Change a target of target spell or ability to Spellskite. ({UP} can be paid with either {U} or 2 life.) \ No newline at end of file diff --git a/src/main/java/forge/card/ability/effects/ChangeTargetsEffect.java b/src/main/java/forge/card/ability/effects/ChangeTargetsEffect.java index cd5ac0b61a6..1e7b8e468fd 100644 --- a/src/main/java/forge/card/ability/effects/ChangeTargetsEffect.java +++ b/src/main/java/forge/card/ability/effects/ChangeTargetsEffect.java @@ -6,6 +6,8 @@ import java.util.List; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; +import com.google.common.collect.Iterables; + import forge.Card; import forge.ITargetable; import forge.card.ability.SpellAbilityEffect; @@ -38,13 +40,13 @@ public class ChangeTargetsEffect extends SpellAbilityEffect { } boolean preserveNumber = sa.hasParam("PreserveNumber"); // Redirect is not supposed to change number of targets - boolean isSpellskite = sa.hasParam("SpellSkite"); // The only card known to replace targets with self is Spellskite + boolean changeOneTarget = sa.hasParam("ChangeSingleTarget"); // The only card known to replace targets with self is Spellskite SpellAbilityStackInstance changingTgtSI = si; Player chooser = sa.getActivatingPlayer(); - if( isSpellskite ) { - Card srcCard = sa.getSourceCard(); + if( changeOneTarget ) { + ITargetable newTarget = Iterables.getFirst(getDefinedCardsOrTargeted(sa), null); // 1. choose a target of target spell List> allTargets = new ArrayList<>(); while(changingTgtSI != null) { @@ -69,8 +71,8 @@ public class ChangeTargetsEffect extends SpellAbilityEffect { newTargetBlock.remove(oldTarget); replaceIn.updateTarget(newTargetBlock); // 3. test if replacing is correct. - if(replaceIn.getSpellAbility().canTarget(srcCard)) { - newTargetBlock.add(srcCard); + if(replaceIn.getSpellAbility().canTarget(newTarget)) { + newTargetBlock.add(newTarget); replaceIn.updateTarget(newTargetBlock); } else replaceIn.updateTarget(oldTargetBlock); diff --git a/src/main/java/forge/card/spellability/SpellAbility.java b/src/main/java/forge/card/spellability/SpellAbility.java index e63408e229a..a7efd33f468 100644 --- a/src/main/java/forge/card/spellability/SpellAbility.java +++ b/src/main/java/forge/card/spellability/SpellAbility.java @@ -1019,20 +1019,19 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable { * a GameEntity * @return a boolean. */ - public final boolean canTarget(final GameEntity entity) { - if (this.getTargetRestrictions() == null) { - if (entity.canBeTargetedBy(this)) { - return true; - } - return false; - } - if (entity.isValid(this.getTargetRestrictions().getValidTgts(), this.getActivatingPlayer(), this.getSourceCard()) - && (!this.getTargetRestrictions().isUniqueTargets() || !this.getUniqueTargets().contains(entity)) - && entity.canBeTargetedBy(this)) { - return true; + public final boolean canTarget(final ITargetable entity) { + // Restriction related to this ability + if (this.getTargetRestrictions() != null) { + if (this.getTargetRestrictions().isUniqueTargets() && this.getUniqueTargets().contains(entity)) + return false; + + String[] validTgt = this.getTargetRestrictions().getValidTgts(); + if (entity instanceof GameEntity && !((GameEntity)entity).isValid(validTgt, this.getActivatingPlayer(), this.getSourceCard())) + return false; } - return false; + // Restrictions coming from target + return entity.canBeTargetedBy(this); } // is this a wrapping ability (used by trigger abilities) @@ -1297,13 +1296,7 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable { public void setTemporary(boolean temporary) { this.temporary = temporary; // TODO: Add 0 to parameter's name. } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // - // THE CODE BELOW IS RELATED TO TARGETING. It shall await extraction to other class from here - // - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// - + @Override public boolean canBeTargetedBy(SpellAbility sa) { return sa.canTargetSpellAbility(this); @@ -1320,7 +1313,12 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable { public TargetRestrictions getTargetRestrictions() { return targetRestricions; } - + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // + // THE CODE BELOW IS RELATED TO TARGETING. It might be extracted to other class from here + // + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void setTargetRestrictions(final TargetRestrictions tgt) { targetRestricions = tgt;