From f9d3003d35f73cbca2813030f1db59b7dcf184f9 Mon Sep 17 00:00:00 2001 From: ArsenalNut Date: Mon, 3 Dec 2012 08:09:00 +0000 Subject: [PATCH] reworked methods for finding SpellAbility targets --- res/cardsfolder/s/sword_of_war_and_peace.txt | 2 +- res/cardsfolder/u/ulvenwald_tracker.txt | 2 +- src/main/java/forge/Card.java | 24 ++-- .../card/abilityfactory/AbilityFactory.java | 87 +++++--------- .../effects/StoreSVarEffect.java | 35 +----- .../card/cardfactory/CardFactoryUtil.java | 22 ++-- .../forge/card/spellability/SpellAbility.java | 111 ++++++++++++++++-- 7 files changed, 149 insertions(+), 134 deletions(-) diff --git a/res/cardsfolder/s/sword_of_war_and_peace.txt b/res/cardsfolder/s/sword_of_war_and_peace.txt index 424cc02db5c..56aa7515e48 100644 --- a/res/cardsfolder/s/sword_of_war_and_peace.txt +++ b/res/cardsfolder/s/sword_of_war_and_peace.txt @@ -6,7 +6,7 @@ K:Equip 2 S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 2 | AddToughness$ 2 | AddKeyword$ Protection from red & Protection from white | Description$ Equipped creature gets +2/+2 and has protection from red and from white. T:Mode$ DamageDone | ValidSource$ Creature.EquippedBy | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDamage | TriggerZones$ Battlefield | TriggerDescription$ Whenever equipped creature deals combat damage to a player, CARDNAME deals damage to that player equal to the number of cards in his or her hand and you gain 1 life for each card in your hand. SVar:TrigDamage:AB$ DealDamage | Cost$ 0 | Defined$ TriggeredTarget | NumDmg$ X | References$ X | SubAbility$ DBGain -SVar:X:TargetedPlayer$CardsInHand +SVar:X:TriggeredTarget$CardsInHand SVar:DBGain:DB$ GainLife | Defined$ You | LifeAmount$ Y | References$ Y SVar:Y:Count$CardsInYourHand SVar:Rarity:Mythic diff --git a/res/cardsfolder/u/ulvenwald_tracker.txt b/res/cardsfolder/u/ulvenwald_tracker.txt index 7fa896460eb..148eca8c97f 100644 --- a/res/cardsfolder/u/ulvenwald_tracker.txt +++ b/res/cardsfolder/u/ulvenwald_tracker.txt @@ -4,7 +4,7 @@ Types:Creature Human Shaman Text:no text PT:1/1 A:AB$ Pump | Cost$ 1 G T | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Choose target creature you control | SubAbility$ TrackerFight | StackDescription$ None | SpellDescription$ Target creature you control fights another target creature. -SVar:TrackerFight:DB$ Fight | Defined$ Targeted | ValidTgts$ Creature | TargetUnique$ True | TgtPrompt$ Choose target creature to fight the first target +SVar:TrackerFight:DB$ Fight | Defined$ ParentTarget | ValidTgts$ Creature | TargetUnique$ True | TgtPrompt$ Choose target creature to fight the first target SVar:RemAIDeck:True SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/ulvenwald_tracker.jpg diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index 938279093d6..cf4d63a4fdf 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -6315,13 +6315,11 @@ public class Card extends GameEntity implements Comparable { } } else if (property.equals("TargetedPlayerCtrl")) { for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) { - final SpellAbility parent = sa.getParentTargetingPlayer(); - if (parent.getTarget() != null) { - for (final Object o : parent.getTarget().getTargetPlayers()) { - if (o instanceof Player) { - if (!this.getController().equals(o)) { - return false; - } + final SpellAbility saTargeting = sa.getSATargetingPlayer(); + if (saTargeting != null) { + for (final Player p : saTargeting.getTarget().getTargetPlayers()) { + if (!this.getController().equals(p)) { + return false; } } } @@ -6365,13 +6363,11 @@ public class Card extends GameEntity implements Comparable { } } else if (property.equals("TargetedPlayerOwn")) { for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) { - final SpellAbility parent = sa.getParentTargetingPlayer(); - if (parent.getTarget() != null) { - for (final Object o : parent.getTarget().getTargetPlayers()) { - if (o instanceof Player) { - if (!this.getOwner().equals(o)) { - return false; - } + final SpellAbility saTargeting = sa.getSATargetingPlayer(); + if (saTargeting != null) { + for (final Player p : saTargeting.getTarget().getTargetPlayers()) { + if (!this.getOwner().equals(p)) { + return false; } } } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactory.java b/src/main/java/forge/card/abilityfactory/AbilityFactory.java index b0fdeea7277..470dee09070 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactory.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactory.java @@ -588,25 +588,21 @@ public class AbilityFactory { // Player attribute counting if (calcX[0].startsWith("TargetedPlayer")) { final ArrayList players = new ArrayList(); - final SpellAbility saTargeting = (ability.getTarget() == null) ? ability.getParentTargetingPlayer() : ability; - if (saTargeting.getTarget() != null) { + final SpellAbility saTargeting = ability.getSATargetingPlayer(); + if (null != saTargeting) { players.addAll(saTargeting.getTarget().getTargetPlayers()); - } else { - players.addAll(AbilityFactory.getDefinedPlayers(card, saTargeting.getParam("Defined"), saTargeting)); } return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier; } if (calcX[0].startsWith("TargetedObjects")) { final ArrayList objects = new ArrayList(); - final SpellAbility saTargeting = (ability.getTarget() == null) ? ability.getParentTargetingPlayer() : ability; - if (saTargeting.getTarget() != null) { - SpellAbility loopSA = saTargeting; - while (loopSA != null) { - objects.addAll(saTargeting.getTarget().getTargets()); - loopSA = loopSA.getSubAbility(); + // Make list of all targeted objects starting with the root SpellAbility + SpellAbility loopSA = ability.getRootAbility(); + while (loopSA != null) { + if (loopSA.getTarget() != null) { + objects.addAll(loopSA.getTarget().getTargets()); } - } else { - objects.addAll(AbilityFactory.getDefinedObjects(card, saTargeting.getParam("Defined"), saTargeting)); + loopSA = loopSA.getSubAbility(); } return CardFactoryUtil.objectXCount(objects, calcX[1], card) * multiplier; } @@ -630,9 +626,9 @@ public class AbilityFactory { } return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier; } - if (calcX[0].startsWith("TriggeredPlayer")) { + if (calcX[0].startsWith("TriggeredPlayer") || calcX[0].startsWith("TriggeredTarget")) { final SpellAbility root = ability.getRootAbility(); - Object o = root.getTriggeringObject("Player"); + Object o = root.getTriggeringObject(calcX[0].substring(9)); final ArrayList players = new ArrayList(); if (o instanceof Player) { players.add((Player) o); @@ -664,38 +660,7 @@ public class AbilityFactory { } else if (calcX[0].startsWith("Revealed")) { list = ability.getRootAbility().getPaidList("Revealed"); } else if (calcX[0].startsWith("Targeted")) { - final Target t = ability.getTarget(); - if (null != t) { - final ArrayList all = t.getTargets(); - list = new ArrayList(); - if (!all.isEmpty() && (all.get(0) instanceof SpellAbility)) { - final SpellAbility saTargeting = ability.getParentTargetingSA(); - // possible NPE on next line - final ArrayList sas = saTargeting.getTarget().getTargetSAs(); - for (final SpellAbility sa : sas) { - list.add(sa.getSourceCard()); - } - } else { - final SpellAbility saTargeting = ability.getParentTargetingCard(); - if (null != saTargeting.getTarget()) { - list.addAll(saTargeting.getTarget().getTargetCards()); - } - } - } else { - final SpellAbility parent = ability.getParentTargetingCard(); - if (parent.getTarget() != null) { - final ArrayList all = parent.getTarget().getTargets(); - if (!all.isEmpty() && (all.get(0) instanceof SpellAbility)) { - list = new ArrayList(); - final ArrayList sas = parent.getTarget().getTargetSAs(); - for (final SpellAbility sa : sas) { - list.add(sa.getSourceCard()); - } - } else { - list = new ArrayList(parent.getTarget().getTargetCards()); - } - } - } + list = ability.findTargetedCards(); } else if (calcX[0].startsWith("Triggered")) { final SpellAbility root = ability.getRootAbility(); list = new ArrayList(); @@ -824,8 +789,14 @@ public class AbilityFactory { } else if (defined.equals("Targeted")) { + final SpellAbility saTargeting = sa.getSATargetingCard(); + if (saTargeting != null) { + cards.addAll(saTargeting.getTarget().getTargetCards()); + } + + } else if (defined.equals("ParentTarget")) { final SpellAbility parent = sa.getParentTargetingCard(); - if (parent.getTarget() != null && parent.getTarget().getTargetCards() != null) { + if (parent != null) { cards.addAll(parent.getTarget().getTargetCards()); } @@ -949,9 +920,9 @@ public class AbilityFactory { final String defined = (def == null) ? "You" : def; if (defined.equals("Targeted")) { - final SpellAbility parent = sa.getParentTargetingPlayer(); - if (parent.getTarget() != null) { - players.addAll(parent.getTarget().getTargetPlayers()); + final SpellAbility saTargeting = sa.getSATargetingPlayer(); + if (saTargeting != null) { + players.addAll(saTargeting.getTarget().getTargetPlayers()); } } else if (defined.equals("TargetedController")) { final ArrayList list = AbilityFactory.getDefinedCards(card, "Targeted", sa); @@ -1161,9 +1132,9 @@ public class AbilityFactory { if (defined.equals("Self")) { s = sa; } else if (defined.equals("Targeted")) { - final SpellAbility parent = sa.getParentTargetingSA(); - if (parent.getTarget() != null) { - sas.addAll(parent.getTarget().getTargetSAs()); + final SpellAbility saTargeting = sa.getSATargetingSA(); + if (saTargeting != null) { + sas.addAll(saTargeting.getTarget().getTargetSAs()); } } else if (defined.startsWith("Triggered")) { final SpellAbility root = sa.getRootAbility(); @@ -1516,13 +1487,9 @@ public class AbilityFactory { } else if (type.startsWith("Targeted")) { source = null; - final SpellAbility parent = sa.getParentTargetingCard(); - if (parent.getTarget() != null) { - if (!parent.getTarget().getTargetCards().isEmpty()) { - source = parent.getTarget().getTargetCards().get(0); - } else if (!parent.getTarget().getTargetSAs().isEmpty()) { - source = parent.getTarget().getTargetSAs().get(0).getSourceCard(); - } + ArrayList tgts = sa.findTargetedCards(); + if (!tgts.isEmpty()) { + source = tgts.get(0); } if (source == null) { return new ArrayList(); diff --git a/src/main/java/forge/card/abilityfactory/effects/StoreSVarEffect.java b/src/main/java/forge/card/abilityfactory/effects/StoreSVarEffect.java index 25dcc0e492d..b4607aaddcb 100644 --- a/src/main/java/forge/card/abilityfactory/effects/StoreSVarEffect.java +++ b/src/main/java/forge/card/abilityfactory/effects/StoreSVarEffect.java @@ -49,40 +49,7 @@ public class StoreSVarEffect extends SpellEffect { value = CardFactoryUtil.xCount(source, "SVar$" + expr); } else if (type.equals("Targeted")) { - List list = new ArrayList(); - final Target t = sa.getTarget(); - if (null != t) { - final ArrayList all = t.getTargets(); - list = new ArrayList(); - if (!all.isEmpty() && (all.get(0) instanceof SpellAbility)) { - final SpellAbility saTargeting = sa.getParentTargetingSA(); - // possible NPE on next line - final ArrayList sas = saTargeting.getTarget().getTargetSAs(); - for (final SpellAbility tgtsa : sas) { - list.add(tgtsa.getSourceCard()); - } - } else { - final SpellAbility saTargeting = sa.getParentTargetingCard(); - if (null != saTargeting.getTarget()) { - list.addAll(saTargeting.getTarget().getTargetCards()); - } - } - } else { - final SpellAbility parent = sa.getParentTargetingCard(); - if (parent.getTarget() != null) { - final ArrayList all = parent.getTarget().getTargets(); - if (!all.isEmpty() && (all.get(0) instanceof SpellAbility)) { - list = new ArrayList(); - final ArrayList sas = parent.getTarget().getTargetSAs(); - for (final SpellAbility tgtsa : sas) { - list.add(tgtsa.getSourceCard()); - } - } else { - list = new ArrayList(parent.getTarget().getTargetCards()); - } - } - } - value = CardFactoryUtil.handlePaid(list, expr, source); + value = CardFactoryUtil.handlePaid(sa.findTargetedCards(), expr, source); } //TODO For other types call a different function diff --git a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java index 822bae365b1..205e33603f4 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java @@ -2165,12 +2165,10 @@ public class CardFactoryUtil { // Count$TargetedLifeTotal (targeted player's life total) if (sq[0].contains("TargetedLifeTotal")) { for (final SpellAbility sa : c.getCharacteristics().getSpellAbility()) { - final SpellAbility parent = sa.getParentTargetingPlayer(); - if (parent.getTarget() != null) { - for (final Object tgtP : parent.getTarget().getTargetPlayers()) { - if (tgtP instanceof Player) { - return CardFactoryUtil.doXMath(((Player) tgtP).getLife(), m, c); - } + final SpellAbility saTargeting = sa.getSATargetingPlayer(); + if (saTargeting != null) { + for (final Player tgtP : saTargeting.getTarget().getTargetPlayers()) { + return CardFactoryUtil.doXMath(tgtP.getLife(), m, c); } } } @@ -2608,14 +2606,10 @@ public class CardFactoryUtil { // Count$InTargetedHand (targeted player's cards in hand) if (sq[0].contains("InTargetedHand")) { for (final SpellAbility sa : c.getCharacteristics().getSpellAbility()) { - final SpellAbility parent = sa.getParentTargetingPlayer(); - if (parent != null) { - if (parent.getTarget() != null) { - for (final Object tgtP : parent.getTarget().getTargetPlayers()) { - if (tgtP instanceof Player) { - someCards.addAll(((Player) tgtP).getCardsIn(ZoneType.Hand)); - } - } + final SpellAbility saTargeting = sa.getSATargetingPlayer(); + if (saTargeting != null) { + for (final Player tgtP : saTargeting.getTarget().getTargetPlayers()) { + someCards.addAll(tgtP.getCardsIn(ZoneType.Hand)); } } } diff --git a/src/main/java/forge/card/spellability/SpellAbility.java b/src/main/java/forge/card/spellability/SpellAbility.java index 78f6a2736f1..a41bac87df5 100644 --- a/src/main/java/forge/card/spellability/SpellAbility.java +++ b/src/main/java/forge/card/spellability/SpellAbility.java @@ -1695,36 +1695,110 @@ public abstract class SpellAbility implements ISpellAbility { /** *

- * findParentsTargetedCard. + * findTargetCards. + *

+ * + * @return a {@link forge.card.spellability.SpellAbility} object. + */ + public ArrayList findTargetedCards() { + + ArrayList list = new ArrayList(); + Target tgt = this.getTarget(); + // First search for targeted cards associated with current ability + if (tgt != null && tgt.getTargetCards() != null && !tgt.getTargetCards().isEmpty()) { + return tgt.getTargetCards(); + } + // Next search for source cards of targeted SAs associated with current ability + else if (tgt != null && tgt.getTargetSAs() != null && !tgt.getTargetSAs().isEmpty()) { + for (final SpellAbility ability : tgt.getTargetSAs()) { + list.add(ability.getSourceCard()); + } + return list; + } + // Lastly Search parent SAs for target cards + else { + // Check for a parent that targets a card + SpellAbility parent = this.getParentTargetingCard(); + if (null != parent) { + return parent.getTarget().getTargetCards(); + } + // Check for a parent that targets an SA + parent = this.getParentTargetingSA(); + if (null != parent) { + for (final SpellAbility ability : parent.getTarget().getTargetSAs()) { + list.add(ability.getSourceCard()); + } + } + } + return list; + } + + /** + *

+ * getSATargetingCard. + *

+ * + * @return a {@link forge.card.spellability.SpellAbility} object. + */ + public SpellAbility getSATargetingCard() { + + Target tgt = this.getTarget(); + if (tgt != null && tgt.getTargetCards() != null && !tgt.getTargetCards().isEmpty()) { + return this; + } + else { + return this.getParentTargetingCard(); + } + } + + /** + *

+ * getParentTargetingCard. *

* * @return a {@link forge.card.spellability.SpellAbility} object. */ public SpellAbility getParentTargetingCard() { - SpellAbility parent = this; - - while (parent.getParent() != null) { + SpellAbility parent = this.getParent(); + while (parent != null) { Target tgt = parent.getTarget(); if (tgt != null && tgt.getTargetCards() != null && !tgt.getTargetCards().isEmpty()) { break; } parent = parent.getParent(); - } return parent; } /** *

- * findParentsTargetedSpellAbility. + * getSATargetingSA. + *

+ * + * @return a {@link forge.card.spellability.SpellAbility} object. + */ + public SpellAbility getSATargetingSA() { + Target tgt = this.getTarget(); + if (tgt != null && tgt.getTargetSAs() != null && !tgt.getTargetSAs().isEmpty()) { + return this; + } + else { + return this.getParentTargetingSA(); + } + } + + /** + *

+ * getParentTargetingSA. *

* * @return a {@link forge.card.spellability.SpellAbility} object. */ public SpellAbility getParentTargetingSA() { - SpellAbility parent = this; - while (parent.getParent() != null) { + SpellAbility parent = this.getParent(); + + while (parent != null) { Target tgt = parent.getTarget(); if (tgt != null && tgt.getTargetSAs() != null && !tgt.getTargetSAs().isEmpty()) { @@ -1736,6 +1810,23 @@ public abstract class SpellAbility implements ISpellAbility { return parent; } + /** + *

+ * getSATargetingPlayer. + *

+ * + * @return a {@link forge.card.spellability.SpellAbility} object. + */ + public SpellAbility getSATargetingPlayer() { + Target tgt = this.getTarget(); + if (tgt != null && tgt.getTargetPlayers() != null && !tgt.getTargetPlayers().isEmpty()) { + return this; + } + else { + return this.getParentTargetingPlayer(); + } + } + /** *

* findParentsTargetedPlayer. @@ -1744,8 +1835,8 @@ public abstract class SpellAbility implements ISpellAbility { * @return a {@link forge.card.spellability.SpellAbility} object. */ public SpellAbility getParentTargetingPlayer() { - SpellAbility parent = this; - while (parent.getParent() != null) { + SpellAbility parent = this.getParent(); + while (parent != null) { Target tgt = parent.getTarget(); if (tgt != null && tgt.getTargetPlayers() != null && !tgt.getTargetPlayers().isEmpty()) {