From 25edd60ac5634da9d144ef15ff006eedda6e87cc Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Tue, 18 Jun 2013 08:21:26 +0000 Subject: [PATCH] Using ITargetable instead of Object to return targets of an ability --- .gitattributes | 1 + src/main/java/forge/GameEntity.java | 14 +- src/main/java/forge/ITargetable.java | 7 + .../java/forge/card/ability/AbilityUtils.java | 5 +- .../card/ability/SpellAbilityEffect.java | 3 +- .../java/forge/card/ability/ai/AttachAi.java | 3 +- .../forge/card/ability/ai/ChooseSourceAi.java | 7 +- .../forge/card/ability/ai/DamageDealAi.java | 6 +- .../card/ability/ai/DamagePreventAi.java | 4 +- .../forge/card/ability/ai/UnattachAllAi.java | 4 +- .../card/ability/effects/AttachEffect.java | 5 +- .../ability/effects/ChooseSourceEffect.java | 12 +- .../ability/effects/DamageDealEffect.java | 6 +- .../ability/effects/DamageEachEffect.java | 4 +- .../ability/effects/DamagePreventEffect.java | 5 +- .../ability/effects/UnattachAllEffect.java | 5 +- .../spellability/HumanPlaySpellAbility.java | 4 +- .../forge/card/spellability/SpellAbility.java | 387 +++++++++--------- .../java/forge/card/spellability/Target.java | 7 +- .../card/spellability/TargetChoices.java | 9 +- .../card/spellability/TargetSelection.java | 3 +- src/main/java/forge/game/ai/ComputerUtil.java | 7 +- src/main/java/forge/game/zone/MagicStack.java | 3 +- 23 files changed, 269 insertions(+), 242 deletions(-) create mode 100644 src/main/java/forge/ITargetable.java diff --git a/.gitattributes b/.gitattributes index 77359793958..33cda89881a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13994,6 +13994,7 @@ src/main/java/forge/GameLog.java -text src/main/java/forge/GameLogEntry.java -text src/main/java/forge/GameLogEntryType.java -text src/main/java/forge/GameLogFormatter.java -text +src/main/java/forge/ITargetable.java -text src/main/java/forge/ImageCache.java svneol=native#text/plain src/main/java/forge/ImageLoader.java -text src/main/java/forge/Singletons.java svneol=native#text/plain diff --git a/src/main/java/forge/GameEntity.java b/src/main/java/forge/GameEntity.java index 0906cc13a13..c2e6043f9a8 100644 --- a/src/main/java/forge/GameEntity.java +++ b/src/main/java/forge/GameEntity.java @@ -19,7 +19,6 @@ package forge; import java.util.ArrayList; -import forge.card.spellability.SpellAbility; import forge.game.Game; import forge.game.player.Player; import forge.util.MyObservable; @@ -32,7 +31,7 @@ import forge.util.MyObservable; * @author Forge * @version $Id: Player.java 10091 2011-08-30 16:11:21Z Sloth $ */ -public abstract class GameEntity extends MyObservable { +public abstract class GameEntity extends MyObservable implements ITargetable { private String name = ""; private int preventNextDamage = 0; @@ -267,17 +266,6 @@ public abstract class GameEntity extends MyObservable { return false; } - /** - * Can target. - * - * @param sa - * the sa - * @return a boolean - */ - public boolean canBeTargetedBy(final SpellAbility sa) { - return false; - } - /** * Checks if is valid. * diff --git a/src/main/java/forge/ITargetable.java b/src/main/java/forge/ITargetable.java new file mode 100644 index 00000000000..f851cd96825 --- /dev/null +++ b/src/main/java/forge/ITargetable.java @@ -0,0 +1,7 @@ +package forge; + +import forge.card.spellability.SpellAbility; + +public interface ITargetable { + boolean canBeTargetedBy(final SpellAbility sa); +} \ No newline at end of file diff --git a/src/main/java/forge/card/ability/AbilityUtils.java b/src/main/java/forge/card/ability/AbilityUtils.java index f29697ac049..810584984bf 100644 --- a/src/main/java/forge/card/ability/AbilityUtils.java +++ b/src/main/java/forge/card/ability/AbilityUtils.java @@ -14,6 +14,7 @@ import forge.CardLists; import forge.CardUtil; import forge.Constant; import forge.CounterType; +import forge.ITargetable; import forge.card.cardfactory.CardFactoryUtil; import forge.card.cost.Cost; import forge.card.mana.ManaCostBeingPaid; @@ -571,8 +572,8 @@ public class AbilityUtils { * a {@link forge.card.spellability.SpellAbility} object. * @return a {@link java.util.ArrayList} object. */ - public static ArrayList getDefinedObjects(final Card card, final String def, final SpellAbility sa) { - final ArrayList objects = new ArrayList(); + public static List getDefinedObjects(final Card card, final String def, final SpellAbility sa) { + final ArrayList objects = new ArrayList(); final String defined = (def == null) ? "Self" : def; objects.addAll(AbilityUtils.getDefinedPlayers(card, defined, sa)); diff --git a/src/main/java/forge/card/ability/SpellAbilityEffect.java b/src/main/java/forge/card/ability/SpellAbilityEffect.java index 78fe16a4c41..a98e6258e2c 100644 --- a/src/main/java/forge/card/ability/SpellAbilityEffect.java +++ b/src/main/java/forge/card/ability/SpellAbilityEffect.java @@ -9,6 +9,7 @@ import java.util.StringTokenizer; import org.apache.commons.lang3.StringUtils; import forge.Card; +import forge.ITargetable; import forge.card.cardfactory.CardFactoryUtil; import forge.card.spellability.AbilitySub; import forge.card.spellability.SpellAbility; @@ -162,7 +163,7 @@ import forge.game.player.Player; return tgt != null ? tgt.getTargetSAs() : AbilityUtils.getDefinedSpellAbilities(sa.getSourceCard(), sa.getParam("Defined"), sa); } - protected List getTargetObjects(SpellAbility sa) { + protected List getTargetObjects(SpellAbility sa) { final Target tgt = sa.getTarget(); return tgt != null ? tgt.getTargets() : AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam("Defined"), sa); } diff --git a/src/main/java/forge/card/ability/ai/AttachAi.java b/src/main/java/forge/card/ability/ai/AttachAi.java index 313b07f115c..46a59f3af85 100644 --- a/src/main/java/forge/card/ability/ai/AttachAi.java +++ b/src/main/java/forge/card/ability/ai/AttachAi.java @@ -14,6 +14,7 @@ import forge.Card; import forge.CardLists; import forge.CardPredicates; import forge.CardUtil; +import forge.ITargetable; import forge.card.ability.AbilityUtils; import forge.card.ability.ApiType; import forge.card.ability.SpellAbilityAi; @@ -611,7 +612,7 @@ public class AttachAi extends SpellAbilityAi { protected boolean doTriggerAINoCost(final Player ai, final SpellAbility sa, final boolean mandatory) { final Card card = sa.getSourceCard(); // Check if there are any valid targets - ArrayList targets = new ArrayList(); + List targets = new ArrayList(); final Target tgt = sa.getTarget(); if (tgt == null) { targets = AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam("Defined"), sa); diff --git a/src/main/java/forge/card/ability/ai/ChooseSourceAi.java b/src/main/java/forge/card/ability/ai/ChooseSourceAi.java index 148b84ac7fe..fe23c790cc4 100644 --- a/src/main/java/forge/card/ability/ai/ChooseSourceAi.java +++ b/src/main/java/forge/card/ability/ai/ChooseSourceAi.java @@ -7,6 +7,7 @@ import com.google.common.base.Predicate; import forge.Card; import forge.CardLists; +import forge.ITargetable; import forge.card.ability.AbilityUtils; import forge.card.ability.ApiType; import forge.card.ability.SpellAbilityAi; @@ -78,17 +79,17 @@ public class ChooseSourceAi extends SpellAbilityAi { } final Card threatSource = topStack.getSourceCard(); - ArrayList objects = new ArrayList(); + List objects = new ArrayList(); final Target threatTgt = topStack.getTarget(); if (threatTgt == null) { if (topStack.hasParam("Defined")) { objects = AbilityUtils.getDefinedObjects(threatSource, topStack.getParam("Defined"), topStack); } else if (topStack.hasParam("ValidPlayers")) { - objects.addAll(AbilityUtils.getDefinedPlayers(threatSource, topStack.getParam("ValidPlayers"), topStack)); + objects = AbilityUtils.getDefinedPlayers(threatSource, topStack.getParam("ValidPlayers"), topStack); } } else { - objects.addAll(threatTgt.getTargetPlayers()); + objects = threatTgt.getTargetPlayers(); } if (!objects.contains(ai) || topStack.hasParam("NoPrevention")) { return false; diff --git a/src/main/java/forge/card/ability/ai/DamageDealAi.java b/src/main/java/forge/card/ability/ai/DamageDealAi.java index ac2c0a48154..26723aedd75 100644 --- a/src/main/java/forge/card/ability/ai/DamageDealAi.java +++ b/src/main/java/forge/card/ability/ai/DamageDealAi.java @@ -1,6 +1,5 @@ package forge.card.ability.ai; -import java.util.ArrayList; import java.util.List; import java.util.Random; @@ -8,6 +7,7 @@ import com.google.common.base.Predicate; import forge.Card; import forge.CardLists; +import forge.ITargetable; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; @@ -146,7 +146,7 @@ public class DamageDealAi extends DamageAiBase { final Card source = saMe.getSourceCard(); List hPlay = CardLists.getValidCards(pl.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, source); - final ArrayList objects = tgt.getTargets(); + final List objects = tgt.getTargets(); if (saMe.hasParam("TargetUnique")) { objects.addAll(saMe.getUniqueTargets()); } @@ -359,7 +359,7 @@ public class DamageDealAi extends DamageAiBase { */ private boolean damageChooseNontargeted(Player ai, final SpellAbility saMe, final int dmg) { // TODO: Improve circumstances where the Defined Damage is unwanted - final ArrayList objects = AbilityUtils.getDefinedObjects(saMe.getSourceCard(), saMe.getParam("Defined"), saMe); + final List objects = AbilityUtils.getDefinedObjects(saMe.getSourceCard(), saMe.getParam("Defined"), saMe); boolean urgent = false; // can it wait? boolean positive = false; diff --git a/src/main/java/forge/card/ability/ai/DamagePreventAi.java b/src/main/java/forge/card/ability/ai/DamagePreventAi.java index ac47a6a454a..7df9f7ad0d3 100644 --- a/src/main/java/forge/card/ability/ai/DamagePreventAi.java +++ b/src/main/java/forge/card/ability/ai/DamagePreventAi.java @@ -6,6 +6,7 @@ import java.util.List; import forge.Card; import forge.CardLists; import forge.CardPredicates; +import forge.ITargetable; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; @@ -52,8 +53,7 @@ public class DamagePreventAi extends SpellAbilityAi { if (tgt == null) { // As far as I can tell these Defined Cards will only have one of // them - final ArrayList objects = AbilityUtils.getDefinedObjects(sa.getSourceCard(), - sa.getParam("Defined"), sa); + final List objects = AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam("Defined"), sa); // react to threats on the stack if (!game.getStack().isEmpty()) { diff --git a/src/main/java/forge/card/ability/ai/UnattachAllAi.java b/src/main/java/forge/card/ability/ai/UnattachAllAi.java index 0adeb287f6f..b398379152d 100644 --- a/src/main/java/forge/card/ability/ai/UnattachAllAi.java +++ b/src/main/java/forge/card/ability/ai/UnattachAllAi.java @@ -1,9 +1,11 @@ package forge.card.ability.ai; import java.util.ArrayList; +import java.util.List; import java.util.Random; import forge.Card; +import forge.ITargetable; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; @@ -66,7 +68,7 @@ public class UnattachAllAi extends SpellAbilityAi { final Card card = sa.getSourceCard(); final Player opp = ai.getOpponent(); // Check if there are any valid targets - ArrayList targets = new ArrayList(); + List targets = new ArrayList(); final Target tgt = sa.getTarget(); if (tgt == null) { targets = AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam("Defined"), sa); diff --git a/src/main/java/forge/card/ability/effects/AttachEffect.java b/src/main/java/forge/card/ability/effects/AttachEffect.java index d4515f69232..19bbb708e5a 100644 --- a/src/main/java/forge/card/ability/effects/AttachEffect.java +++ b/src/main/java/forge/card/ability/effects/AttachEffect.java @@ -7,6 +7,7 @@ import forge.Card; import forge.CardLists; import forge.Command; import forge.GameEntity; +import forge.ITargetable; import forge.card.ability.AbilityUtils; import forge.card.ability.ApiType; import forge.card.ability.SpellAbilityEffect; @@ -37,7 +38,7 @@ public class AttachEffect extends SpellAbilityEffect { Card source = sa.getSourceCard(); Card card = sa.getSourceCard(); - final List targets = getTargetObjects(sa); + final List targets = getTargetObjects(sa); if (sa.hasParam("Object")) { card = AbilityUtils.getDefinedCards(source, sa.getParam("Object"), sa).get(0); @@ -60,7 +61,7 @@ public class AttachEffect extends SpellAbilityEffect { sb.append(" Attach to "); - final List targets = getTargetObjects(sa); + final List targets = getTargetObjects(sa); // Should never allow more than one Attachment per card for (final Object o : targets) { diff --git a/src/main/java/forge/card/ability/effects/ChooseSourceEffect.java b/src/main/java/forge/card/ability/effects/ChooseSourceEffect.java index e087892f5a1..3e3cdf8152c 100644 --- a/src/main/java/forge/card/ability/effects/ChooseSourceEffect.java +++ b/src/main/java/forge/card/ability/effects/ChooseSourceEffect.java @@ -5,9 +5,11 @@ import java.util.List; import org.apache.commons.lang3.StringUtils; import com.google.common.base.Predicate; +import com.google.common.collect.Lists; import forge.Card; import forge.CardLists; +import forge.ITargetable; import forge.card.ability.AbilityUtils; import forge.card.ability.ApiType; import forge.card.ability.SpellAbilityEffect; @@ -188,18 +190,20 @@ public class ChooseSourceEffect extends SpellAbilityEffect { } - ArrayList objects = new ArrayList(); + final List objects; final Target threatTgt = abilityOnStack.getTarget(); if (threatTgt == null) { if (abilityOnStack.hasParam("Defined")) { objects = AbilityUtils.getDefinedObjects(source, abilityOnStack.getParam("Defined"), abilityOnStack); } else if (abilityOnStack.hasParam("ValidPlayers")) { - objects.addAll(AbilityUtils.getDefinedPlayers(source, abilityOnStack.getParam("ValidPlayers"), abilityOnStack)); - } + objects = AbilityUtils.getDefinedPlayers(source, abilityOnStack.getParam("ValidPlayers"), abilityOnStack); + } else + objects = Lists.newArrayList(); } else { - objects.addAll(threatTgt.getTargetPlayers()); + objects = threatTgt.getTargetPlayers(); } + if (!objects.contains(ai) || abilityOnStack.hasParam("NoPrevention")) { continue; } diff --git a/src/main/java/forge/card/ability/effects/DamageDealEffect.java b/src/main/java/forge/card/ability/effects/DamageDealEffect.java index fc7f1674ab4..5a4efbb7d46 100644 --- a/src/main/java/forge/card/ability/effects/DamageDealEffect.java +++ b/src/main/java/forge/card/ability/effects/DamageDealEffect.java @@ -1,11 +1,11 @@ package forge.card.ability.effects; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import forge.Card; import forge.CardUtil; +import forge.ITargetable; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; @@ -25,7 +25,7 @@ public class DamageDealEffect extends SpellAbilityEffect { final int dmg = AbilityUtils.calculateAmount(sa.getSourceCard(), damage, sa); - List tgts = getTargetObjects(sa); + List tgts = getTargetObjects(sa); if (tgts.isEmpty()) return ""; @@ -73,7 +73,7 @@ public class DamageDealEffect extends SpellAbilityEffect { final boolean combatDmg = sa.hasParam("CombatDamage"); final boolean removeDamage = sa.hasParam("Remove"); - ArrayList tgts; + List tgts; if (sa.getTarget() == null) { tgts = AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam("Defined"), sa) ; } else { diff --git a/src/main/java/forge/card/ability/effects/DamageEachEffect.java b/src/main/java/forge/card/ability/effects/DamageEachEffect.java index cb307f27443..bc4f6208dd8 100644 --- a/src/main/java/forge/card/ability/effects/DamageEachEffect.java +++ b/src/main/java/forge/card/ability/effects/DamageEachEffect.java @@ -1,10 +1,10 @@ package forge.card.ability.effects; -import java.util.ArrayList; import java.util.List; import forge.Card; import forge.CardLists; +import forge.ITargetable; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.cardfactory.CardFactoryUtil; @@ -65,7 +65,7 @@ public class DamageEachEffect extends SpellAbilityEffect { sources = CardLists.getValidCards(sources, sa.getParam("ValidCards"), card.getController(), card); } - ArrayList tgts = new ArrayList(); + final List tgts; if (sa.getTarget() == null) { tgts = AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam("DefinedPlayers"), sa); } else { diff --git a/src/main/java/forge/card/ability/effects/DamagePreventEffect.java b/src/main/java/forge/card/ability/effects/DamagePreventEffect.java index a5780c4f9c5..78f9f7f8869 100644 --- a/src/main/java/forge/card/ability/effects/DamagePreventEffect.java +++ b/src/main/java/forge/card/ability/effects/DamagePreventEffect.java @@ -5,6 +5,7 @@ import java.util.List; import forge.Card; import forge.CardUtil; +import forge.ITargetable; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; @@ -16,7 +17,7 @@ public class DamagePreventEffect extends SpellAbilityEffect { protected String getStackDescription(SpellAbility sa) { final StringBuilder sb = new StringBuilder(); - final List tgts = getTargetObjects(sa); + final List tgts = getTargetObjects(sa); sb.append("Prevent the next "); sb.append(sa.getParam("Amount")); @@ -65,7 +66,7 @@ public class DamagePreventEffect extends SpellAbilityEffect { Card host = sa.getSourceCard(); int numDam = AbilityUtils.calculateAmount(host, sa.getParam("Amount"), sa); - ArrayList tgts; + final List tgts; final ArrayList untargetedCards = new ArrayList(); if (sa.getTarget() == null) { tgts = AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam("Defined"), sa); diff --git a/src/main/java/forge/card/ability/effects/UnattachAllEffect.java b/src/main/java/forge/card/ability/effects/UnattachAllEffect.java index 1c438aebaee..eaae52e172f 100644 --- a/src/main/java/forge/card/ability/effects/UnattachAllEffect.java +++ b/src/main/java/forge/card/ability/effects/UnattachAllEffect.java @@ -7,6 +7,7 @@ import org.apache.commons.lang3.StringUtils; import forge.Card; import forge.CardLists; import forge.GameEntity; +import forge.ITargetable; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; import forge.game.Game; @@ -142,7 +143,7 @@ public class UnattachAllEffect extends SpellAbilityEffect { protected String getStackDescription(SpellAbility sa) { final StringBuilder sb = new StringBuilder(); sb.append("Unattach all valid Equipment and Auras from "); - final List targets = getTargetObjects(sa); + final List targets = getTargetObjects(sa); sb.append(StringUtils.join(targets, " ")); return sb.toString(); } @@ -154,7 +155,7 @@ public class UnattachAllEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { Card source = sa.getSourceCard(); final Game game = sa.getActivatingPlayer().getGame(); - final List targets = getTargetObjects(sa); + final List targets = getTargetObjects(sa); // If Cast Targets will be checked on the Stack for (final Object o : targets) { diff --git a/src/main/java/forge/card/spellability/HumanPlaySpellAbility.java b/src/main/java/forge/card/spellability/HumanPlaySpellAbility.java index 3422e629950..0511aafb84a 100644 --- a/src/main/java/forge/card/spellability/HumanPlaySpellAbility.java +++ b/src/main/java/forge/card/spellability/HumanPlaySpellAbility.java @@ -18,11 +18,13 @@ package forge.card.spellability; import java.util.ArrayList; +import java.util.List; import org.apache.commons.lang3.StringUtils; import forge.Card; import forge.CardCharacteristicName; +import forge.ITargetable; import forge.card.CardType; import forge.card.ability.AbilityUtils; import forge.card.cost.CostPartMana; @@ -202,7 +204,7 @@ public class HumanPlaySpellAbility { final StringBuilder sb = new StringBuilder(); sb.append(ability.getSourceCard().getName()); if (ability.getTarget() != null) { - final ArrayList targets = ability.getTarget().getTargets(); + final List targets = ability.getTarget().getTargets(); if (targets.size() > 0) { sb.append(" - Targeting "); for (final Object o : targets) { diff --git a/src/main/java/forge/card/spellability/SpellAbility.java b/src/main/java/forge/card/spellability/SpellAbility.java index 702268195b2..d9240a62825 100644 --- a/src/main/java/forge/card/spellability/SpellAbility.java +++ b/src/main/java/forge/card/spellability/SpellAbility.java @@ -28,6 +28,7 @@ import org.apache.commons.lang3.StringUtils; import forge.Card; import forge.GameEntity; +import forge.ITargetable; import forge.card.ability.AbilityUtils; import forge.card.ability.ApiType; import forge.card.cost.Cost; @@ -48,7 +49,7 @@ import forge.util.TextUtil; * @author Forge * @version $Id$ */ -public abstract class SpellAbility implements ISpellAbility { +public abstract class SpellAbility implements ISpellAbility, ITargetable { // choices for constructor isPermanent argument private String description = ""; @@ -890,79 +891,6 @@ public abstract class SpellAbility implements ISpellAbility { return this.subAbility; } - /** - *

