diff --git a/forge-game/src/main/java/forge/game/ForgeScript.java b/forge-game/src/main/java/forge/game/ForgeScript.java index 119c7c36e74..d7a41fd52dc 100644 --- a/forge-game/src/main/java/forge/game/ForgeScript.java +++ b/forge-game/src/main/java/forge/game/ForgeScript.java @@ -15,12 +15,16 @@ import forge.game.mana.ManaCostBeingPaid; import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbilityPredicates; +import forge.game.spellability.TargetChoices; import forge.game.staticability.StaticAbility; import forge.game.trigger.Trigger; import forge.game.zone.ZoneType; import forge.util.Expressions; import org.apache.commons.lang3.StringUtils; +import java.util.HashSet; +import java.util.Set; + public class ForgeScript { public static boolean cardStateHasProperty(CardState cardState, String property, Player sourceController, @@ -217,6 +221,15 @@ public class ForgeScript { return false; } return source.equals(m.getHostCard()); + } else if (property.startsWith("numTargets")) { + Set targets = new HashSet<>(); + for (TargetChoices tc : sa.getAllTargetChoices()) { + targets.addAll(tc); + } + String[] k = property.split(" ", 2); + String comparator = k[1].substring(0, 2); + int y = AbilityUtils.calculateAmount(sa.getHostCard(), k[1].substring(2), sa); + return Expressions.compare(targets.size(), comparator, y); } else if (property.startsWith("IsTargeting")) { String[] k = property.split(" ", 2); boolean found = false; diff --git a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java index 383627de66e..cfb843b4e3f 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java @@ -365,9 +365,6 @@ public final class AbilityFactory { abTgt.setSAValidTargeting(mapParams.get("TargetValidTargeting")); } - if (mapParams.containsKey("TargetsSingleTarget")) { - abTgt.setSingleTarget(true); - } if (mapParams.containsKey("TargetUnique")) { abTgt.setUniqueTargets(true); } diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index 6ba34f181cf..7940ae92aa0 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -21,11 +21,9 @@ import java.util.Arrays; import java.util.EnumMap; import java.util.EnumSet; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; @@ -1971,21 +1969,6 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit } } - if (tgt.isSingleTarget()) { - Set targets = new HashSet<>(); - for (TargetChoices tc : topSA.getAllTargetChoices()) { - targets.addAll(tc); - if (targets.size() > 1) { - // As soon as we get more than one, bail out - return false; - } - } - if (targets.size() != 1) { - // Make sure that there actually is one target - return false; - } - } - return topSA.getHostCard().isValid(tgt.getValidTgts(), getActivatingPlayer(), getHostCard(), this); } diff --git a/forge-game/src/main/java/forge/game/spellability/TargetRestrictions.java b/forge-game/src/main/java/forge/game/spellability/TargetRestrictions.java index 0bd7702073f..729694181fd 100644 --- a/forge-game/src/main/java/forge/game/spellability/TargetRestrictions.java +++ b/forge-game/src/main/java/forge/game/spellability/TargetRestrictions.java @@ -65,7 +65,6 @@ public class TargetRestrictions { private boolean withoutSameCreatureType = false; private boolean withSameCreatureType = false; private boolean withSameCardType = false; - private boolean singleTarget = false; private boolean randomTarget = false; private boolean randomNumTargets = false; @@ -108,7 +107,6 @@ public class TargetRestrictions { this.withoutSameCreatureType = target.isWithoutSameCreatureType(); this.withSameCreatureType = target.isWithSameCreatureType(); this.withSameCardType = target.isWithSameCardType(); - this.singleTarget = target.isSingleTarget(); this.randomTarget = target.isRandomTarget(); this.randomNumTargets = target.isRandomNumTargets(); } @@ -767,20 +765,6 @@ public class TargetRestrictions { this.sameController = same; } - /** - * @return the singleTarget - */ - public boolean isSingleTarget() { - return singleTarget; - } - - /** - * @param singleTarget the singleTarget to set - */ - public void setSingleTarget(boolean singleTarget) { - this.singleTarget = singleTarget; - } - public final void applyTargetTextChanges(final SpellAbility sa) { for (int i = 0; i < validTgts.length; i++) { validTgts[i] = AbilityUtils.applyAbilityTextChangeEffects(originalValidTgts[i], sa); diff --git a/forge-gui/res/cardsfolder/b/bolt_bend.txt b/forge-gui/res/cardsfolder/b/bolt_bend.txt index 6e08c907d82..97f87c8dbf0 100644 --- a/forge-gui/res/cardsfolder/b/bolt_bend.txt +++ b/forge-gui/res/cardsfolder/b/bolt_bend.txt @@ -2,6 +2,6 @@ Name:Bolt Bend ManaCost:3 R Types:Instant S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ 3 | EffectZone$ All | IsPresent$ Creature.YouCtrl+powerGE4 | Description$ This Spell costs {3} less to cast if you control a creature with power 4 or greater. -A:SP$ ChangeTargets | Cost$ 3 R | TargetType$ Spell,Activated,Triggered | ValidTgts$ Card | TargetsSingleTarget$ True | SpellDescription$ Change the target of target spell or ability with a single target. +A:SP$ ChangeTargets | TargetType$ SpellAbility.numTargets EQ1 | ValidTgts$ Card | TgtPrompt$ Select target spell or ability with a single target | SpellDescription$ Change the target of target spell or ability with a single target. AI:RemoveDeck:All Oracle:This spell costs {3} less to cast if you control a creature with power 4 or greater.\nChange the target of target spell or ability with a single target. diff --git a/forge-gui/res/cardsfolder/c/chefs_kiss.txt b/forge-gui/res/cardsfolder/c/chefs_kiss.txt index 53e2b33f31c..fd28ca98b52 100644 --- a/forge-gui/res/cardsfolder/c/chefs_kiss.txt +++ b/forge-gui/res/cardsfolder/c/chefs_kiss.txt @@ -1,7 +1,7 @@ Name:Chef's Kiss ManaCost:1 R R Types:Instant -A:SP$ ControlSpell | ValidTgts$ Card | TgtPrompt$ Select target spell that targets only a single permanent or player | TargetType$ Spell | Mode$ Gain | TargetsSingleTarget$ True | TargetValidTargeting$ Permanent.inZoneBattlefield,Player | SubAbility$ DBCopy | StackDescription$ SpellDescription | SpellDescription$ Gain control of target spell that targets only a single permanent or player. Copy it, then reselect the targets at random for the spell and the copy. The new targets can't be you or a permanent you control. +A:SP$ ControlSpell | ValidTgts$ Card | TgtPrompt$ Select target spell that targets only a single permanent or player | TargetType$ Spell.numTargets EQ1+IsTargeting Player,Spell.numTargets EQ1+IsTargeting Valid Permanent | Mode$ Gain | SubAbility$ DBCopy | StackDescription$ SpellDescription | SpellDescription$ Gain control of target spell that targets only a single permanent or player. Copy it, then reselect the targets at random for the spell and the copy. The new targets can't be you or a permanent you control. SVar:DBCopy:DB$ CopySpellAbility | Defined$ Targeted | RandomTarget$ True | RandomTargetRestriction$ Player.Other,Permanent.YouDontCtrl | SubAbility$ DBChangeTargets | StackDescription$ None SVar:DBChangeTargets:DB$ ChangeTargets | Defined$ Targeted | RandomTarget$ True | RandomTargetRestriction$ Player.Other,Permanent.YouDontCtrl Oracle:Gain control of target spell that targets only a single permanent or player. Copy it, then reselect the targets at random for the spell and the copy. The new targets can't be you or a permanent you control. diff --git a/forge-gui/res/cardsfolder/d/deflection.txt b/forge-gui/res/cardsfolder/d/deflection.txt index 1d14df1bd92..c2db064317a 100644 --- a/forge-gui/res/cardsfolder/d/deflection.txt +++ b/forge-gui/res/cardsfolder/d/deflection.txt @@ -1,6 +1,6 @@ Name:Deflection ManaCost:3 U Types:Instant -A:SP$ ChangeTargets | Cost$ 3 U | TargetType$ Spell | ValidTgts$ Card | TargetsSingleTarget$ True | SpellDescription$ Change the target of target spell with a single target. +A:SP$ ChangeTargets | TargetType$ Spell.numTargets EQ1 | ValidTgts$ Card | TgtPrompt$ Select target spell with a single target | SpellDescription$ Change the target of target spell with a single target. AI:RemoveDeck:All Oracle:Change the target of target spell with a single target. diff --git a/forge-gui/res/cardsfolder/d/divert.txt b/forge-gui/res/cardsfolder/d/divert.txt index 316a627acbc..7745a1c0fde 100644 --- a/forge-gui/res/cardsfolder/d/divert.txt +++ b/forge-gui/res/cardsfolder/d/divert.txt @@ -1,6 +1,6 @@ Name:Divert ManaCost:U Types:Instant -A:SP$ ChangeTargets | Cost$ U | TargetType$ Spell | ValidTgts$ Card | TargetsSingleTarget$ True | RememberTargets$ True | ForgetOtherRemembered$ True | UnlessCost$ 2 | SpellDescription$ Change the target of target spell with a single target unless that spell's controller pays {2}. +A:SP$ ChangeTargets | TargetType$ Spell.numTargets EQ1 | ValidTgts$ Card | TgtPrompt$ Select target spell with a single target | UnlessCost$ 2 | SpellDescription$ Change the target of target spell with a single target unless that spell's controller pays {2}. AI:RemoveDeck:All Oracle:Change the target of target spell with a single target unless that spell's controller pays {2}. diff --git a/forge-gui/res/cardsfolder/i/imps_mischief.txt b/forge-gui/res/cardsfolder/i/imps_mischief.txt index 62140811de9..64ce8ee1ef8 100644 --- a/forge-gui/res/cardsfolder/i/imps_mischief.txt +++ b/forge-gui/res/cardsfolder/i/imps_mischief.txt @@ -1,8 +1,8 @@ Name:Imp's Mischief ManaCost:1 B Types:Instant -A:SP$ ChangeTargets | Cost$ 1 B | TargetType$ Spell | ValidTgts$ Card | TargetsSingleTarget$ True | RememberTargetedCard$ True | SubAbility$ DBLoseLife | SpellDescription$ Change the target of target spell with a single target. You lose life equal to that spell's mana value. -SVar:DBLoseLife:DB$ LoseLife | Defined$ You | LifeAmount$ X | SubAbility$ DBCleanup +A:SP$ ChangeTargets | TargetType$ Spell.numTargets EQ1 | ValidTgts$ Card | TgtPrompt$ Select target spell with a single target | RememberTargetedCard$ True | SubAbility$ DBLoseLife | SpellDescription$ Change the target of target spell with a single target. You lose life equal to that spell's mana value. +SVar:DBLoseLife:DB$ LoseLife | LifeAmount$ X | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:Remembered$CardManaCost AI:RemoveDeck:All diff --git a/forge-gui/res/cardsfolder/m/misdirection.txt b/forge-gui/res/cardsfolder/m/misdirection.txt index 4344682116c..600c1e4d253 100644 --- a/forge-gui/res/cardsfolder/m/misdirection.txt +++ b/forge-gui/res/cardsfolder/m/misdirection.txt @@ -2,6 +2,6 @@ Name:Misdirection ManaCost:3 U U Types:Instant SVar:AltCost:Cost$ ExileFromHand<1/Card.Blue+Other> | Description$ You may exile a blue card from your hand rather than pay this spell's mana cost. -A:SP$ ChangeTargets | Cost$ 3 U U | TargetType$ Spell | ValidTgts$ Card | TargetsSingleTarget$ True | SpellDescription$ Change the target of target spell with a single target. +A:SP$ ChangeTargets | TargetType$ Spell.numTargets EQ1 | ValidTgts$ Card | TgtPrompt$ Select target spell with a single target | SpellDescription$ Change the target of target spell with a single target. AI:RemoveDeck:All Oracle:You may exile a blue card from your hand rather than pay this spell's mana cost.\nChange the target of target spell with a single target. diff --git a/forge-gui/res/cardsfolder/m/muck_drubb.txt b/forge-gui/res/cardsfolder/m/muck_drubb.txt index 719970deba4..8c60d076116 100644 --- a/forge-gui/res/cardsfolder/m/muck_drubb.txt +++ b/forge-gui/res/cardsfolder/m/muck_drubb.txt @@ -4,6 +4,6 @@ Types:Creature Beast PT:3/3 K:Flash T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChange | TriggerDescription$ When CARDNAME enters the battlefield, change the target of target spell that targets only a single creature to Muck Drubb. -SVar:TrigChange:DB$ ChangeTargets | TargetType$ Spell | ValidTgts$ Card | DefinedMagnet$ Self | TargetsSingleTarget$ True | TargetValidTargeting$ Creature +SVar:TrigChange:DB$ ChangeTargets | TargetType$ Spell.numTargets EQ1+IsTargeting Valid Creature | ValidTgts$ Card | TgtPrompt$ Select target spell that targets only a single creature | DefinedMagnet$ Self K:Madness:2 B Oracle:Flash\nWhen Muck Drubb enters the battlefield, change the target of target spell that targets only a single creature to Muck Drubb.\nMadness {2}{B} (If you discard this card, discard it into exile. When you do, cast it for its madness cost or put it into your graveyard.) diff --git a/forge-gui/res/cardsfolder/r/radiant_performer.txt b/forge-gui/res/cardsfolder/r/radiant_performer.txt index 9db7febc942..b1afad01f91 100644 --- a/forge-gui/res/cardsfolder/r/radiant_performer.txt +++ b/forge-gui/res/cardsfolder/r/radiant_performer.txt @@ -4,5 +4,5 @@ Types:Creature Human Wizard PT:2/2 K:Flash T:Mode$ ChangesZone | ValidCard$ Card.wasCastFromYourHandByYou+Self | Destination$ Battlefield | Execute$ TrigRadiate | TriggerDescription$ When CARDNAME enters the battlefield, if you cast it from your hand, choose target spell or ability that targets only a single permanent or player. Copy that spell or ability for each other permanent or player the spell or ability could target. Each copy targets a different one of those permanents and players. -SVar:TrigRadiate:DB$ CopySpellAbility | ValidTgts$ Card | TgtPrompt$ Select target spell or ability that targets a single permanent or player | TargetType$ Spell,Activated,Triggered | TargetsSingleTarget$ True | TargetValidTargeting$ Permanent.inZoneBattlefield,Player | Controller$ You | CopyForEachCanTarget$ True | CanTargetPlayer$ True | SpellDescription$ Choose target spell or ability that targets only a single permanent or player. Copy that spell for each other permanent or player the spell could target. Each copy targets a different one of those permanents and players. +SVar:TrigRadiate:DB$ CopySpellAbility | ValidTgts$ Card | TgtPrompt$ Select target spell or ability that targets a single permanent or player | TargetType$ SpellAbility.numTargets EQ1+IsTargeting Player,SpellAbility.numTargets EQ1+IsTargeting Valid Permanent | Controller$ You | CopyForEachCanTarget$ True | CanTargetPlayer$ True | SpellDescription$ Choose target spell or ability that targets only a single permanent or player. Copy that spell for each other permanent or player the spell could target. Each copy targets a different one of those permanents and players. Oracle:Flash\nWhen Radiant Performer enters the battlefield, if you cast it from your hand, choose target spell or ability that targets only a single permanent or player. Copy that spell or ability for each other permanent or player the spell or ability could target. Each copy targets a different one of those permanents and players. diff --git a/forge-gui/res/cardsfolder/r/radiate.txt b/forge-gui/res/cardsfolder/r/radiate.txt index ff8fb6fc763..ffa31c261db 100644 --- a/forge-gui/res/cardsfolder/r/radiate.txt +++ b/forge-gui/res/cardsfolder/r/radiate.txt @@ -1,6 +1,6 @@ Name:Radiate ManaCost:3 R R Types:Instant -A:SP$ CopySpellAbility | Cost$ 3 R R | ValidTgts$ Instant,Sorcery | TargetType$ Spell | TargetsSingleTarget$ True | TargetValidTargeting$ Permanent.inZoneBattlefield,Player | Controller$ You | CopyForEachCanTarget$ True | CanTargetPlayer$ True | SpellDescription$ Choose target instant or sorcery spell that targets only a single permanent or player. Copy that spell for each other permanent or player the spell could target. Each copy targets a different one of those permanents and players. +A:SP$ CopySpellAbility | ValidTgts$ Instant,Sorcery | TgtPrompt$ Choose target instant or sorcery spell that targets only a single permanent or player | TargetType$ Spell.numTargets EQ1+IsTargeting Player,Spell.numTargets EQ1+IsTargeting Valid Permanent | Controller$ You | CopyForEachCanTarget$ True | CanTargetPlayer$ True | SpellDescription$ Choose target instant or sorcery spell that targets only a single permanent or player. Copy that spell for each other permanent or player the spell could target. Each copy targets a different one of those permanents and players. AI:RemoveDeck:Random Oracle:Choose target instant or sorcery spell that targets only a single permanent or player. Copy that spell for each other permanent or player the spell could target. Each copy targets a different one of those permanents and players. diff --git a/forge-gui/res/cardsfolder/r/rebound.txt b/forge-gui/res/cardsfolder/r/rebound.txt index d48b9f2fee8..853723cbed2 100644 --- a/forge-gui/res/cardsfolder/r/rebound.txt +++ b/forge-gui/res/cardsfolder/r/rebound.txt @@ -1,6 +1,6 @@ Name:Rebound ManaCost:1 U Types:Instant -A:SP$ ChangeTargets | Cost$ 1 U | TargetType$ Spell | ValidTgts$ Card | TargetValidTargeting$ Player | TargetsSingleTarget$ True | TargetRestriction$ Player | SpellDescription$ Change the target of target spell that targets only a player. The new target must be a player. +A:SP$ ChangeTargets | TargetType$ Spell.numTargets EQ1+IsTargeting Player | ValidTgts$ Card | TgtPrompt$ Select target spell that targets only a player | TargetRestriction$ Player | SpellDescription$ Change the target of target spell that targets only a player. The new target must be a player. AI:RemoveDeck:All Oracle:Change the target of target spell that targets only a player. The new target must be a player. diff --git a/forge-gui/res/cardsfolder/r/reflecting_mirror.txt b/forge-gui/res/cardsfolder/r/reflecting_mirror.txt index d9efb9d4630..a7543d1dc03 100644 --- a/forge-gui/res/cardsfolder/r/reflecting_mirror.txt +++ b/forge-gui/res/cardsfolder/r/reflecting_mirror.txt @@ -1,7 +1,7 @@ Name:Reflecting Mirror ManaCost:4 Types:Artifact -A:AB$ ChangeTargets | Cost$ X T | TargetType$ Spell | ValidTgts$ Card | TargetValidTargeting$ You | TargetsSingleTarget$ True | TargetRestriction$ Player | SpellDescription$ Change the target of target spell with a single target if that target is you. The new target must be a player. X is twice the mana value of that spell. +A:AB$ ChangeTargets | Cost$ X T | TargetType$ Spell.numTargets EQ1+IsTargeting You | ValidTgts$ Card | TgtPrompt$ Select target spell with a single target targeting you | TargetRestriction$ Player | SpellDescription$ Change the target of target spell with a single target if that target is you. The new target must be a player. X is twice the mana value of that spell. AI:RemoveDeck:All SVar:X:Targeted$CardManaCost/Twice Oracle:{X}, {T}: Change the target of target spell with a single target if that target is you. The new target must be a player. X is twice the mana value of that spell. diff --git a/forge-gui/res/cardsfolder/r/reroute.txt b/forge-gui/res/cardsfolder/r/reroute.txt index 63b2917f09b..3c57372c2b9 100644 --- a/forge-gui/res/cardsfolder/r/reroute.txt +++ b/forge-gui/res/cardsfolder/r/reroute.txt @@ -1,7 +1,7 @@ Name:Reroute ManaCost:1 R Types:Instant -A:SP$ ChangeTargets | Cost$ 1 R | TargetType$ Activated | ValidTgts$ Card | TgtPrompt$ Select target Activated Ability | TargetsSingleTarget$ True | SubAbility$ DBDraw | SpellDescription$ Change the target of target activated ability with a single target. (Mana abilities can't be targeted.) Draw a card. +A:SP$ ChangeTargets | TargetType$ Activated.numTargets EQ1 | ValidTgts$ Card | TgtPrompt$ Select target activated ability with a single target | SubAbility$ DBDraw | SpellDescription$ Change the target of target activated ability with a single target. (Mana abilities can't be targeted.) Draw a card. SVar:DBDraw:DB$ Draw | NumCards$ 1 AI:RemoveDeck:All Oracle:Change the target of target activated ability with a single target. (Mana abilities can't be targeted.)\nDraw a card. diff --git a/forge-gui/res/cardsfolder/r/ricochet_trap.txt b/forge-gui/res/cardsfolder/r/ricochet_trap.txt index 93f4e041876..9496fdb9658 100644 --- a/forge-gui/res/cardsfolder/r/ricochet_trap.txt +++ b/forge-gui/res/cardsfolder/r/ricochet_trap.txt @@ -2,6 +2,6 @@ Name:Ricochet Trap ManaCost:3 R Types:Instant Trap SVar:AltCost:Cost$ R | CheckSVar$ X | SVarCompare$ GE1 | StackDescription$ Description | Description$ If an opponent cast a blue spell this turn, you may pay {R} rather than pay this spell's mana cost. -A:SP$ ChangeTargets | Cost$ 3 R | TargetType$ Spell | ValidTgts$ Card | TgtPrompt$ Select target spell with a single target | TargetsSingleTarget$ True | StackDescription$ SpellDescription | SpellDescription$ Change the target of target spell with a single target. +A:SP$ ChangeTargets | TargetType$ Spell.numTargets EQ1 | ValidTgts$ Card | TgtPrompt$ Select target spell with a single target | StackDescription$ SpellDescription | SpellDescription$ Change the target of target spell with a single target. SVar:X:Count$ThisTurnCast_Card.Blue+OppCtrl Oracle:If an opponent cast a blue spell this turn, you may pay {R} rather than pay this spell's mana cost.\nChange the target of target spell with a single target. diff --git a/forge-gui/res/cardsfolder/s/shunt.txt b/forge-gui/res/cardsfolder/s/shunt.txt index a50d97db88b..4af0ab5e3ec 100644 --- a/forge-gui/res/cardsfolder/s/shunt.txt +++ b/forge-gui/res/cardsfolder/s/shunt.txt @@ -1,6 +1,6 @@ Name:Shunt ManaCost:1 R R Types:Instant -A:SP$ ChangeTargets | Cost$ 1 R R | TargetType$ Spell | ValidTgts$ Card | TargetsSingleTarget$ True | SpellDescription$ Change the target of target spell with a single target. +A:SP$ ChangeTargets | TargetType$ Spell.numTargets EQ1 | ValidTgts$ Card | TgtPrompt$ Select target spell with a single target | SpellDescription$ Change the target of target spell with a single target. AI:RemoveDeck:All Oracle:Change the target of target spell with a single target. diff --git a/forge-gui/res/cardsfolder/s/silver_wyvern.txt b/forge-gui/res/cardsfolder/s/silver_wyvern.txt index fea2b671715..0151324bf7e 100644 --- a/forge-gui/res/cardsfolder/s/silver_wyvern.txt +++ b/forge-gui/res/cardsfolder/s/silver_wyvern.txt @@ -3,6 +3,6 @@ ManaCost:3 U U Types:Creature Drake PT:4/3 K:Flying -A:AB$ ChangeTargets | Cost$ U | TargetType$ Spell,Activated,Triggered | ValidTgts$ Card | TargetValidTargeting$ Card.Self | TargetsSingleTarget$ True | TargetRestriction$ Creature | SpellDescription$ Change the target of target spell or ability that targets only CARDNAME. The new target must be a creature. +A:AB$ ChangeTargets | Cost$ U | TargetType$ SpellAbility.numTargets EQ1+IsTargeting Self | ValidTgts$ Card | TgtPrompt$ Select target spell or ability that targets only CARDNAME | TargetRestriction$ Creature | SpellDescription$ Change the target of target spell or ability that targets only CARDNAME. The new target must be a creature. AI:RemoveDeck:All Oracle:Flying\n{U}: Change the target of target spell or ability that targets only Silver Wyvern. The new target must be a creature. diff --git a/forge-gui/res/cardsfolder/s/swerve.txt b/forge-gui/res/cardsfolder/s/swerve.txt index 34f78401b87..8832f6b5016 100644 --- a/forge-gui/res/cardsfolder/s/swerve.txt +++ b/forge-gui/res/cardsfolder/s/swerve.txt @@ -1,6 +1,6 @@ Name:Swerve ManaCost:U R Types:Instant -A:SP$ ChangeTargets | Cost$ U R | TargetType$ Spell | ValidTgts$ Card | TargetsSingleTarget$ True | SpellDescription$ Change the target of target spell with a single target. +A:SP$ ChangeTargets | TargetType$ Spell.numTargets EQ1 | ValidTgts$ Card | TgtPrompt$ Select target spell with a single target | SpellDescription$ Change the target of target spell with a single target. AI:RemoveDeck:All Oracle:Change the target of target spell with a single target. diff --git a/forge-gui/res/cardsfolder/t/torchling.txt b/forge-gui/res/cardsfolder/t/torchling.txt index a896f4ce10f..1d55cdfd51e 100644 --- a/forge-gui/res/cardsfolder/t/torchling.txt +++ b/forge-gui/res/cardsfolder/t/torchling.txt @@ -4,7 +4,7 @@ Types:Creature Shapeshifter PT:3/3 A:AB$ Untap | Cost$ R | SpellDescription$ Untap CARDNAME. A:AB$ MustBlock | Cost$ R | ValidTgts$ Creature | TgtPrompt$ Select target creature | SpellDescription$ Target creature blocks CARDNAME this turn if able. -A:AB$ ChangeTargets | Cost$ R | TargetType$ Spell | ValidTgts$ Card | TargetsSingleTarget$ True | TargetValidTargeting$ Card.Self | SpellDescription$ Change the target of target spell that targets only CARDNAME. +A:AB$ ChangeTargets | Cost$ R | TargetType$ Spell.numTargets EQ1+IsTargeting Self | ValidTgts$ Card | TgtPrompt$ Select target spell that targets only CARDNAME | SpellDescription$ Change the target of target spell that targets only CARDNAME. A:AB$ Pump | Cost$ 1 | NumAtt$ +1 | NumDef$ -1 | SpellDescription$ CARDNAME gets +1/-1 until end of turn. A:AB$ Pump | Cost$ 1 | NumAtt$ -1 | NumDef$ +1 | SpellDescription$ CARDNAME gets -1/+1 until end of turn. AI:RemoveDeck:All diff --git a/forge-gui/res/cardsfolder/upcoming/wylls_reversal.txt b/forge-gui/res/cardsfolder/upcoming/wylls_reversal.txt new file mode 100644 index 00000000000..73d96a0c9bb --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/wylls_reversal.txt @@ -0,0 +1,10 @@ +Name:Wyll's Reversal +ManaCost:2 R +Types:Instant +A:SP$ Pump | TargetType$ SpellAbility.numTargets GE1 | TgtZone$ Stack | ValidTgts$ Card | TgtPrompt$ Select target spell or ability with one or more targets | SubAbility$ RollD20 | StackDescription$ {p:You} chooses {s:Targeted}. | SpellDescription$ Choose target spell or ability with one or more targets. +SVar:RollD20:DB$ RollDice | Sides$ 20 | Modifier$ Y | ResultSubAbilities$ 1-14:ChooseNew,Else:ChooseAndCopy | StackDescription$ SpellDescription | SpellDescription$ Roll a d20 and add the greatest power among creatures you control. +SVar:ChooseNew:DB$ ChangeTargets | Defined$ Targeted | Optional$ True | SpellDescription$ 1—14 VERT You may choose new targets for that spell or ability. +SVar:ChooseAndCopy:DB$ ChangeTargets | Defined$ Targeted | Optional$ True | SubAbility$ DBCopy | SpellDescription$ 15+ VERT You may choose new targets for that spell or ability. +SVar:DBCopy:DB$ CopySpellAbility | Defined$ Targeted | Controller$ You | MayChooseTarget$ True +SVar:Y:Count$Valid Creature.YouCtrl$GreatestPower +Oracle:Choose target spell or ability with one or more targets. Roll a d20 and add the greatest power among creatures you control.\n1-14 | You may choose new targets for that spell or ability.\n15+ | You may choose new targets for that spell or ability. Then copy it. You may choose new targets for the copy. diff --git a/forge-gui/res/cardsfolder/w/warriors_lesson.txt b/forge-gui/res/cardsfolder/w/warriors_lesson.txt index a6b2f164d18..a70d6ecb3aa 100644 --- a/forge-gui/res/cardsfolder/w/warriors_lesson.txt +++ b/forge-gui/res/cardsfolder/w/warriors_lesson.txt @@ -2,7 +2,7 @@ Name:Warriors' Lesson ManaCost:G Types:Instant A:SP$ Animate | Cost$ G | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select up to two target creatures you control | TargetMin$ 0 | TargetMax$ 2 | Triggers$ WarriorLessonDmg | sVars$ WarriorLessonDraw | SpellDescription$ Until end of turn, up to two target creatures you control each gain "Whenever this creature deals combat damage to a player, draw a card." -SVar:WarriorLessonDmg:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ WarriorLessonDraw | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, draw a card. +SVar:WarriorLessonDmg:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ WarriorLessonDraw | TriggerDescription$ Whenever this creature deals combat damage to a player, draw a card. SVar:WarriorLessonDraw:DB$ Draw | Defined$ You | NumCards$ 1 AI:RemoveDeck:All Oracle:Until end of turn, up to two target creatures you control each gain "Whenever this creature deals combat damage to a player, draw a card." diff --git a/forge-gui/res/cardsfolder/w/willbender.txt b/forge-gui/res/cardsfolder/w/willbender.txt index 71b23f34a37..44221c09c1c 100644 --- a/forge-gui/res/cardsfolder/w/willbender.txt +++ b/forge-gui/res/cardsfolder/w/willbender.txt @@ -4,6 +4,6 @@ Types:Creature Human Wizard PT:1/2 K:Morph:1 U T:Mode$ TurnFaceUp | ValidCard$ Card.Self | Execute$ TrigChange | TriggerZones$ Battlefield | TriggerDescription$ When CARDNAME is turned face up, change the target of target spell or ability with a single target. -SVar:TrigChange:DB$ ChangeTargets | TargetType$ Spell,Activated,Triggered | ValidTgts$ Card | TargetsSingleTarget$ True +SVar:TrigChange:DB$ ChangeTargets | TargetType$ SpellAbility.numTargets EQ1 | ValidTgts$ Card | TgtPrompt$ Select target spell or ability with a single target AI:RemoveDeck:All Oracle:Morph {1}{U} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its morph cost.)\nWhen Willbender is turned face up, change the target of target spell or ability with a single target. diff --git a/forge-gui/src/main/java/forge/player/TargetSelection.java b/forge-gui/src/main/java/forge/player/TargetSelection.java index 72c9ebc6180..d5aabf4fdfa 100644 --- a/forge-gui/src/main/java/forge/player/TargetSelection.java +++ b/forge-gui/src/main/java/forge/player/TargetSelection.java @@ -47,6 +47,7 @@ import forge.game.zone.Zone; import forge.game.zone.ZoneType; import forge.gamemodes.match.input.InputSelectTargets; import forge.util.Aggregates; +import forge.util.TextUtil; /** *

@@ -265,10 +266,13 @@ public class TargetSelection { } Object chosen = null; + String message = TextUtil.fastReplace(getTgt().getVTSelection(), + "CARDNAME", ability.getHostCard().toString()); + if (!choices.isEmpty() && mandatory) { - chosen = controller.getGui().one(getTgt().getVTSelection(), choicesFiltered); + chosen = controller.getGui().one(message, choicesFiltered); } else { - chosen = controller.getGui().oneOrNone(getTgt().getVTSelection(), choicesFiltered); + chosen = controller.getGui().oneOrNone(message, choicesFiltered); } if (chosen == null) { return false; @@ -303,7 +307,8 @@ public class TargetSelection { private final boolean chooseCardFromStack(final boolean mandatory) { final TargetRestrictions tgt = this.getTgt(); - final String message = tgt.getVTSelection(); + final String message = TextUtil.fastReplace(tgt.getVTSelection(), + "CARDNAME", ability.getHostCard().toString()); // Find what's targetable, then allow human to choose final List selectOptions = new ArrayList<>(); HashMap stackItemViewCache = new HashMap<>();