mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 03:08:02 +00:00
Spellskite script uses a general clause 'ChangeSingleTarget', uses 'Defined' to specify new target
SpellAbility.canTarget now also works for SpellAbilities
This commit is contained in:
@@ -2,6 +2,6 @@ Name:Spellskite
|
|||||||
ManaCost:2
|
ManaCost:2
|
||||||
Types:Artifact Creature Horror
|
Types:Artifact Creature Horror
|
||||||
PT:0/4
|
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
|
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.)
|
Oracle:{UP}: Change a target of target spell or ability to Spellskite. ({UP} can be paid with either {U} or 2 life.)
|
||||||
@@ -6,6 +6,8 @@ import java.util.List;
|
|||||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.ITargetable;
|
import forge.ITargetable;
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
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 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;
|
SpellAbilityStackInstance changingTgtSI = si;
|
||||||
Player chooser = sa.getActivatingPlayer();
|
Player chooser = sa.getActivatingPlayer();
|
||||||
|
|
||||||
if( isSpellskite ) {
|
if( changeOneTarget ) {
|
||||||
Card srcCard = sa.getSourceCard();
|
ITargetable newTarget = Iterables.getFirst(getDefinedCardsOrTargeted(sa), null);
|
||||||
// 1. choose a target of target spell
|
// 1. choose a target of target spell
|
||||||
List<Pair<SpellAbilityStackInstance, ITargetable>> allTargets = new ArrayList<>();
|
List<Pair<SpellAbilityStackInstance, ITargetable>> allTargets = new ArrayList<>();
|
||||||
while(changingTgtSI != null) {
|
while(changingTgtSI != null) {
|
||||||
@@ -69,8 +71,8 @@ public class ChangeTargetsEffect extends SpellAbilityEffect {
|
|||||||
newTargetBlock.remove(oldTarget);
|
newTargetBlock.remove(oldTarget);
|
||||||
replaceIn.updateTarget(newTargetBlock);
|
replaceIn.updateTarget(newTargetBlock);
|
||||||
// 3. test if replacing is correct.
|
// 3. test if replacing is correct.
|
||||||
if(replaceIn.getSpellAbility().canTarget(srcCard)) {
|
if(replaceIn.getSpellAbility().canTarget(newTarget)) {
|
||||||
newTargetBlock.add(srcCard);
|
newTargetBlock.add(newTarget);
|
||||||
replaceIn.updateTarget(newTargetBlock);
|
replaceIn.updateTarget(newTargetBlock);
|
||||||
} else
|
} else
|
||||||
replaceIn.updateTarget(oldTargetBlock);
|
replaceIn.updateTarget(oldTargetBlock);
|
||||||
|
|||||||
@@ -1019,20 +1019,19 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable {
|
|||||||
* a GameEntity
|
* a GameEntity
|
||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public final boolean canTarget(final GameEntity entity) {
|
public final boolean canTarget(final ITargetable entity) {
|
||||||
if (this.getTargetRestrictions() == null) {
|
// Restriction related to this ability
|
||||||
if (entity.canBeTargetedBy(this)) {
|
if (this.getTargetRestrictions() != null) {
|
||||||
return true;
|
if (this.getTargetRestrictions().isUniqueTargets() && this.getUniqueTargets().contains(entity))
|
||||||
}
|
return false;
|
||||||
return false;
|
|
||||||
}
|
String[] validTgt = this.getTargetRestrictions().getValidTgts();
|
||||||
if (entity.isValid(this.getTargetRestrictions().getValidTgts(), this.getActivatingPlayer(), this.getSourceCard())
|
if (entity instanceof GameEntity && !((GameEntity)entity).isValid(validTgt, this.getActivatingPlayer(), this.getSourceCard()))
|
||||||
&& (!this.getTargetRestrictions().isUniqueTargets() || !this.getUniqueTargets().contains(entity))
|
return false;
|
||||||
&& entity.canBeTargetedBy(this)) {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
// Restrictions coming from target
|
||||||
|
return entity.canBeTargetedBy(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// is this a wrapping ability (used by trigger abilities)
|
// is this a wrapping ability (used by trigger abilities)
|
||||||
@@ -1298,12 +1297,6 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable {
|
|||||||
this.temporary = temporary; // TODO: Add 0 to parameter's name.
|
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
|
@Override
|
||||||
public boolean canBeTargetedBy(SpellAbility sa) {
|
public boolean canBeTargetedBy(SpellAbility sa) {
|
||||||
return sa.canTargetSpellAbility(this);
|
return sa.canTargetSpellAbility(this);
|
||||||
@@ -1321,6 +1314,11 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable {
|
|||||||
return targetRestricions;
|
return targetRestricions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// THE CODE BELOW IS RELATED TO TARGETING. It might be extracted to other class from here
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public void setTargetRestrictions(final TargetRestrictions tgt) {
|
public void setTargetRestrictions(final TargetRestrictions tgt) {
|
||||||
targetRestricions = tgt;
|
targetRestricions = tgt;
|
||||||
|
|||||||
Reference in New Issue
Block a user