- * Getter for the field targetCard. - *

- * - * @return a {@link forge.Card} object. - */ - public Card getTargetCard() { - if (this.targetCard == null) { - final Target tgt = this.getTarget(); - if (tgt != null) { - final List list = tgt.getTargetCards(); - - if (!list.isEmpty()) { - return list.get(0); - } - } - return null; - } - - return this.targetCard; - } - - /** - *

- * Setter for the field targetCard. - *

- * - * @param card - * a {@link forge.Card} object. - */ - public void setTargetCard(final Card card) { - if (card == null) { - System.out.println(this.getSourceCard() - + " - SpellAbility.setTargetCard() called with null for target card."); - return; - } - - final Target tgt = this.getTarget(); - if (tgt != null) { - tgt.addTarget(card); - } else { - this.targetCard = card; - } - String desc = ""; - - if (!card.isFaceDown()) { - desc = this.getSourceCard().getName() + " - targeting " + card; - } else { - desc = this.getSourceCard().getName() + " - targeting Morph(" + card.getUniqueNumber() + ")"; - } - this.setStackDescription(desc); - } - - /** - *

- * Getter for the field targetPlayer. - *

- * - * @return a {@link forge.game.player.Player} object. - */ - public Player getTargetPlayer() { - final Target tgt = this.getTarget(); - if (tgt != null) { - final List list = tgt.getTargetPlayers(); - - if (!list.isEmpty()) { - return list.get(0); - } - } - return null; - } - /** *

* isBasicAbility. @@ -1211,25 +1139,6 @@ public abstract class SpellAbility implements ISpellAbility { this.delve = isDelve0; } - /** - * Gets the chosen target. - * - * @return the chosenTarget - */ - public Target getChosenTarget() { - return this.chosenTarget; - } - - /** - * Sets the chosen target. - * - * @param chosenTarget0 - * the chosenTarget to set - */ - public void setChosenTarget(final Target chosenTarget0) { - this.chosenTarget = chosenTarget0; - } - /** * Adds the tapped for convoke. * @@ -1368,6 +1277,178 @@ public abstract class SpellAbility implements ISpellAbility { return null; } + /** + * TODO: Write javadoc for this method. + * @return + */ + public boolean isUndoable() { + return this.undoable && this.payCosts.isUndoable() && this.getSourceCard().isInPlay(); + } + + /** + * TODO: Write javadoc for this method. + */ + public void undo() { + if (isUndoable()) { + this.payCosts.refundPaidCost(sourceCard); + } + } + + /** + * TODO: Write javadoc for this method. + * @param b + */ + public void setUndoable(boolean b) { + this.undoable = b; + } + + /** + * @return the isCopied + */ + public boolean isCopied() { + return isCopied; + } + + /** + * @param isCopied0 the isCopied to set + */ + public void setCopied(boolean isCopied0) { + this.isCopied = isCopied0; + } + + /** + * Returns whether variable was present in the announce list. + */ + public boolean isAnnouncing(String variable) { + String announce = getParam("Announce"); + if (StringUtils.isBlank(announce)) return false; + String[] announcedOnes = TextUtil.split(announce, ','); + for(String a : announcedOnes) { + if( a.trim().equalsIgnoreCase(variable)) + return true; + } + return false; + } + + public boolean isXCost() { + CostPartMana cm = payCosts != null ? getPayCosts().getCostMana() : null; + return cm != null && cm.getAmountOfX() > 0; + } + + public boolean isBasicLandAbility() { + return basicLandAbility; + } + + public void setBasicLandAbility(boolean basicLandAbility) { + this.basicLandAbility = basicLandAbility; // TODO: Add 0 to parameter's name. + } + + public boolean isTemporary() { + return temporary; + } + + 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 + // + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + *

+ * Getter for the field targetCard. + *

+ * + * @return a {@link forge.Card} object. + */ + public Card getTargetCard() { + if (this.targetCard == null) { + final Target tgt = this.getTarget(); + if (tgt != null) { + final List list = tgt.getTargetCards(); + + if (!list.isEmpty()) { + return list.get(0); + } + } + return null; + } + + return this.targetCard; + } + + /** + *

+ * Setter for the field targetCard. + *

+ * + * @param card + * a {@link forge.Card} object. + */ + public void setTargetCard(final Card card) { + if (card == null) { + System.out.println(this.getSourceCard() + + " - SpellAbility.setTargetCard() called with null for target card."); + return; + } + + final Target tgt = this.getTarget(); + if (tgt != null) { + tgt.addTarget(card); + } else { + this.targetCard = card; + } + String desc = ""; + + if (!card.isFaceDown()) { + desc = this.getSourceCard().getName() + " - targeting " + card; + } else { + desc = this.getSourceCard().getName() + " - targeting Morph(" + card.getUniqueNumber() + ")"; + } + this.setStackDescription(desc); + } + + /** + *

+ * Getter for the field targetPlayer. + *

+ * + * @return a {@link forge.game.player.Player} object. + */ + public Player getTargetPlayer() { + final Target tgt = this.getTarget(); + if (tgt != null) { + final List list = tgt.getTargetPlayers(); + + if (!list.isEmpty()) { + return list.get(0); + } + } + return null; + } + + /** + * Gets the chosen target. + * + * @return the chosenTarget + */ + public Target getChosenTarget() { + return this.chosenTarget; + } + + /** + * Sets the chosen target. + * + * @param chosenTarget0 + * the chosenTarget to set + */ + public void setChosenTarget(final Target chosenTarget0) { + this.chosenTarget = chosenTarget0; + } + /** *

* findTargetCards. @@ -1415,7 +1496,7 @@ public abstract class SpellAbility implements ISpellAbility { * @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; @@ -1434,7 +1515,7 @@ public abstract class SpellAbility implements ISpellAbility { */ public SpellAbility getParentTargetingCard() { SpellAbility parent = this.getParent(); - + while (parent != null) { Target tgt = parent.getTarget(); if (tgt != null && tgt.getTargetCards() != null && !tgt.getTargetCards().isEmpty()) { @@ -1471,15 +1552,15 @@ public abstract class SpellAbility implements ISpellAbility { */ public SpellAbility getParentTargetingSA() { SpellAbility parent = this.getParent(); - + while (parent != null) { - + Target tgt = parent.getTarget(); if (tgt != null && tgt.getTargetSAs() != null && !tgt.getTargetSAs().isEmpty()) { break; } parent = parent.getParent(); - + } return parent; } @@ -1511,56 +1592,17 @@ public abstract class SpellAbility implements ISpellAbility { public SpellAbility getParentTargetingPlayer() { SpellAbility parent = this.getParent(); while (parent != null) { - + Target tgt = parent.getTarget(); if (tgt != null && tgt.getTargetPlayers() != null && !tgt.getTargetPlayers().isEmpty()) { break; } parent = parent.getParent(); - + } return parent; } - /** - * TODO: Write javadoc for this method. - * @return - */ - public boolean isUndoable() { - return this.undoable && this.payCosts.isUndoable() && this.getSourceCard().isInPlay(); - } - - /** - * TODO: Write javadoc for this method. - */ - public void undo() { - if (isUndoable()) { - this.payCosts.refundPaidCost(sourceCard); - } - } - - /** - * TODO: Write javadoc for this method. - * @param b - */ - public void setUndoable(boolean b) { - this.undoable = b; - } - - /** - * @return the isCopied - */ - public boolean isCopied() { - return isCopied; - } - - /** - * @param isCopied0 the isCopied to set - */ - public void setCopied(boolean isCopied0) { - this.isCopied = isCopied0; - } - /** * Gets the unique targets. * @@ -1568,8 +1610,8 @@ public abstract class SpellAbility implements ISpellAbility { * the ability * @return the unique targets */ - public final List getUniqueTargets() { - final List targets = new ArrayList(); + public final List getUniqueTargets() { + final List targets = new ArrayList(); SpellAbility child = this.getParent(); while (child != null) { if (child.getTarget() != null) { @@ -1579,11 +1621,16 @@ public abstract class SpellAbility implements ISpellAbility { } return targets; } + + @Override + public boolean canBeTargetedBy(SpellAbility sa) { + return sa.canBeTargetedBy(this); + } public boolean canTargetSpellAbility(final SpellAbility topSA) { final Target tgt = this.getTarget(); final String saType = tgt.getTargetSpellAbilityType(); - + if (null == saType) { // just take this to mean no restrictions - carry on. } else if (topSA instanceof Spell) { @@ -1601,31 +1648,31 @@ public abstract class SpellAbility implements ISpellAbility { } else { return false; //Static ability? Whatever. } - + final String splitTargetRestrictions = tgt.getSAValidTargeting(); if (splitTargetRestrictions != null) { // TODO What about spells with SubAbilities with Targets? - + final Target matchTgt = topSA.getTarget(); - + if (matchTgt == null) { return false; } - + boolean result = false; - + for (final Object o : matchTgt.getTargets()) { if (matchesValid(o, splitTargetRestrictions.split(","))) { result = true; break; } } - + if (!result) { return false; } } - + if (tgt.isSingleTarget()) { final ArrayList choices = topSA.getAllTargetChoices(); int totalTargets = 0; @@ -1641,11 +1688,10 @@ public abstract class SpellAbility implements ISpellAbility { return false; } } - + return topSA.getSourceCard().isValid(tgt.getValidTgts(), this.getActivatingPlayer(), this.getSourceCard()); } - private boolean matchesValid(final Object o, final String[] valids) { final Card srcCard = this.getSourceCard(); final Player activatingPlayer = this.getActivatingPlayer(); @@ -1653,49 +1699,14 @@ public abstract class SpellAbility implements ISpellAbility { final Card c = (Card) o; return c.isValid(valids, activatingPlayer, srcCard); } - + if (o instanceof Player) { Player p = (Player) o; if (p.isValid(valids, activatingPlayer, srcCard)) { return true; } } - + return false; } - - /** - * Returns whether variable was present in the announce list. - */ - public boolean isAnnouncing(String variable) { - String announce = getParam("Announce"); - if (StringUtils.isBlank(announce)) return false; - String[] announcedOnes = TextUtil.split(announce, ','); - for(String a : announcedOnes) { - if( a.trim().equalsIgnoreCase(variable)) - return true; - } - return false; - } - - public boolean isXCost() { - CostPartMana cm = payCosts != null ? getPayCosts().getCostMana() : null; - return cm != null && cm.getAmountOfX() > 0; - } - - public boolean isBasicLandAbility() { - return basicLandAbility; - } - - public void setBasicLandAbility(boolean basicLandAbility) { - this.basicLandAbility = basicLandAbility; // TODO: Add 0 to parameter's name. - } - - public boolean isTemporary() { - return temporary; - } - - public void setTemporary(boolean temporary) { - this.temporary = temporary; // TODO: Add 0 to parameter's name. - } } diff --git a/src/main/java/forge/card/spellability/Target.java b/src/main/java/forge/card/spellability/Target.java index 344f738c69b..1e488c7941f 100644 --- a/src/main/java/forge/card/spellability/Target.java +++ b/src/main/java/forge/card/spellability/Target.java @@ -23,6 +23,7 @@ import java.util.HashMap; import java.util.List; import forge.Card; +import forge.ITargetable; import forge.card.CardType; import forge.card.ability.AbilityUtils; import forge.game.Game; @@ -518,9 +519,9 @@ public class Target { * * @return a {@link java.util.ArrayList} object. */ - public final ArrayList getTargets() { + public final List getTargets() { if (this.choice == null) { - return new ArrayList(); + return new ArrayList(); } return this.choice.getTargets(); @@ -557,7 +558,7 @@ public class Target { * @return a {@link java.lang.String} object. */ public final String getTargetedString() { - final ArrayList tgts = this.getTargets(); + final List tgts = this.getTargets(); final StringBuilder sb = new StringBuilder(""); for (final Object o : tgts) { if (o instanceof Player) { diff --git a/src/main/java/forge/card/spellability/TargetChoices.java b/src/main/java/forge/card/spellability/TargetChoices.java index ae81a496d63..5bf4cbb1772 100644 --- a/src/main/java/forge/card/spellability/TargetChoices.java +++ b/src/main/java/forge/card/spellability/TargetChoices.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.List; import forge.Card; +import forge.ITargetable; import forge.game.player.Player; /** @@ -233,8 +234,8 @@ public class TargetChoices { * * @return a {@link java.util.ArrayList} object. */ - public final ArrayList getTargets() { - final ArrayList tgts = new ArrayList(); + public final List getTargets() { + final ArrayList tgts = new ArrayList(); tgts.addAll(this.targetPlayers); tgts.addAll(this.targetCards); tgts.addAll(this.targetSAs); @@ -250,8 +251,8 @@ public class TargetChoices { * @return a {@link java.lang.String} object. */ public final String getTargetedString() { - final ArrayList tgts = this.getTargets(); - final StringBuilder sb = new StringBuilder(""); + final List tgts = this.getTargets(); + final StringBuilder sb = new StringBuilder(); for (final Object o : tgts) { if (o instanceof Player) { final Player p = (Player) o; diff --git a/src/main/java/forge/card/spellability/TargetSelection.java b/src/main/java/forge/card/spellability/TargetSelection.java index d86d03b6937..808b1bfd8ae 100644 --- a/src/main/java/forge/card/spellability/TargetSelection.java +++ b/src/main/java/forge/card/spellability/TargetSelection.java @@ -24,6 +24,7 @@ import com.google.common.base.Predicate; import forge.Card; import forge.CardLists; +import forge.ITargetable; import forge.Singletons; import forge.card.ability.AbilityUtils; import forge.game.Game; @@ -151,7 +152,7 @@ public class TargetSelection { choices.remove(tgt.getSourceCard()); } } - List targetedObjects = this.ability.getUniqueTargets(); + List targetedObjects = this.ability.getUniqueTargets(); if (tgt.isUniqueTargets()) { for (final Object o : targetedObjects) { diff --git a/src/main/java/forge/game/ai/ComputerUtil.java b/src/main/java/forge/game/ai/ComputerUtil.java index 8ed2a7a3d7b..352a9002906 100644 --- a/src/main/java/forge/game/ai/ComputerUtil.java +++ b/src/main/java/forge/game/ai/ComputerUtil.java @@ -33,6 +33,7 @@ import forge.CardPredicates; import forge.Constant; import forge.CardPredicates.Presets; import forge.CardUtil; +import forge.ITargetable; import forge.card.CardType; import forge.card.MagicColor; import forge.card.ability.AbilityUtils; @@ -1287,10 +1288,10 @@ public class ComputerUtil { * @return a {@link java.util.ArrayList} object. * @since 1.0.15 */ - public static ArrayList predictThreatenedObjects(final Player aiPlayer, final SpellAbility saviour, + public static List predictThreatenedObjects(final Player aiPlayer, final SpellAbility saviour, final SpellAbility topStack) { - ArrayList objects = new ArrayList(); - final ArrayList threatened = new ArrayList(); + List objects = new ArrayList(); + final List threatened = new ArrayList(); ApiType saviourApi = saviour.getApi(); if (topStack == null) { diff --git a/src/main/java/forge/game/zone/MagicStack.java b/src/main/java/forge/game/zone/MagicStack.java index 43728b0e7e6..e8845b6cb11 100644 --- a/src/main/java/forge/game/zone/MagicStack.java +++ b/src/main/java/forge/game/zone/MagicStack.java @@ -35,6 +35,7 @@ import forge.CardLists; import forge.CardPredicates; import forge.Command; import forge.FThreads; +import forge.ITargetable; import forge.Singletons; import forge.CardPredicates.Presets; import forge.GameLogEntryType; @@ -679,7 +680,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable tgts = tgt.getTargets(); + final List tgts = tgt.getTargets(); final TargetChoices choices = tgt.getTargetChoices(); for (final Object o : tgts) { boolean invalidTarget = false;