diff --git a/.gitattributes b/.gitattributes index 33cda89881a..d25d74d3c5d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14035,6 +14035,7 @@ src/main/java/forge/card/ability/AbilityApiBased.java -text src/main/java/forge/card/ability/AbilityFactory.java svneol=native#text/plain src/main/java/forge/card/ability/AbilityUtils.java -text src/main/java/forge/card/ability/ApiType.java -text +src/main/java/forge/card/ability/SaTargetRountines.java -text src/main/java/forge/card/ability/SpellAbilityAi.java -text src/main/java/forge/card/ability/SpellAbilityEffect.java -text src/main/java/forge/card/ability/SpellApiBased.java -text @@ -14324,8 +14325,8 @@ src/main/java/forge/card/spellability/SpellAbilityRestriction.java svneol=native src/main/java/forge/card/spellability/SpellAbilityStackInstance.java svneol=native#text/plain src/main/java/forge/card/spellability/SpellAbilityVariables.java svneol=native#text/plain src/main/java/forge/card/spellability/SpellPermanent.java svneol=native#text/plain -src/main/java/forge/card/spellability/Target.java svneol=native#text/plain src/main/java/forge/card/spellability/TargetChoices.java svneol=native#text/plain +src/main/java/forge/card/spellability/TargetRestrictions.java svneol=native#text/plain src/main/java/forge/card/spellability/TargetSelection.java svneol=native#text/plain src/main/java/forge/card/spellability/package-info.java svneol=native#text/plain src/main/java/forge/card/staticability/StaticAbility.java svneol=native#text/plain diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index a55185b38e9..cd0e917e9c6 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -58,7 +58,7 @@ import forge.card.spellability.AbilityTriggered; import forge.card.spellability.OptionalCost; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellPermanent; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.card.staticability.StaticAbility; import forge.card.trigger.Trigger; import forge.card.trigger.TriggerType; @@ -5355,7 +5355,7 @@ public class Card extends GameEntity implements Comparable { for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) { final SpellAbility saTargeting = sa.getSATargetingPlayer(); if (saTargeting != null) { - for (final Player p : saTargeting.getTarget().getTargetPlayers()) { + for (final Player p : saTargeting.getTargets().getTargetPlayers()) { if (!this.getController().equals(p)) { return false; } @@ -5403,7 +5403,7 @@ public class Card extends GameEntity implements Comparable { for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) { final SpellAbility saTargeting = sa.getSATargetingPlayer(); if (saTargeting != null) { - for (final Player p : saTargeting.getTarget().getTargetPlayers()) { + for (final Player p : saTargeting.getTargets().getTargetPlayers()) { if (!this.getOwner().equals(p)) { return false; } @@ -5504,7 +5504,7 @@ public class Card extends GameEntity implements Comparable { for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) { final SpellAbility saTargeting = sa.getSATargetingCard(); if (saTargeting != null) { - for (final Card c : saTargeting.getTarget().getTargetCards()) { + for (final Card c : saTargeting.getTargets().getTargetCards()) { if (!this.getEnchantedBy().contains(c) && !this.equals(c.getEnchanting())) { return false; } @@ -5518,7 +5518,7 @@ public class Card extends GameEntity implements Comparable { for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) { final SpellAbility saTargeting = sa.getSATargetingCard(); if (saTargeting != null) { - for (final Card c : saTargeting.getTarget().getTargetCards()) { + for (final Card c : saTargeting.getTargets().getTargetCards()) { if (this.getEnchantedBy().contains(c)) { return false; } @@ -5549,7 +5549,7 @@ public class Card extends GameEntity implements Comparable { for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) { final SpellAbility saTargeting = sa.getSATargetingCard(); if (saTargeting != null) { - for (final Card c : saTargeting.getTarget().getTargetCards()) { + for (final Card c : saTargeting.getTargets().getTargetCards()) { if (!this.canBeEnchantedBy(c)) { return false; } @@ -5575,7 +5575,7 @@ public class Card extends GameEntity implements Comparable { for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) { final SpellAbility saTargeting = sa.getSATargetingCard(); if (saTargeting != null) { - for (final Card c : saTargeting.getTarget().getTargetCards()) { + for (final Card c : saTargeting.getTargets().getTargetCards()) { if (!this.equippedBy.contains(c)) { return false; } @@ -5686,7 +5686,7 @@ public class Card extends GameEntity implements Comparable { for (final SpellAbility sa : this.getCharacteristics().getSpellAbility()) { final SpellAbility saTargeting = sa.getSATargetingCard(); if (saTargeting != null) { - for (final Card c : saTargeting.getTarget().getTargetCards()) { + for (final Card c : saTargeting.getTargets().getTargetCards()) { if (c.equals(source)) { return true; } @@ -8050,9 +8050,9 @@ public class Card extends GameEntity implements Comparable { */ public final boolean canBeEnchantedBy(final Card aura) { final SpellAbility sa = aura.getFirstSpellAbility(); - Target tgt = null; + TargetRestrictions tgt = null; if (sa != null) { - tgt = sa.getTarget(); + tgt = sa.getTargetRestrictions(); } if (this.hasProtectionFrom(aura) diff --git a/src/main/java/forge/GameLogFormatter.java b/src/main/java/forge/GameLogFormatter.java index e5579400c57..2a5da2632c9 100644 --- a/src/main/java/forge/GameLogFormatter.java +++ b/src/main/java/forge/GameLogFormatter.java @@ -76,7 +76,7 @@ public class GameLogFormatter extends IGameEventVisitor.Base { StringBuilder sb = new StringBuilder(); sb.append(who).append(action).append(what); - if (event.sa.getTarget() != null) { + if (event.sa.getTargetRestrictions() != null) { sb.append(" targeting "); for (TargetChoices ch : event.sa.getAllTargetChoices()) { if (null != ch) { diff --git a/src/main/java/forge/card/ability/AbilityApiBased.java b/src/main/java/forge/card/ability/AbilityApiBased.java index fa397f0f02a..ca26719f1a4 100644 --- a/src/main/java/forge/card/ability/AbilityApiBased.java +++ b/src/main/java/forge/card/ability/AbilityApiBased.java @@ -11,7 +11,7 @@ import forge.card.cardfactory.CardFactory; import forge.card.cost.Cost; import forge.card.spellability.AbilityActivated; import forge.card.spellability.AbilityManaPart; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; public class AbilityApiBased extends AbilityActivated { @@ -20,7 +20,7 @@ public class AbilityApiBased extends AbilityActivated { private static final long serialVersionUID = -4183793555528531978L; - public AbilityApiBased(ApiType api0, Card sourceCard, Cost abCost, Target tgt, Map params0) { + public AbilityApiBased(ApiType api0, Card sourceCard, Cost abCost, TargetRestrictions tgt, Map params0) { super(sourceCard, abCost, tgt); params = params0; api = api0; @@ -48,7 +48,7 @@ public class AbilityApiBased extends AbilityActivated { */ @Override public AbilityActivated getCopy() { - Target tgt = getTarget() == null ? null : new Target(getTarget()); + TargetRestrictions tgt = getTargetRestrictions() == null ? null : new TargetRestrictions(getTargetRestrictions()); AbilityActivated res = new AbilityApiBased(api, getSourceCard(), getPayCosts(), tgt, params); CardFactory.copySpellAbility(this, res); return res; diff --git a/src/main/java/forge/card/ability/AbilityFactory.java b/src/main/java/forge/card/ability/AbilityFactory.java index 83cca998c65..d2d5357a022 100644 --- a/src/main/java/forge/card/ability/AbilityFactory.java +++ b/src/main/java/forge/card/ability/AbilityFactory.java @@ -28,7 +28,7 @@ import forge.card.spellability.AbilitySub; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbilityCondition; import forge.card.spellability.SpellAbilityRestriction; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.zone.ZoneType; import forge.util.FileSection; @@ -55,7 +55,7 @@ public final class AbilityFactory { return prefix; } - public SpellAbility buildSpellAbility(ApiType api, Card hostCard, Cost abCost, Target abTgt, Map mapParams ) { + public SpellAbility buildSpellAbility(ApiType api, Card hostCard, Cost abCost, TargetRestrictions abTgt, Map mapParams ) { switch(this) { case Ability: return new AbilityApiBased(api, hostCard, abCost, abTgt, mapParams); case Spell: return new SpellApiBased(api, hostCard, abCost, abTgt, mapParams); @@ -124,7 +124,7 @@ public final class AbilityFactory { public static final SpellAbility getAbility(AbilityRecordType type, ApiType api, Map mapParams, Cost abCost, Card hostCard) { - Target abTgt = mapParams.containsKey("ValidTgts") ? readTarget(mapParams) : null; + TargetRestrictions abTgt = mapParams.containsKey("ValidTgts") ? readTarget(mapParams) : null; if (api == ApiType.CopySpellAbility || api == ApiType.Counter || api == ApiType.ChangeTargets) { // Since all "CopySpell" ABs copy things on the Stack no need for it to be everywhere @@ -204,7 +204,7 @@ public final class AbilityFactory { return spellAbility; } - private static final Target readTarget(Map mapParams) { + private static final TargetRestrictions readTarget(Map mapParams) { final String min = mapParams.containsKey("TargetMin") ? mapParams.get("TargetMin") : "1"; final String max = mapParams.containsKey("TargetMax") ? mapParams.get("TargetMax") : "1"; @@ -214,7 +214,7 @@ public final class AbilityFactory { final String prompt = mapParams.containsKey("TgtPrompt") ? mapParams.get("TgtPrompt") : "Select target " + mapParams.get("ValidTgts"); sb.append(prompt); - Target abTgt = new Target(prompt, mapParams.get("ValidTgts").split(","), min, max); + TargetRestrictions abTgt = new TargetRestrictions(prompt, mapParams.get("ValidTgts").split(","), min, max); if (mapParams.containsKey("TgtZone")) { // if Targeting // something @@ -338,11 +338,11 @@ public final class AbilityFactory { origin = ZoneType.listValueOf(params.get("Origin")); } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); // Don't set the zone if it targets a player if ((tgt != null) && !tgt.canTgtPlayer()) { - sa.getTarget().setZone(origin); + sa.getTargetRestrictions().setZone(origin); } } diff --git a/src/main/java/forge/card/ability/AbilityUtils.java b/src/main/java/forge/card/ability/AbilityUtils.java index 810584984bf..01094aed568 100644 --- a/src/main/java/forge/card/ability/AbilityUtils.java +++ b/src/main/java/forge/card/ability/AbilityUtils.java @@ -9,6 +9,8 @@ import forge.card.MagicColor; import forge.card.mana.ManaCostShard; import org.apache.commons.lang3.StringUtils; +import com.google.common.collect.Iterables; + import forge.Card; import forge.CardLists; import forge.CardUtil; @@ -124,13 +126,13 @@ public class AbilityUtils { else if (defined.equals("Targeted")) { final SpellAbility saTargeting = sa.getSATargetingCard(); if (saTargeting != null) { - cards.addAll(saTargeting.getTarget().getTargetCards()); + Iterables.addAll(cards, saTargeting.getTargets().getTargetCards()); } } else if (defined.equals("ParentTarget")) { final SpellAbility parent = sa.getParentTargetingCard(); if (parent != null) { - cards.addAll(parent.getTarget().getTargetCards()); + Iterables.addAll(cards, parent.getTargets().getTargetCards()); } } else if (defined.startsWith("Triggered") && (sa != null)) { @@ -445,17 +447,17 @@ public class AbilityUtils { final ArrayList players = new ArrayList(); final SpellAbility saTargeting = ability.getSATargetingPlayer(); if (null != saTargeting) { - players.addAll(saTargeting.getTarget().getTargetPlayers()); + Iterables.addAll(players, saTargeting.getTargets().getTargetPlayers()); } return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier; } if (calcX[0].startsWith("TargetedObjects")) { - final ArrayList objects = new ArrayList(); + final List objects = new ArrayList(); // 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()); + if (loopSA.getTargetRestrictions() != null) { + Iterables.addAll(objects, loopSA.getTargets().getTargets()); } loopSA = loopSA.getSubAbility(); } @@ -702,7 +704,7 @@ public class AbilityUtils { if (defined.equals("Targeted")) { final SpellAbility saTargeting = sa.getSATargetingPlayer(); if (saTargeting != null) { - players.addAll(saTargeting.getTarget().getTargetPlayers()); + Iterables.addAll(players, saTargeting.getTargets().getTargetPlayers()); } } else if (defined.equals("TargetedController")) { final List list = getDefinedCards(card, "Targeted", sa); @@ -732,7 +734,7 @@ public class AbilityUtils { } else if (defined.equals("TargetedAndYou")) { final SpellAbility saTargeting = sa.getSATargetingPlayer(); if (saTargeting != null) { - players.addAll(saTargeting.getTarget().getTargetPlayers()); + Iterables.addAll(players, saTargeting.getTargets().getTargetPlayers()); players.add(sa.getActivatingPlayer()); } } else if (defined.equals("Remembered")) { @@ -959,7 +961,7 @@ public class AbilityUtils { } else if (defined.equals("Targeted")) { final SpellAbility saTargeting = sa.getSATargetingSA(); if (saTargeting != null) { - sas.addAll(saTargeting.getTarget().getTargetSAs()); + Iterables.addAll(sas, saTargeting.getTargets().getTargetSpells()); } } else if (defined.startsWith("Triggered")) { final SpellAbility root = sa.getRootAbility(); @@ -1103,7 +1105,7 @@ public class AbilityUtils { boolean paid = false; for (Player payer : payers) { - final Ability ability = new AbilityStatic(source, cost, sa.getTarget()) { @Override public void resolve() { } }; + final Ability ability = new AbilityStatic(source, cost, sa.getTargetRestrictions()) { @Override public void resolve() { } }; ability.setActivatingPlayer(payer); if (payer.isComputer()) { if (ComputerUtilCost.willPayUnlessCost(sa, payer, cost, paid, payers) && ComputerUtilCost.canPayCost(ability, payer)) { @@ -1136,11 +1138,11 @@ public class AbilityUtils { public static void handleRemembering(final SpellAbility sa) { Card host = sa.getSourceCard(); - if (sa.hasParam("RememberTargets") && sa.getTarget() != null) { + if (sa.hasParam("RememberTargets") && sa.getTargetRestrictions() != null) { if (sa.hasParam("ForgetOtherTargets")) { host.clearRemembered(); } - for (final Object o : sa.getTarget().getTargets()) { + for (final ITargetable o : sa.getTargets().getTargets()) { host.addRemembered(o); } } diff --git a/src/main/java/forge/card/ability/SaTargetRountines.java b/src/main/java/forge/card/ability/SaTargetRountines.java new file mode 100644 index 00000000000..24e3232108f --- /dev/null +++ b/src/main/java/forge/card/ability/SaTargetRountines.java @@ -0,0 +1,61 @@ +package forge.card.ability; + +import java.util.List; + +import com.google.common.collect.Lists; + +import forge.Card; +import forge.ITargetable; +import forge.card.spellability.SpellAbility; +import forge.game.player.Player; + +// Class contains all that methods that are used by both effects and AI to fetch their targets. +// {SA}Effect and {SA}Ai now inherit from this class to use these routines, though they should not. + +public class SaTargetRountines { + + // Cards + protected List getTargetCards(SpellAbility sa) { return getCards(false, "Defined", sa); } + protected List getTargetCards(SpellAbility sa, String definedParam) { return getCards(false, definedParam, sa); } + protected List getDefinedCardsOrTargeted(SpellAbility sa, String definedParam) { return getCards(true, definedParam, sa); } + + private List getCards(boolean definedFirst, String definedParam, SpellAbility sa) { + boolean useTargets = sa.usesTargeting() && (!definedFirst || !sa.hasParam(definedParam)); + return useTargets ? Lists.newArrayList(sa.getTargets().getTargetCards()) + : AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam(definedParam), sa); + } + + // Players + protected List getTargetPlayers(SpellAbility sa) { return getPlayers(false, "Defined", sa); } + protected List getTargetPlayers(SpellAbility sa, String definedParam) { return getPlayers(false, definedParam, sa); } + protected List getDefinedPlayersOrTargeted(SpellAbility sa ) { return getPlayers(true, "Defined", sa); } + protected List getDefinedPlayersOrTargeted(SpellAbility sa, String definedParam) { return getPlayers(true, definedParam, sa); } + + private List getPlayers(boolean definedFirst, String definedParam, SpellAbility sa) { + boolean useTargets = sa.usesTargeting() && (!definedFirst || !sa.hasParam(definedParam)); + return useTargets ? Lists.newArrayList(sa.getTargets().getTargetPlayers()) + : AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam(definedParam), sa); + } + + // Spells + protected List getTargetSpells(SpellAbility sa) { return getSpells(false, "Defined", sa); } + protected List getTargetSpells(SpellAbility sa, String definedParam) { return getSpells(false, definedParam, sa); } + protected List getDefinedSpellsOrTargeted(SpellAbility sa, String definedParam) { return getSpells(true, definedParam, sa); } + + private List getSpells(boolean definedFirst, String definedParam, SpellAbility sa) { + boolean useTargets = sa.usesTargeting() && (!definedFirst || !sa.hasParam(definedParam)); + return useTargets ? Lists.newArrayList(sa.getTargets().getTargetSpells()) + : AbilityUtils.getDefinedSpellAbilities(sa.getSourceCard(), sa.getParam(definedParam), sa); + } + + // Targets of unspecified type + protected List getTargets(SpellAbility sa) { return getTargetables(false, "Defined", sa); } + protected List getTargets(SpellAbility sa, String definedParam) { return getTargetables(false, definedParam, sa); } + protected List getDefinedOrTargeteded(SpellAbility sa, String definedParam) { return getTargetables(true, definedParam, sa); } + + private List getTargetables(boolean definedFirst, String definedParam, SpellAbility sa) { + boolean useTargets = sa.usesTargeting() && (!definedFirst || !sa.hasParam(definedParam)); + return useTargets ? Lists.newArrayList(sa.getTargets().getTargets()) + : AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam(definedParam), sa); + } +} \ No newline at end of file diff --git a/src/main/java/forge/card/ability/SpellAbilityAi.java b/src/main/java/forge/card/ability/SpellAbilityAi.java index 6a7230cce24..7f667e1deca 100644 --- a/src/main/java/forge/card/ability/SpellAbilityAi.java +++ b/src/main/java/forge/card/ability/SpellAbilityAi.java @@ -12,7 +12,7 @@ import forge.game.phase.PhaseType; import forge.game.player.Player; import forge.game.player.PlayerActionConfirmMode; -public abstract class SpellAbilityAi { +public abstract class SpellAbilityAi extends SaTargetRountines { public final boolean canPlayAIWithSubs(final Player aiPlayer, final SpellAbility sa) { if (!canPlayAI(aiPlayer, sa)) { diff --git a/src/main/java/forge/card/ability/SpellAbilityEffect.java b/src/main/java/forge/card/ability/SpellAbilityEffect.java index a98e6258e2c..a5abf58406a 100644 --- a/src/main/java/forge/card/ability/SpellAbilityEffect.java +++ b/src/main/java/forge/card/ability/SpellAbilityEffect.java @@ -1,20 +1,15 @@ package forge.card.ability; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; 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; -import forge.card.spellability.Target; -import forge.game.player.Player; /** *

@@ -25,7 +20,7 @@ import forge.game.player.Player; * @version $Id: AbilityFactoryAlterLife.java 17656 2012-10-22 19:32:56Z Max mtg $ */ - public abstract class SpellAbilityEffect { + public abstract class SpellAbilityEffect extends SaTargetRountines { public abstract void resolve(final SpellAbility sa); @@ -123,49 +118,4 @@ import forge.game.player.Player; } } } - - protected List getTargetCards(SpellAbility sa) { - final Target tgt = sa.getTarget(); - return tgt != null ? tgt.getTargetCards() : AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa); - } - - protected List getTargetPlayers(SpellAbility sa) { - return getTargetPlayers(sa, false, true); - } - - protected List getTargetPlayersEmptyAsDefault(SpellAbility sa) { - return getTargetPlayers(sa, true, true); - } - - protected List getDefinedPlayersBeforeTargetOnes(SpellAbility sa) { - return getTargetPlayers(sa, false, false); - } - - // Each AF used its own preference in choosing target players: - // Some checked target first and params["Defined"] then - @see targetIsPreferred - // Some wanted empty list when params["Defined"] was not set - @see wantEmptyAsDefault - // Poor me had to gather it all in a single place - private static final List emptyPlayerList = Collections.unmodifiableList(new ArrayList()); - private List getTargetPlayers(SpellAbility sa, final boolean wantEmptyAsDefault, final boolean targetIsPreferred) { - final Target tgt = sa.getTarget(); - final String defined = sa.getParam("Defined"); - if (tgt != null && (targetIsPreferred || (StringUtils.isEmpty(defined) && !wantEmptyAsDefault))) { - return tgt.getTargetPlayers(); - } - if (StringUtils.isEmpty(defined) && wantEmptyAsDefault) { - return emptyPlayerList; - } - return AbilityUtils.getDefinedPlayers(sa.getSourceCard(), defined, sa); - } - - protected List getTargetSpellAbilities(SpellAbility sa) { - final Target tgt = sa.getTarget(); - return tgt != null ? tgt.getTargetSAs() : AbilityUtils.getDefinedSpellAbilities(sa.getSourceCard(), sa.getParam("Defined"), 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/SpellApiBased.java b/src/main/java/forge/card/ability/SpellApiBased.java index af5950a3853..58d11d040cf 100644 --- a/src/main/java/forge/card/ability/SpellApiBased.java +++ b/src/main/java/forge/card/ability/SpellApiBased.java @@ -10,16 +10,16 @@ import forge.card.ability.effects.ManaReflectedEffect; import forge.card.cost.Cost; import forge.card.spellability.AbilityManaPart; import forge.card.spellability.Spell; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; public class SpellApiBased extends Spell { private static final long serialVersionUID = -6741797239508483250L; private final SpellAbilityEffect effect; private final SpellAbilityAi ai; - public SpellApiBased(ApiType api0, Card sourceCard, Cost abCost, Target tgt, Map params0) { + public SpellApiBased(ApiType api0, Card sourceCard, Cost abCost, TargetRestrictions tgt, Map params0) { super(sourceCard, abCost); - this.setTarget(tgt); + this.setTargetRestrictions(tgt); params = params0; api = api0; diff --git a/src/main/java/forge/card/ability/ai/AddTurnAi.java b/src/main/java/forge/card/ability/ai/AddTurnAi.java index 16a29491621..2b1b353645c 100644 --- a/src/main/java/forge/card/ability/ai/AddTurnAi.java +++ b/src/main/java/forge/card/ability/ai/AddTurnAi.java @@ -22,7 +22,6 @@ import java.util.List; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.game.player.Player; /** @@ -39,21 +38,20 @@ public class AddTurnAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { final Player opp = ai.getWeakestOpponent(); - final Target tgt = sa.getTarget(); - if (sa.getTarget() != null) { - tgt.resetTargets(); + if (sa.usesTargeting()) { + sa.resetTargets(); if (sa.canTarget(ai)) { - sa.getTarget().addTarget(ai); + sa.getTargets().add(ai); } else if (mandatory) { for (final Player ally : ai.getAllies()) { if (sa.canTarget(ally)) { - sa.getTarget().addTarget(ally); + sa.getTargets().add(ally); break; } } - if (!sa.getTarget().isMinTargetsChosen(sa.getSourceCard(), sa) && sa.canTarget(opp)) { - sa.getTarget().addTarget(opp); + if (!sa.getTargetRestrictions().isMinTargetsChosen(sa.getSourceCard(), sa) && sa.canTarget(opp)) { + sa.getTargets().add(opp); } else { return false; } diff --git a/src/main/java/forge/card/ability/ai/AnimateAi.java b/src/main/java/forge/card/ability/ai/AnimateAi.java index 814b88b6053..ce31802b926 100644 --- a/src/main/java/forge/card/ability/ai/AnimateAi.java +++ b/src/main/java/forge/card/ability/ai/AnimateAi.java @@ -9,7 +9,7 @@ import forge.CardPredicates; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.phase.PhaseType; import forge.game.player.Player; @@ -31,7 +31,7 @@ public class AnimateAi extends SpellAbilityAi { */ @Override protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); final Game game = aiPlayer.getGame(); @@ -112,7 +112,7 @@ public class AnimateAi extends SpellAbilityAi { return false; } } else { - tgt.resetTargets(); + sa.resetTargets(); if (!animateTgtAI(sa)) { return false; } @@ -125,8 +125,8 @@ public class AnimateAi extends SpellAbilityAi { @Override public boolean chkAIDrawback(SpellAbility sa, Player aiPlayer) { - if (sa.getTarget() != null) { - sa.getTarget().resetTargets(); + if (sa.usesTargeting()) { + sa.resetTargets(); if (!animateTgtAI(sa)) { return false; } @@ -151,7 +151,7 @@ public class AnimateAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player aiPlayer, SpellAbility sa, boolean mandatory) { - if (sa.getTarget() != null && !animateTgtAI(sa) && !mandatory) { + if (sa.usesTargeting() && !animateTgtAI(sa) && !mandatory) { return false; } diff --git a/src/main/java/forge/card/ability/ai/AttachAi.java b/src/main/java/forge/card/ability/ai/AttachAi.java index 46a59f3af85..97c5296ea9c 100644 --- a/src/main/java/forge/card/ability/ai/AttachAi.java +++ b/src/main/java/forge/card/ability/ai/AttachAi.java @@ -21,7 +21,7 @@ import forge.card.ability.SpellAbilityAi; import forge.card.cardfactory.CardFactoryUtil; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.card.staticability.StaticAbility; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCard; @@ -60,9 +60,9 @@ public class AttachAi extends SpellAbilityAi { final boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn()); // Attach spells always have a target - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.resetTargets(); + sa.resetTargets(); if (!attachPreference(sa, tgt, false)) { return false; } @@ -455,7 +455,7 @@ public class AttachAi extends SpellAbilityAi { final Card attachSource) { // AI For choosing a Card to Gain Control of. - if (sa.getTarget().canTgtPermanent()) { + if (sa.getTargetRestrictions().canTgtPermanent()) { // If can target all Permanents, and Life isn't in eminent danger, // grab Planeswalker first, then Creature // if Life < 5 grab Creature first, then Planeswalker. Lands, @@ -613,7 +613,7 @@ public class AttachAi extends SpellAbilityAi { final Card card = sa.getSourceCard(); // Check if there are any valid targets List targets = new ArrayList(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt == null) { targets = AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam("Defined"), sa); } else { @@ -678,8 +678,8 @@ public class AttachAi extends SpellAbilityAi { * the mandatory * @return true, if successful */ - private static boolean attachPreference(final SpellAbility sa, final Target tgt, final boolean mandatory) { - Object o; + private static boolean attachPreference(final SpellAbility sa, final TargetRestrictions tgt, final boolean mandatory) { + ITargetable o; if (tgt.canTgtPlayer()) { o = attachToPlayerAIPreferences(sa.getActivatingPlayer(), sa, mandatory); } else { @@ -690,7 +690,7 @@ public class AttachAi extends SpellAbilityAi { return false; } - tgt.addTarget(o); + sa.getTargets().add(o); return true; } @@ -866,7 +866,7 @@ public class AttachAi extends SpellAbilityAi { * @return the card */ private static Card attachToCardAIPreferences(final Player aiPlayer, final SpellAbility sa, final boolean mandatory) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card attachSource = sa.getSourceCard(); // TODO AttachSource is currently set for the Source of the Spell, but // at some point can support attaching a different card diff --git a/src/main/java/forge/card/ability/ai/BecomesBlockedAi.java b/src/main/java/forge/card/ability/ai/BecomesBlockedAi.java index 9757a940277..e15f19a2bfe 100644 --- a/src/main/java/forge/card/ability/ai/BecomesBlockedAi.java +++ b/src/main/java/forge/card/ability/ai/BecomesBlockedAi.java @@ -7,7 +7,7 @@ import forge.Card; import forge.CardLists; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtilCard; import forge.game.phase.PhaseType; @@ -19,7 +19,7 @@ public class BecomesBlockedAi extends SpellAbilityAi { @Override protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) { final Card source = sa.getSourceCard(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Game game = aiPlayer.getGame(); if (!game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS) @@ -33,7 +33,7 @@ public class BecomesBlockedAi extends SpellAbilityAi { list = CardLists.getTargetableCards(list, sa); list = CardLists.getNotKeyword(list, "Trample"); - while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) { Card choice = null; if (list.isEmpty()) { @@ -47,7 +47,7 @@ public class BecomesBlockedAi extends SpellAbilityAi { } list.remove(choice); - tgt.addTarget(choice); + sa.getTargets().add(choice); } return true; } diff --git a/src/main/java/forge/card/ability/ai/ChangeZoneAi.java b/src/main/java/forge/card/ability/ai/ChangeZoneAi.java index d771821a04d..98ff7e64aa5 100644 --- a/src/main/java/forge/card/ability/ai/ChangeZoneAi.java +++ b/src/main/java/forge/card/ability/ai/ChangeZoneAi.java @@ -8,6 +8,7 @@ import java.util.Random; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; import forge.Card; import forge.CardCharacteristicName; @@ -16,6 +17,7 @@ import forge.CardPredicates; import forge.CardPredicates.Presets; import forge.Constant; import forge.GameEntity; +import forge.ITargetable; import forge.card.ability.AbilityUtils; import forge.card.ability.ApiType; import forge.card.ability.SpellAbilityAi; @@ -25,7 +27,7 @@ import forge.card.cost.CostDiscard; import forge.card.cost.CostPart; import forge.card.spellability.AbilitySub; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.card.trigger.TriggerType; import forge.game.Game; import forge.game.GlobalRuleChange; @@ -228,17 +230,16 @@ public class ChangeZoneAi extends SpellAbilityAi { // prevent run-away activations - first time will always return true boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn()); - List pDefined = new ArrayList(); - pDefined.add(source.getController()); - final Target tgt = sa.getTarget(); + Iterable pDefined = Lists.newArrayList(source.getController()); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if ((tgt != null) && tgt.canTgtPlayer()) { boolean isCurse = sa.isCurse(); if (isCurse && sa.canTarget(opponent)) { - tgt.addTarget(opponent); + sa.getTargets().add(opponent); } else if (!isCurse && sa.canTarget(ai)) { - tgt.addTarget(ai); + sa.getTargets().add(ai); } - pDefined = tgt.getTargetPlayers(); + pDefined = sa.getTargets().getTargetPlayers(); } else { if (sa.hasParam("DefinedPlayer")) { pDefined = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("DefinedPlayer"), sa); @@ -323,14 +324,14 @@ public class ChangeZoneAi extends SpellAbilityAi { private static boolean hiddenOriginPlayDrawbackAI(final Player aiPlayer, final SpellAbility sa) { // if putting cards from hand to library and parent is drawing cards // make sure this will actually do something: - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Player opp = aiPlayer.getOpponent(); if ((tgt != null) && tgt.canTgtPlayer()) { boolean isCurse = sa.isCurse(); if (isCurse && sa.canTarget(opp)) { - tgt.addTarget(opp); + sa.getTargets().add(opp); } else if (!isCurse && sa.canTarget(aiPlayer)) { - tgt.addTarget(aiPlayer); + sa.getTargets().add(aiPlayer); } else { return false; } @@ -372,32 +373,32 @@ public class ChangeZoneAi extends SpellAbilityAi { source.setSVar("PayX", Integer.toString(xPay)); } - List pDefined; - final Target tgt = sa.getTarget(); + Iterable pDefined; + final TargetRestrictions tgt = sa.getTargetRestrictions(); if ((tgt != null) && tgt.canTgtPlayer()) { final Player opp = ai.getOpponent(); if (sa.isCurse()) { if (sa.canTarget(opp)) { - tgt.addTarget(opp); + sa.getTargets().add(opp); } else if (mandatory && sa.canTarget(ai)) { - tgt.addTarget(ai); + sa.getTargets().add(ai); } } else { if (sa.canTarget(ai)) { - tgt.addTarget(ai); + sa.getTargets().add(ai); } else if (mandatory && sa.canTarget(opp)) { - tgt.addTarget(opp); + sa.getTargets().add(opp); } } - pDefined = tgt.getTargetPlayers(); + pDefined = sa.getTargets().getTargetPlayers(); - if (pDefined.isEmpty()) { + if (Iterables.isEmpty(pDefined)) { return false; } if (mandatory) { - return pDefined.size() > 0; + return true; } } else { if (mandatory) { @@ -571,7 +572,7 @@ public class ChangeZoneAi extends SpellAbilityAi { // prevent run-away activations - first time will always return true boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getRestrictions().getNumberTurnActivations()); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { if (!isPreferredTarget(ai, sa, false)) { return false; @@ -609,7 +610,7 @@ public class ChangeZoneAi extends SpellAbilityAi { return false; } - final ArrayList objects = ComputerUtil.predictThreatenedObjects(ai, sa); + final List objects = ComputerUtil.predictThreatenedObjects(ai, sa); boolean contains = false; for (final Card c : retrieval) { if (objects.contains(c)) { @@ -664,7 +665,7 @@ public class ChangeZoneAi extends SpellAbilityAi { * @return a boolean. */ private static boolean knownOriginPlayDrawbackAI(final Player aiPlayer, final SpellAbility sa) { - if (sa.getTarget() == null) { + if (sa.getTargetRestrictions() == null) { return true; } @@ -688,7 +689,7 @@ public class ChangeZoneAi extends SpellAbilityAi { final Card source = sa.getSourceCard(); final ZoneType origin = ZoneType.listValueOf(sa.getParam("Origin")).get(0); final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination")); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final AbilitySub abSub = sa.getSubAbility(); ApiType subApi = null; @@ -700,7 +701,7 @@ public class ChangeZoneAi extends SpellAbilityAi { } } - tgt.resetTargets(); + sa.resetTargets(); List list = CardLists.getValidCards(ai.getGame().getCardsIn(origin), tgt.getValidTgts(), ai, source); list = CardLists.getTargetableCards(list, sa); if (sa.hasParam("AITgts")) { @@ -730,7 +731,7 @@ public class ChangeZoneAi extends SpellAbilityAi { // check stack for something on the stack that will kill // anything i control if (!ai.getGame().getStack().isEmpty()) { - final ArrayList objects = ComputerUtil.predictThreatenedObjects(ai, sa); + final List objects = ComputerUtil.predictThreatenedObjects(ai, sa); final List threatenedTargets = new ArrayList(); @@ -742,7 +743,7 @@ public class ChangeZoneAi extends SpellAbilityAi { if (!threatenedTargets.isEmpty()) { // Choose "best" of the remaining to save - tgt.addTarget(ComputerUtilCard.getBestAI(threatenedTargets)); + sa.getTargets().add(ComputerUtilCard.getBestAI(threatenedTargets)); return true; } } @@ -753,7 +754,7 @@ public class ChangeZoneAi extends SpellAbilityAi { for (final Card c : combatants) { if (c.getShield() == 0 && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c) && c.getOwner() == ai && !c.isToken()) { - tgt.addTarget(c); + sa.getTargets().add(c); return true; } } @@ -789,7 +790,7 @@ public class ChangeZoneAi extends SpellAbilityAi { }); if (!aiPermanents.isEmpty()) { // Choose "best" of the remaining to save - tgt.addTarget(ComputerUtilCard.getBestAI(aiPermanents)); + sa.getTargets().add(ComputerUtilCard.getBestAI(aiPermanents)); return true; } }*/ @@ -860,7 +861,7 @@ public class ChangeZoneAi extends SpellAbilityAi { } // target loop - while (tgt.getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) { // AI Targeting Card choice = null; @@ -909,9 +910,9 @@ public class ChangeZoneAi extends SpellAbilityAi { } } if (choice == null) { // can't find anything left - if (tgt.getNumTargeted() == 0 || tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { + if (sa.getTargets().getNumTargeted() == 0 || sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { if (!mandatory) { - tgt.resetTargets(); + sa.resetTargets(); } return false; } else { @@ -923,7 +924,7 @@ public class ChangeZoneAi extends SpellAbilityAi { } list.remove(choice); - tgt.addTarget(choice); + sa.getTargets().add(choice); } return true; @@ -951,7 +952,7 @@ public class ChangeZoneAi extends SpellAbilityAi { final Card source = sa.getSourceCard(); final ZoneType origin = ZoneType.listValueOf(sa.getParam("Origin")).get(0); final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination")); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); List list = CardLists.getValidCards(ai.getGame().getCardsIn(origin), tgt.getValidTgts(), ai, source); @@ -969,7 +970,7 @@ public class ChangeZoneAi extends SpellAbilityAi { } - for (final Card c : tgt.getTargetCards()) { + for (final Card c : sa.getTargets().getTargetCards()) { list.remove(c); } @@ -978,7 +979,7 @@ public class ChangeZoneAi extends SpellAbilityAi { } // target loop - while (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { // AI Targeting Card choice = null; @@ -1020,8 +1021,8 @@ public class ChangeZoneAi extends SpellAbilityAi { } } if (choice == null) { // can't find anything left - if ((tgt.getNumTargeted() == 0) || (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa))) { - tgt.resetTargets(); + if ((sa.getTargets().getNumTargeted() == 0) || (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa))) { + sa.resetTargets(); return false; } else { if (!ComputerUtil.shouldCastLessThanMax(ai, source)) { @@ -1032,7 +1033,7 @@ public class ChangeZoneAi extends SpellAbilityAi { } list.remove(choice); - tgt.addTarget(choice); + sa.getTargets().add(choice); } return true; @@ -1054,7 +1055,7 @@ public class ChangeZoneAi extends SpellAbilityAi { private static boolean knownOriginTriggerAI(final Player ai, final SpellAbility sa, final boolean mandatory) { - if (sa.getTarget() == null) { + if (sa.getTargetRestrictions() == null) { // Just in case of Defined cases if (!mandatory && sa.hasParam("AttachedTo")) { final List list = AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("AttachedTo"), sa); @@ -1088,15 +1089,15 @@ public class ChangeZoneAi extends SpellAbilityAi { * a {@link forge.game.player.Player} object. */ public static void hiddenOriginResolveAI(final Player ai, final SpellAbility sa, Player player) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card card = sa.getSourceCard(); final boolean defined = sa.hasParam("Defined"); final Player activator = sa.getActivatingPlayer(); final Game game = ai.getGame(); if (tgt != null) { - if (!tgt.getTargetPlayers().isEmpty()) { - player = sa.hasParam("DefinedPlayer") ? player : tgt.getTargetPlayers().get(0); + if (sa.getTargets().isTargetingAnyPlayer()) { + player = sa.hasParam("DefinedPlayer") ? player : sa.getTargets().getFirstTargetedPlayer(); if (!player.canBeTargetedBy(sa)) { return; } @@ -1342,7 +1343,7 @@ public class ChangeZoneAi extends SpellAbilityAi { // Auras without Candidates stay in their current location if (c.isAura()) { final SpellAbility saAura = AttachEffect.getAttachSpellAbility(c); - if (!saAura.getTarget().hasCandidates(saAura, false)) { + if (!saAura.getTargetRestrictions().hasCandidates(saAura, false)) { continue; } } diff --git a/src/main/java/forge/card/ability/ai/ChangeZoneAllAi.java b/src/main/java/forge/card/ability/ai/ChangeZoneAllAi.java index bc7b45a066b..8b948d10c2f 100644 --- a/src/main/java/forge/card/ability/ai/ChangeZoneAllAi.java +++ b/src/main/java/forge/card/ability/ai/ChangeZoneAllAi.java @@ -9,7 +9,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCost; import forge.game.phase.PhaseType; @@ -57,7 +57,7 @@ public class ChangeZoneAllAi extends SpellAbilityAi { final List humanType = AbilityUtils.filterListByType(opp.getCardsIn(origin), sa.getParam("ChangeType"), sa); List computerType = ai.getCardsIn(origin); computerType = AbilityUtils.filterListByType(computerType, sa.getParam("ChangeType"), sa); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); // TODO improve restrictions on when the AI would want to use this // spBounceAll has some AI we can compare to. @@ -67,8 +67,8 @@ public class ChangeZoneAllAi extends SpellAbilityAi { || !opp.canBeTargetedBy(sa)) { return false; } - tgt.resetTargets(); - tgt.addTarget(opp); + sa.resetTargets(); + sa.getTargets().add(opp); } } else if (origin.equals(ZoneType.Battlefield)) { // this statement is assuming the AI is trying to use this spell @@ -82,8 +82,8 @@ public class ChangeZoneAllAi extends SpellAbilityAi { || !opp.canBeTargetedBy(sa)) { return false; } - tgt.resetTargets(); - tgt.addTarget(opp); + sa.resetTargets(); + sa.getTargets().add(opp); computerType.clear(); } if ((CardLists.getNotType(humanType, "Creature").size() == 0) && (CardLists.getNotType(computerType, "Creature").size() == 0)) { @@ -108,8 +108,8 @@ public class ChangeZoneAllAi extends SpellAbilityAi { || !opp.canBeTargetedBy(sa)) { return false; } - tgt.resetTargets(); - tgt.addTarget(opp); + sa.resetTargets(); + sa.getTargets().add(opp); } } else if (origin.equals(ZoneType.Exile)) { @@ -189,14 +189,14 @@ public class ChangeZoneAllAi extends SpellAbilityAi { // TODO improve restrictions on when the AI would want to use this // spBounceAll has some AI we can compare to. if (origin.equals(ZoneType.Hand) || origin.equals(ZoneType.Library)) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { if (opp.getCardsIn(ZoneType.Hand).isEmpty() || !opp.canBeTargetedBy(sa)) { return false; } - tgt.resetTargets(); - tgt.addTarget(opp); + sa.resetTargets(); + sa.getTargets().add(opp); } } else if (origin.equals(ZoneType.Battlefield)) { // this statement is assuming the AI is trying to use this spell offensively @@ -215,14 +215,14 @@ public class ChangeZoneAllAi extends SpellAbilityAi { return false; } } else if (origin.equals(ZoneType.Graveyard)) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { if (opp.getCardsIn(ZoneType.Graveyard).isEmpty() || !opp.canBeTargetedBy(sa)) { return false; } - tgt.resetTargets(); - tgt.addTarget(opp); + sa.resetTargets(); + sa.getTargets().add(opp); } } else if (origin.equals(ZoneType.Exile)) { diff --git a/src/main/java/forge/card/ability/ai/ChooseCardAi.java b/src/main/java/forge/card/ability/ai/ChooseCardAi.java index 0af91f3301d..db86b89e5b4 100644 --- a/src/main/java/forge/card/ability/ai/ChooseCardAi.java +++ b/src/main/java/forge/card/ability/ai/ChooseCardAi.java @@ -9,7 +9,7 @@ import forge.CardLists; import forge.CardPredicates.Presets; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCombat; @@ -27,11 +27,11 @@ public class ChooseCardAi extends SpellAbilityAi { final Card host = sa.getSourceCard(); final Game game = ai.getGame(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.resetTargets(); + sa.resetTargets(); if (sa.canTarget(ai.getOpponent())) { - tgt.addTarget(ai.getOpponent()); + sa.getTargets().add(ai.getOpponent()); } else { return false; } diff --git a/src/main/java/forge/card/ability/ai/ChooseCardNameAi.java b/src/main/java/forge/card/ability/ai/ChooseCardNameAi.java index 276f785099b..6b1edf03e7f 100644 --- a/src/main/java/forge/card/ability/ai/ChooseCardNameAi.java +++ b/src/main/java/forge/card/ability/ai/ChooseCardNameAi.java @@ -3,7 +3,7 @@ package forge.card.ability.ai; import forge.Card; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilMana; import forge.game.phase.PhaseType; @@ -40,13 +40,13 @@ public class ChooseCardNameAi extends SpellAbilityAi { source.setSVar("PayX", Integer.toString(tokenSize)); } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.resetTargets(); + sa.resetTargets(); if (tgt.canOnlyTgtOpponent()) { - tgt.addTarget(ai.getOpponent()); + sa.getTargets().add(ai.getOpponent()); } else { - tgt.addTarget(ai); + sa.getTargets().add(ai); } } return true; diff --git a/src/main/java/forge/card/ability/ai/ChooseSourceAi.java b/src/main/java/forge/card/ability/ai/ChooseSourceAi.java index fe23c790cc4..53b855912e0 100644 --- a/src/main/java/forge/card/ability/ai/ChooseSourceAi.java +++ b/src/main/java/forge/card/ability/ai/ChooseSourceAi.java @@ -1,6 +1,5 @@ package forge.card.ability.ai; -import java.util.ArrayList; import java.util.List; import com.google.common.base.Predicate; @@ -13,7 +12,7 @@ import forge.card.ability.ApiType; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtilCombat; import forge.game.ai.ComputerUtilCost; @@ -56,11 +55,11 @@ public class ChooseSourceAi extends SpellAbilityAi { } } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.resetTargets(); + sa.resetTargets(); if (sa.canTarget(ai.getOpponent())) { - tgt.addTarget(ai.getOpponent()); + sa.getTargets().add(ai.getOpponent()); } else { return false; } @@ -79,18 +78,12 @@ public class ChooseSourceAi extends SpellAbilityAi { } final Card threatSource = topStack.getSourceCard(); - List objects = new ArrayList(); - final Target threatTgt = topStack.getTarget(); + List objects = getTargets(sa); - if (threatTgt == null) { - if (topStack.hasParam("Defined")) { - objects = AbilityUtils.getDefinedObjects(threatSource, topStack.getParam("Defined"), topStack); - } else if (topStack.hasParam("ValidPlayers")) { - objects = AbilityUtils.getDefinedPlayers(threatSource, topStack.getParam("ValidPlayers"), topStack); - } - } else { - objects = threatTgt.getTargetPlayers(); + if (!topStack.usesTargeting() && topStack.hasParam("ValidPlayers") && !topStack.hasParam("Defined")) { + objects = AbilityUtils.getDefinedPlayers(threatSource, topStack.getParam("ValidPlayers"), topStack); } + if (!objects.contains(ai) || topStack.hasParam("NoPrevention")) { return false; } diff --git a/src/main/java/forge/card/ability/ai/ChooseTypeAi.java b/src/main/java/forge/card/ability/ai/ChooseTypeAi.java index d8de63f9217..e2318ba7a1c 100644 --- a/src/main/java/forge/card/ability/ai/ChooseTypeAi.java +++ b/src/main/java/forge/card/ability/ai/ChooseTypeAi.java @@ -3,7 +3,6 @@ package forge.card.ability.ai; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.game.player.Player; public class ChooseTypeAi extends SpellAbilityAi { @@ -18,11 +17,9 @@ public class ChooseTypeAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { - final Target tgt = sa.getTarget(); - - if (sa.getTarget() != null) { - tgt.resetTargets(); - sa.getTarget().addTarget(ai); + if (sa.usesTargeting()) { + sa.resetTargets(); + sa.getTargets().add(ai); } else { for (final Player p : AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa)) { if (p.isOpponentOf(ai) && !mandatory) { diff --git a/src/main/java/forge/card/ability/ai/ClashAi.java b/src/main/java/forge/card/ability/ai/ClashAi.java index a50fe31a4ba..15bf8ff34e9 100644 --- a/src/main/java/forge/card/ability/ai/ClashAi.java +++ b/src/main/java/forge/card/ability/ai/ClashAi.java @@ -3,7 +3,7 @@ package forge.card.ability.ai; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; public class ClashAi extends SpellAbilityAi { @@ -21,14 +21,14 @@ public class ClashAi extends SpellAbilityAi { */ @Override protected boolean canPlayAI(Player ai, SpellAbility sa) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Player opp = ai.getOpponent(); if (tgt != null) { if (!opp.canBeTargetedBy(sa)) { return false; } - tgt.resetTargets(); - tgt.addTarget(opp); + sa.resetTargets(); + sa.getTargets().add(opp); } return true; } diff --git a/src/main/java/forge/card/ability/ai/CloneAi.java b/src/main/java/forge/card/ability/ai/CloneAi.java index 0bb52337d95..02351ee6510 100644 --- a/src/main/java/forge/card/ability/ai/CloneAi.java +++ b/src/main/java/forge/card/ability/ai/CloneAi.java @@ -6,7 +6,7 @@ import forge.Card; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; @@ -16,7 +16,7 @@ public class CloneAi extends SpellAbilityAi { @Override protected boolean canPlayAI(Player ai, SpellAbility sa) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); final Game game = source.getGame(); @@ -85,7 +85,7 @@ public class CloneAi extends SpellAbilityAi { return false; } } else { - tgt.resetTargets(); + sa.resetTargets(); useAbility &= cloneTgtAI(sa); } @@ -97,7 +97,7 @@ public class CloneAi extends SpellAbilityAi { // AI should only activate this during Human's turn boolean chance = true; - if (sa.getTarget() != null) { + if (sa.usesTargeting()) { chance = cloneTgtAI(sa); } @@ -110,7 +110,7 @@ public class CloneAi extends SpellAbilityAi { boolean chance = true; - if (sa.getTarget() != null) { + if (sa.usesTargeting()) { chance = cloneTgtAI(sa); } diff --git a/src/main/java/forge/card/ability/ai/ControlExchangeAi.java b/src/main/java/forge/card/ability/ai/ControlExchangeAi.java index e444c11cb8b..3834866f27c 100644 --- a/src/main/java/forge/card/ability/ai/ControlExchangeAi.java +++ b/src/main/java/forge/card/ability/ai/ControlExchangeAi.java @@ -10,7 +10,7 @@ import forge.CardLists; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtilCard; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -25,8 +25,8 @@ public class ControlExchangeAi extends SpellAbilityAi { protected boolean canPlayAI(Player ai, final SpellAbility sa) { Card object1 = null; Card object2 = null; - final Target tgt = sa.getTarget(); - tgt.resetTargets(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); + sa.resetTargets(); List list = CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, sa.getSourceCard()); @@ -46,13 +46,13 @@ public class ControlExchangeAi extends SpellAbilityAi { List list2 = ai.getCardsIn(ZoneType.Battlefield); list2 = CardLists.getValidCards(list2, tgt.getValidTgts(), ai, sa.getSourceCard()); object2 = ComputerUtilCard.getWorstAI(list2); - tgt.addTarget(object2); + sa.getTargets().add(object2); } if (object1 == null || object2 == null) { return false; } if (ComputerUtilCard.evaluateCreature(object1) > ComputerUtilCard.evaluateCreature(object2) + 40) { - tgt.addTarget(object1); + sa.getTargets().add(object1); return MyRandom.getRandom().nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn()); } return false; diff --git a/src/main/java/forge/card/ability/ai/ControlGainAi.java b/src/main/java/forge/card/ability/ai/ControlGainAi.java index ebedbc40140..3dce6675c49 100644 --- a/src/main/java/forge/card/ability/ai/ControlGainAi.java +++ b/src/main/java/forge/card/ability/ai/ControlGainAi.java @@ -28,7 +28,7 @@ import forge.CardLists; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtilCard; import forge.game.phase.CombatUtil; @@ -70,7 +70,7 @@ public class ControlGainAi extends SpellAbilityAi { final List lose = sa.hasParam("LoseControl") ? Arrays.asList(sa.getParam("LoseControl").split(",")) : null; - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); Player opp = ai.getOpponent(); // if Defined, then don't worry about targeting @@ -84,12 +84,12 @@ public class ControlGainAi extends SpellAbilityAi { } return true; } else { - tgt.resetTargets(); + sa.resetTargets(); if (tgt.canOnlyTgtOpponent()) { if (!opp.canBeTargetedBy(sa)) { return false; } - tgt.addTarget(opp); + sa.getTargets().add(opp); } } @@ -116,7 +116,7 @@ public class ControlGainAi extends SpellAbilityAi { return false; } - while (tgt.getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) { Card t = null; for (final Card c : list) { if (c.isCreature()) { @@ -134,8 +134,8 @@ public class ControlGainAi extends SpellAbilityAi { } if (list.isEmpty()) { - if ((tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (tgt.getNumTargeted() == 0)) { - tgt.resetTargets(); + if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (sa.getTargets().getNumTargeted() == 0)) { + sa.resetTargets(); return false; } else { // TODO is this good enough? for up to amounts? @@ -155,7 +155,7 @@ public class ControlGainAi extends SpellAbilityAi { t = ComputerUtilCard.getMostExpensivePermanentAI(list, sa, true); } - tgt.addTarget(t); + sa.getTargets().add(t); list.remove(t); hasCreature = false; @@ -170,7 +170,7 @@ public class ControlGainAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { - if (sa.getTarget() == null) { + if (sa.getTargetRestrictions() == null) { if (mandatory) { return true; } @@ -184,7 +184,7 @@ public class ControlGainAi extends SpellAbilityAi { @Override public boolean chkAIDrawback(SpellAbility sa, final Player ai) { final Game game = ai.getGame(); - if ((sa.getTarget() == null) || !sa.getTarget().doesTarget()) { + if ((sa.getTargetRestrictions() == null) || !sa.getTargetRestrictions().doesTarget()) { if (sa.hasParam("AllValid")) { List tgtCards = CardLists.filterControlledBy(game.getCardsIn(ZoneType.Battlefield), ai.getOpponent()); tgtCards = AbilityUtils.filterListByType(tgtCards, sa.getParam("AllValid"), sa); diff --git a/src/main/java/forge/card/ability/ai/CopyPermanentAi.java b/src/main/java/forge/card/ability/ai/CopyPermanentAi.java index 226b7154690..ada81a66d22 100644 --- a/src/main/java/forge/card/ability/ai/CopyPermanentAi.java +++ b/src/main/java/forge/card/ability/ai/CopyPermanentAi.java @@ -11,7 +11,7 @@ import forge.CardLists; import forge.CardPredicates.Presets; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtilCard; import forge.game.phase.PhaseType; import forge.game.player.Player; @@ -53,7 +53,7 @@ public class CopyPermanentAi extends SpellAbilityAi { // //// // Targeting - final Target abTgt = sa.getTarget(); + final TargetRestrictions abTgt = sa.getTargetRestrictions(); if (abTgt != null) { List list = aiPlayer.getGame().getCardsIn(ZoneType.Battlefield); @@ -66,13 +66,13 @@ public class CopyPermanentAi extends SpellAbilityAi { return !vars.containsKey("RemAIDeck"); } }); - abTgt.resetTargets(); + sa.resetTargets(); // target loop - while (abTgt.getNumTargeted() < abTgt.getMaxTargets(sa.getSourceCard(), sa)) { + while (sa.getTargets().getNumTargeted() < abTgt.getMaxTargets(sa.getSourceCard(), sa)) { if (list.isEmpty()) { - if ((abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) - || (abTgt.getNumTargeted() == 0)) { - abTgt.resetTargets(); + if ((sa.getTargets().getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) + || (sa.getTargets().getNumTargeted() == 0)) { + sa.resetTargets(); return false; } else { // TODO is this good enough? for up to amounts? @@ -94,9 +94,9 @@ public class CopyPermanentAi extends SpellAbilityAi { } if (choice == null) { // can't find anything left - if ((abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) - || (abTgt.getNumTargeted() == 0)) { - abTgt.resetTargets(); + if ((sa.getTargets().getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) + || (sa.getTargets().getNumTargeted() == 0)) { + sa.resetTargets(); return false; } else { // TODO is this good enough? for up to amounts? @@ -104,7 +104,7 @@ public class CopyPermanentAi extends SpellAbilityAi { } } list.remove(choice); - abTgt.addTarget(choice); + sa.getTargets().add(choice); } } else { // if no targeting, it should always be ok diff --git a/src/main/java/forge/card/ability/ai/CounterAi.java b/src/main/java/forge/card/ability/ai/CounterAi.java index 17b56ec66de..5512eb50280 100644 --- a/src/main/java/forge/card/ability/ai/CounterAi.java +++ b/src/main/java/forge/card/ability/ai/CounterAi.java @@ -6,7 +6,7 @@ import forge.card.ability.SpellAbilityAi; import forge.card.cardfactory.CardFactoryUtil; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilMana; @@ -35,7 +35,7 @@ public class CounterAi extends SpellAbilityAi { } } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { final SpellAbility topSA = game.getStack().peekAbility(); @@ -48,9 +48,9 @@ public class CounterAi extends SpellAbilityAi { return false; } - tgt.resetTargets(); + sa.resetTargets(); if (sa.canTargetSpellAbility(topSA)) { - tgt.addTarget(topSA); + sa.getTargets().add(topSA); } else { return false; } @@ -108,7 +108,7 @@ public class CounterAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { final Game game = ai.getGame(); if (game.getStack().isEmpty()) { @@ -119,9 +119,9 @@ public class CounterAi extends SpellAbilityAi { return false; } - tgt.resetTargets(); + sa.resetTargets(); if (sa.canTargetSpellAbility(topSA)) { - tgt.addTarget(topSA); + sa.getTargets().add(topSA); } else { return false; } diff --git a/src/main/java/forge/card/ability/ai/CountersMoveAi.java b/src/main/java/forge/card/ability/ai/CountersMoveAi.java index 68b3f13c9d7..02997d2dc50 100644 --- a/src/main/java/forge/card/ability/ai/CountersMoveAi.java +++ b/src/main/java/forge/card/ability/ai/CountersMoveAi.java @@ -9,7 +9,7 @@ import forge.CounterType; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtilCard; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -48,7 +48,7 @@ public class CountersMoveAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { final Card host = sa.getSourceCard(); - final Target abTgt = sa.getTarget(); + final TargetRestrictions abTgt = sa.getTargetRestrictions(); final String type = sa.getParam("CounterType"); final String amountStr = sa.getParam("CounterNum"); int amount = 0; @@ -124,7 +124,7 @@ public class CountersMoveAi extends SpellAbilityAi { // TODO - I think choice can be null here. Is that ok for // addTarget()? - abTgt.addTarget(choice); + sa.getTargets().add(choice); } return chance; diff --git a/src/main/java/forge/card/ability/ai/CountersPutAi.java b/src/main/java/forge/card/ability/ai/CountersPutAi.java index 3f2e9bd8662..058ad557673 100644 --- a/src/main/java/forge/card/ability/ai/CountersPutAi.java +++ b/src/main/java/forge/card/ability/ai/CountersPutAi.java @@ -13,7 +13,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCost; @@ -32,7 +32,7 @@ public class CountersPutAi extends SpellAbilityAi { // what the expected targets could be final Random r = MyRandom.getRandom(); final Cost abCost = sa.getPayCosts(); - final Target abTgt = sa.getTarget(); + final TargetRestrictions abTgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); List list; Card choice = null; @@ -89,7 +89,7 @@ public class CountersPutAi extends SpellAbilityAi { // Targeting if (abTgt != null) { - abTgt.resetTargets(); + sa.resetTargets(); // target loop list = CardLists.filter(player.getCardsIn(ZoneType.Battlefield), new Predicate() { @@ -104,11 +104,11 @@ public class CountersPutAi extends SpellAbilityAi { if (list.size() < abTgt.getMinTargets(source, sa)) { return false; } - while (abTgt.getNumTargeted() < abTgt.getMaxTargets(sa.getSourceCard(), sa)) { + while (sa.getTargets().getNumTargeted() < abTgt.getMaxTargets(sa.getSourceCard(), sa)) { if (list.isEmpty()) { - if ((abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) - || (abTgt.getNumTargeted() == 0)) { - abTgt.resetTargets(); + if ((sa.getTargets().getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) + || (sa.getTargets().getNumTargeted() == 0)) { + sa.resetTargets(); return false; } else { // TODO is this good enough? for up to amounts? @@ -123,9 +123,9 @@ public class CountersPutAi extends SpellAbilityAi { } if (choice == null) { // can't find anything left - if ((abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) - || (abTgt.getNumTargeted() == 0)) { - abTgt.resetTargets(); + if ((sa.getTargets().getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) + || (sa.getTargets().getNumTargeted() == 0)) { + sa.resetTargets(); return false; } else { // TODO is this good enough? for up to amounts? @@ -134,7 +134,7 @@ public class CountersPutAi extends SpellAbilityAi { } list.remove(choice); - abTgt.addTarget(choice); + sa.getTargets().add(choice); if (divided) { abTgt.addDividedAllocation(choice, amount); @@ -175,7 +175,7 @@ public class CountersPutAi extends SpellAbilityAi { @Override public boolean chkAIDrawback(final SpellAbility sa, Player ai) { boolean chance = true; - final Target abTgt = sa.getTarget(); + final TargetRestrictions abTgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); Card choice = null; final String type = sa.getParam("CounterType"); @@ -193,9 +193,9 @@ public class CountersPutAi extends SpellAbilityAi { return false; } - abTgt.resetTargets(); + sa.resetTargets(); // target loop - while (abTgt.getNumTargeted() < abTgt.getMaxTargets(sa.getSourceCard(), sa)) { + while (sa.getTargets().getNumTargeted() < abTgt.getMaxTargets(sa.getSourceCard(), sa)) { list = CardLists.filter(list, new Predicate() { @Override public boolean apply(final Card c) { @@ -203,9 +203,9 @@ public class CountersPutAi extends SpellAbilityAi { } }); if (list.size() == 0) { - if ((abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) - || (abTgt.getNumTargeted() == 0)) { - abTgt.resetTargets(); + if ((sa.getTargets().getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) + || (sa.getTargets().getNumTargeted() == 0)) { + sa.resetTargets(); return false; } else { break; @@ -219,9 +219,9 @@ public class CountersPutAi extends SpellAbilityAi { } if (choice == null) { // can't find anything left - if ((abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) - || (abTgt.getNumTargeted() == 0)) { - abTgt.resetTargets(); + if ((sa.getTargets().getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) + || (sa.getTargets().getNumTargeted() == 0)) { + sa.resetTargets(); return false; } else { // TODO is this good enough? for up to amounts? @@ -229,7 +229,7 @@ public class CountersPutAi extends SpellAbilityAi { } } list.remove(choice); - abTgt.addTarget(choice); + sa.getTargets().add(choice); if (divided) { abTgt.addDividedAllocation(choice, amount); break; @@ -242,7 +242,7 @@ public class CountersPutAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { - final Target abTgt = sa.getTarget(); + final TargetRestrictions abTgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); // boolean chance = true; boolean preferred = true; @@ -316,7 +316,7 @@ public class CountersPutAi extends SpellAbilityAi { // TODO - I think choice can be null here. Is that ok for // addTarget()? - abTgt.addTarget(choice); + sa.getTargets().add(choice); } return true; diff --git a/src/main/java/forge/card/ability/ai/CountersPutAllAi.java b/src/main/java/forge/card/ability/ai/CountersPutAllAi.java index 3fe9e66f4a8..5d99759cf02 100644 --- a/src/main/java/forge/card/ability/ai/CountersPutAllAi.java +++ b/src/main/java/forge/card/ability/ai/CountersPutAllAi.java @@ -12,7 +12,7 @@ import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.AbilitySub; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilMana; import forge.game.phase.PhaseHandler; @@ -36,7 +36,7 @@ public class CountersPutAllAi extends SpellAbilityAi { final String amountStr = sa.getParam("CounterNum"); final String valid = sa.getParam("ValidCards"); final boolean curse = sa.isCurse(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); hList = CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid, source.getController(), source); cList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source); @@ -58,7 +58,7 @@ public class CountersPutAllAi extends SpellAbilityAi { if (tgt != null) { Player pl = curse ? ai.getOpponent() : ai; - tgt.addTarget(pl); + sa.getTargets().add(pl); hList = CardLists.filterControlledBy(hList, pl); cList = CardLists.filterControlledBy(cList, pl); diff --git a/src/main/java/forge/card/ability/ai/CountersRemoveAi.java b/src/main/java/forge/card/ability/ai/CountersRemoveAi.java index db6c086350d..0db04fe86b1 100644 --- a/src/main/java/forge/card/ability/ai/CountersRemoveAi.java +++ b/src/main/java/forge/card/ability/ai/CountersRemoveAi.java @@ -5,7 +5,7 @@ import forge.CounterType; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCost; import forge.game.phase.PhaseType; @@ -19,7 +19,7 @@ public class CountersRemoveAi extends SpellAbilityAi { // based on what // the expected targets could be final Cost abCost = sa.getPayCosts(); - Target abTgt = sa.getTarget(); + TargetRestrictions abTgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); // List list; // Card choice = null; diff --git a/src/main/java/forge/card/ability/ai/DamageAllAi.java b/src/main/java/forge/card/ability/ai/DamageAllAi.java index 9cc4fbf4f6a..0ee290f316c 100644 --- a/src/main/java/forge/card/ability/ai/DamageAllAi.java +++ b/src/main/java/forge/card/ability/ai/DamageAllAi.java @@ -12,7 +12,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCombat; import forge.game.ai.ComputerUtilCost; @@ -51,10 +51,10 @@ public class DamageAllAi extends SpellAbilityAi { final List humanList = this.getKillableCreatures(sa, opp, dmg); List computerList = this.getKillableCreatures(sa, ai, dmg); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null && sa.canTarget(opp)) { - tgt.resetTargets(); - sa.getTarget().addTarget(opp); + sa.resetTargets(); + sa.getTargets().add(opp); computerList = new ArrayList(); } @@ -124,11 +124,11 @@ public class DamageAllAi extends SpellAbilityAi { Player enemy = ai.getOpponent(); final List humanList = this.getKillableCreatures(sa, enemy, dmg); List computerList = this.getKillableCreatures(sa, ai, dmg); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null && sa.canTarget(enemy)) { - tgt.resetTargets(); - sa.getTarget().addTarget(enemy); + sa.resetTargets(); + sa.getTargets().add(enemy); computerList.clear(); } // Don't get yourself killed @@ -208,11 +208,11 @@ public class DamageAllAi extends SpellAbilityAi { Player enemy = ai.getOpponent(); final List humanList = this.getKillableCreatures(sa, enemy, dmg); List computerList = this.getKillableCreatures(sa, ai, dmg); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null && sa.canTarget(enemy)) { - tgt.resetTargets(); - sa.getTarget().addTarget(enemy); + sa.resetTargets(); + sa.getTargets().add(enemy); computerList.clear(); } diff --git a/src/main/java/forge/card/ability/ai/DamageDealAi.java b/src/main/java/forge/card/ability/ai/DamageDealAi.java index 26723aedd75..080a89e3b4f 100644 --- a/src/main/java/forge/card/ability/ai/DamageDealAi.java +++ b/src/main/java/forge/card/ability/ai/DamageDealAi.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.Random; import com.google.common.base.Predicate; +import com.google.common.collect.Lists; import forge.Card; import forge.CardLists; @@ -13,7 +14,7 @@ import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.AbilitySub; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCard; @@ -104,11 +105,10 @@ public class DamageDealAi extends DamageAiBase { if (damage.equals("X") && source.getSVar(damage).equals("Count$xPaid")) { // If I can kill my target by paying less mana, do it - final Target tgt = sa.getTarget(); - if (tgt != null && tgt.getTargetPlayers().isEmpty() && !sa.hasParam("DividedAsYouChoose")) { + if (sa.usesTargeting() && !sa.getTargets().isTargetingAnyPlayer() && !sa.hasParam("DividedAsYouChoose")) { int actualPay = 0; final boolean noPrevention = sa.hasParam("NoPrevention"); - for (final Card c : tgt.getTargetCards()) { + for (final Card c : sa.getTargets().getTargetCards()) { final int adjDamage = ComputerUtilCombat.getEnoughDamageToKill(c, dmg, source, false, noPrevention); if ((adjDamage > actualPay) && (adjDamage <= dmg)) { actualPay = adjDamage; @@ -135,20 +135,20 @@ public class DamageDealAi extends DamageAiBase { * a boolean. * @return a {@link forge.Card} object. */ - private Card dealDamageChooseTgtC(final Player ai, final SpellAbility saMe, final int d, final boolean noPrevention, + private Card dealDamageChooseTgtC(final Player ai, final SpellAbility sa, final int d, final boolean noPrevention, final Player pl, final boolean mandatory) { // wait until stack is empty (prevents duplicate kills) - if (!saMe.isTrigger() && !ai.getGame().getStack().isEmpty()) { + if (!sa.isTrigger() && !ai.getGame().getStack().isEmpty()) { return null; } - final Target tgt = saMe.getTarget(); - final Card source = saMe.getSourceCard(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); + final Card source = sa.getSourceCard(); List hPlay = CardLists.getValidCards(pl.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, source); - final List objects = tgt.getTargets(); - if (saMe.hasParam("TargetUnique")) { - objects.addAll(saMe.getUniqueTargets()); + final List objects = Lists.newArrayList(sa.getTargets().getTargets()); + if (sa.hasParam("TargetUnique")) { + objects.addAll(sa.getUniqueTargets()); } for (final Object o : objects) { if (o instanceof Card) { @@ -158,7 +158,7 @@ public class DamageDealAi extends DamageAiBase { } } } - hPlay = CardLists.getTargetableCards(hPlay, saMe); + hPlay = CardLists.getTargetableCards(hPlay, sa); final List killables = CardLists.filter(hPlay, new Predicate() { @Override @@ -204,7 +204,7 @@ public class DamageDealAi extends DamageAiBase { * @return a boolean. */ private boolean damageTargetAI(final Player ai, final SpellAbility saMe, final int dmg) { - final Target tgt = saMe.getTarget(); + final TargetRestrictions tgt = saMe.getTargetRestrictions(); if (tgt == null) { return this.damageChooseNontargeted(ai, saMe, dmg); @@ -222,38 +222,38 @@ public class DamageDealAi extends DamageAiBase { * damageChoosingTargets. *

* - * @param saMe + * @param sa * a {@link forge.card.spellability.SpellAbility} object. * @param tgt - * a {@link forge.card.spellability.Target} object. + * a {@link forge.card.spellability.TargetRestrictions} object. * @param dmg * a int. * @param mandatory * a boolean. * @return a boolean. */ - private boolean damageChoosingTargets(final Player ai, final SpellAbility saMe, final Target tgt, int dmg, + private boolean damageChoosingTargets(final Player ai, final SpellAbility sa, final TargetRestrictions tgt, int dmg, final boolean isTrigger, final boolean mandatory) { - final Card source = saMe.getSourceCard(); - final boolean noPrevention = saMe.hasParam("NoPrevention"); + final Card source = sa.getSourceCard(); + final boolean noPrevention = sa.hasParam("NoPrevention"); final Game game = source.getGame(); final PhaseHandler phase = game.getPhaseHandler(); - final boolean divided = saMe.hasParam("DividedAsYouChoose"); + final boolean divided = sa.hasParam("DividedAsYouChoose"); // target loop - tgt.resetTargets(); + sa.resetTargets(); Player enemy = ai.getOpponent(); - if (tgt.getMaxTargets(source, saMe) <= 0) { + if (tgt.getMaxTargets(source, sa) <= 0) { return false; } - while (tgt.getNumTargeted() < tgt.getMaxTargets(source, saMe)) { + while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) { if (tgt.canTgtCreatureAndPlayer()) { - if (this.shouldTgtP(ai, saMe, dmg, noPrevention)) { - tgt.addTarget(enemy); + if (this.shouldTgtP(ai, sa, dmg, noPrevention)) { + sa.getTargets().add(enemy); if (divided) { tgt.addDividedAllocation(enemy, dmg); break; @@ -261,9 +261,9 @@ public class DamageDealAi extends DamageAiBase { continue; } - final Card c = this.dealDamageChooseTgtC(ai, saMe, dmg, noPrevention, enemy, false); + final Card c = this.dealDamageChooseTgtC(ai, sa, dmg, noPrevention, enemy, false); if (c != null) { - tgt.addTarget(c); + sa.getTargets().add(c); if (divided) { final int assignedDamage = ComputerUtilCombat.getEnoughDamageToKill(c, dmg, source, false, noPrevention); if (assignedDamage <= dmg) { @@ -284,21 +284,21 @@ public class DamageDealAi extends DamageAiBase { // TODO: add check here if card is about to die from something // on the stack // or from taking combat damage - final boolean freePing = isTrigger || saMe.getPayCosts() == null || tgt.getNumTargeted() > 0 - || (phase.is(PhaseType.END_OF_TURN) && saMe.isAbility() && phase.getNextTurn().equals(ai)) - || (phase.is(PhaseType.MAIN2) && saMe.getRestrictions().getPlaneswalker()); + final boolean freePing = isTrigger || sa.getPayCosts() == null || sa.getTargets().getNumTargeted() > 0 + || (phase.is(PhaseType.END_OF_TURN) && sa.isAbility() && phase.getNextTurn().equals(ai)) + || (phase.is(PhaseType.MAIN2) && sa.getRestrictions().getPlaneswalker()); - if (freePing && saMe.canTarget(enemy)) { - tgt.addTarget(enemy); + if (freePing && sa.canTarget(enemy)) { + sa.getTargets().add(enemy); if (divided) { tgt.addDividedAllocation(enemy, dmg); break; } } } else if (tgt.canTgtCreature()) { - final Card c = this.dealDamageChooseTgtC(ai, saMe, dmg, noPrevention, enemy, mandatory); + final Card c = this.dealDamageChooseTgtC(ai, sa, dmg, noPrevention, enemy, mandatory); if (c != null) { - tgt.addTarget(c); + sa.getTargets().add(c); if (divided) { final int assignedDamage = ComputerUtilCombat.getEnoughDamageToKill(c, dmg, source, false, noPrevention); if (assignedDamage <= dmg) { @@ -315,12 +315,12 @@ public class DamageDealAi extends DamageAiBase { // TODO: Improve Damage, we shouldn't just target the player just // because we can - else if (saMe.canTarget(enemy)) { + else if (sa.canTarget(enemy)) { if ((phase.is(PhaseType.END_OF_TURN) && phase.getNextTurn().equals(ai)) - || (SpellAbilityAi.isSorcerySpeed(saMe) && phase.is(PhaseType.MAIN2)) - || saMe.getPayCosts() == null || isTrigger - || this.shouldTgtP(ai, saMe, dmg, noPrevention)) { - tgt.addTarget(enemy); + || (SpellAbilityAi.isSorcerySpeed(sa) && phase.is(PhaseType.MAIN2)) + || sa.getPayCosts() == null || isTrigger + || this.shouldTgtP(ai, sa, dmg, noPrevention)) { + sa.getTargets().add(enemy); if (divided) { tgt.addDividedAllocation(enemy, dmg); break; @@ -329,13 +329,13 @@ public class DamageDealAi extends DamageAiBase { } } // fell through all the choices, no targets left? - if (((tgt.getNumTargeted() < tgt.getMinTargets(source, saMe)) || (tgt.getNumTargeted() == 0))) { + if (((sa.getTargets().getNumTargeted() < tgt.getMinTargets(source, sa)) || (sa.getTargets().getNumTargeted() == 0))) { if (!mandatory) { - tgt.resetTargets(); + sa.resetTargets(); return false; } else { // If the trigger is mandatory, gotta choose my own stuff now - return this.damageChooseRequiredTargets(ai, saMe, tgt, dmg, mandatory); + return this.damageChooseRequiredTargets(ai, sa, tgt, dmg, mandatory); } } else { // TODO is this good enough? for up to amounts? @@ -406,28 +406,28 @@ public class DamageDealAi extends DamageAiBase { * damageChooseRequiredTargets. *

* - * @param saMe + * @param sa * a {@link forge.card.spellability.SpellAbility} object. * @param tgt - * a {@link forge.card.spellability.Target} object. + * a {@link forge.card.spellability.TargetRestrictions} object. * @param dmg * a int. * @param mandatory * a boolean. * @return a boolean. */ - private boolean damageChooseRequiredTargets(final Player ai, final SpellAbility saMe, final Target tgt, final int dmg, + private boolean damageChooseRequiredTargets(final Player ai, final SpellAbility sa, final TargetRestrictions tgt, final int dmg, final boolean mandatory) { // this is for Triggered targets that are mandatory - final boolean noPrevention = saMe.hasParam("NoPrevention"); - final boolean divided = saMe.hasParam("DividedAsYouChoose"); + final boolean noPrevention = sa.hasParam("NoPrevention"); + final boolean divided = sa.hasParam("DividedAsYouChoose"); - while (tgt.getNumTargeted() < tgt.getMinTargets(saMe.getSourceCard(), saMe)) { + while (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { // TODO: Consider targeting the planeswalker if (tgt.canTgtCreature()) { - final Card c = this.dealDamageChooseTgtC(ai, saMe, dmg, noPrevention, ai, mandatory); + final Card c = this.dealDamageChooseTgtC(ai, sa, dmg, noPrevention, ai, mandatory); if (c != null) { - tgt.addTarget(c); + sa.getTargets().add(c); if (divided) { tgt.addDividedAllocation(c, dmg); break; @@ -436,8 +436,8 @@ public class DamageDealAi extends DamageAiBase { } } - if (saMe.canTarget(ai)) { - if (tgt.addTarget(ai)) { + if (sa.canTarget(ai)) { + if (sa.getTargets().add(ai)) { if (divided) { tgt.addDividedAllocation(ai, dmg); break; @@ -466,7 +466,7 @@ public class DamageDealAi extends DamageAiBase { source.setSVar("PayX", Integer.toString(dmg)); } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt == null) { // If it's not mandatory check a few things if (!mandatory && !this.damageChooseNontargeted(ai, sa, dmg)) { @@ -481,12 +481,12 @@ public class DamageDealAi extends DamageAiBase { // If I can kill my target by paying less mana, do it int actualPay = 0; final boolean noPrevention = sa.hasParam("NoPrevention"); - final List cards = tgt.getTargetCards(); + //target is a player - if (cards.isEmpty()) { + if (!sa.getTargets().isTargetingAnyCard()) { actualPay = dmg; } - for (final Card c : cards) { + for (final Card c : sa.getTargets().getTargetCards()) { final int adjDamage = ComputerUtilCombat.getEnoughDamageToKill(c, dmg, source, false, noPrevention); if (adjDamage > actualPay) { actualPay = adjDamage; diff --git a/src/main/java/forge/card/ability/ai/DamageEachAi.java b/src/main/java/forge/card/ability/ai/DamageEachAi.java index f2cdd5293e9..d21feb44333 100644 --- a/src/main/java/forge/card/ability/ai/DamageEachAi.java +++ b/src/main/java/forge/card/ability/ai/DamageEachAi.java @@ -3,7 +3,7 @@ package forge.card.ability.ai; import forge.card.ability.AbilityUtils; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; public class DamageEachAi extends DamageAiBase { @@ -13,11 +13,11 @@ public class DamageEachAi extends DamageAiBase { */ @Override protected boolean canPlayAI(Player ai, SpellAbility sa) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null && sa.canTarget(ai.getOpponent())) { - tgt.resetTargets(); - sa.getTarget().addTarget(ai.getOpponent()); + sa.resetTargets(); + sa.getTargets().add(ai.getOpponent()); } final String damage = sa.getParam("NumDmg"); diff --git a/src/main/java/forge/card/ability/ai/DamagePreventAi.java b/src/main/java/forge/card/ability/ai/DamagePreventAi.java index 7df9f7ad0d3..2f01f74a1fb 100644 --- a/src/main/java/forge/card/ability/ai/DamagePreventAi.java +++ b/src/main/java/forge/card/ability/ai/DamagePreventAi.java @@ -11,7 +11,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCard; @@ -49,7 +49,7 @@ public class DamagePreventAi extends SpellAbilityAi { return false; } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt == null) { // As far as I can tell these Defined Cards will only have one of // them @@ -57,7 +57,7 @@ public class DamagePreventAi extends SpellAbilityAi { // react to threats on the stack if (!game.getStack().isEmpty()) { - final ArrayList threatenedObjects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa); + final List threatenedObjects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa); for (final Object o : objects) { if (threatenedObjects.contains(o)) { chance = true; @@ -91,14 +91,14 @@ public class DamagePreventAi extends SpellAbilityAi { // react to threats on the stack else if (!game.getStack().isEmpty()) { - tgt.resetTargets(); + sa.resetTargets(); // check stack for something on the stack will kill anything i // control final ArrayList objects = new ArrayList(); // AbilityFactory.predictThreatenedObjects(af); if (objects.contains(ai)) { - tgt.addTarget(ai); + sa.getTargets().add(ai); } final List threatenedTargets = new ArrayList(); @@ -114,7 +114,7 @@ public class DamagePreventAi extends SpellAbilityAi { if (!threatenedTargets.isEmpty()) { // Choose "best" of the remaining to save - tgt.addTarget(ComputerUtilCard.getBestCreatureAI(threatenedTargets)); + sa.getTargets().add(ComputerUtilCard.getBestCreatureAI(threatenedTargets)); chance = true; } @@ -123,7 +123,7 @@ public class DamagePreventAi extends SpellAbilityAi { if (sa.canTarget(ai) && ComputerUtilCombat.wouldLoseLife(ai, game.getCombat()) && (ComputerUtilCombat.lifeInDanger(ai, game.getCombat()) || sa.isAbility()) && game.getPhaseHandler().isPlayerTurn(ai.getOpponent())) { - tgt.addTarget(ai); + sa.getTargets().add(ai); chance = true; } else { // filter AIs battlefield by what I can target @@ -139,7 +139,7 @@ public class DamagePreventAi extends SpellAbilityAi { for (final Card c : combatants) { if (ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) { - tgt.addTarget(c); + sa.getTargets().add(c); chance = true; break; } @@ -153,7 +153,7 @@ public class DamagePreventAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { boolean chance = false; - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt == null) { // If there's no target on the trigger, just say yes. chance = true; @@ -179,8 +179,8 @@ public class DamagePreventAi extends SpellAbilityAi { */ private boolean preventDamageMandatoryTarget(final Player ai, final SpellAbility sa, final boolean mandatory) { - final Target tgt = sa.getTarget(); - tgt.resetTargets(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); + sa.resetTargets(); // filter AIs battlefield by what I can target final Game game = ai.getGame(); List targetables = game.getCardsIn(ZoneType.Battlefield); @@ -201,7 +201,7 @@ public class DamagePreventAi extends SpellAbilityAi { if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) { for (final Card c : combatants) { if (ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) { - tgt.addTarget(c); + sa.getTargets().add(c); return true; } } @@ -210,11 +210,11 @@ public class DamagePreventAi extends SpellAbilityAi { // TODO see if something on the stack is about to kill something I // can target - tgt.addTarget(combatants.get(0)); + sa.getTargets().add(combatants.get(0)); return true; } - tgt.addTarget(ComputerUtilCard.getCheapestPermanentAI(targetables, sa, true)); + sa.getTargets().add(ComputerUtilCard.getCheapestPermanentAI(targetables, sa, true)); return true; } diff --git a/src/main/java/forge/card/ability/ai/DebuffAi.java b/src/main/java/forge/card/ability/ai/DebuffAi.java index 7f9c45f1c79..20ca1d693dc 100644 --- a/src/main/java/forge/card/ability/ai/DebuffAi.java +++ b/src/main/java/forge/card/ability/ai/DebuffAi.java @@ -13,7 +13,7 @@ import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbilityRestriction; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCost; import forge.game.phase.PhaseHandler; @@ -30,7 +30,7 @@ public class DebuffAi extends SpellAbilityAi { protected boolean canPlayAI(final Player ai, final SpellAbility sa) { // if there is no target and host card isn't in play, don't activate final Card source = sa.getSourceCard(); - if ((sa.getTarget() == null) && !source.isInPlay()) { + if ((sa.getTargetRestrictions() == null) && !source.isInPlay()) { return false; } @@ -70,7 +70,7 @@ public class DebuffAi extends SpellAbilityAi { return false; } - if ((sa.getTarget() == null) || !sa.getTarget().doesTarget()) { + if ((sa.getTargetRestrictions() == null) || !sa.getTargetRestrictions().doesTarget()) { List cards = AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa); if (!cards.isEmpty()) { @@ -97,7 +97,7 @@ public class DebuffAi extends SpellAbilityAi { @Override public boolean chkAIDrawback(SpellAbility sa, Player ai) { - if ((sa.getTarget() == null) || !sa.getTarget().doesTarget()) { + if ((sa.getTargetRestrictions() == null) || !sa.getTargetRestrictions().doesTarget()) { // TODO - copied from AF_Pump.pumpDrawbackAI() - what should be // here? } else { @@ -128,8 +128,8 @@ public class DebuffAi extends SpellAbilityAi { return false; } - final Target tgt = sa.getTarget(); - tgt.resetTargets(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); + sa.resetTargets(); List list = getCurseCreatures(ai, sa, kws); list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard()); @@ -144,17 +144,17 @@ public class DebuffAi extends SpellAbilityAi { return mandatory && debuffMandatoryTarget(ai, sa, mandatory); } - while (tgt.getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) { Card t = null; // boolean goodt = false; if (list.isEmpty()) { - if ((tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (tgt.getNumTargeted() == 0)) { + if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (sa.getTargets().getNumTargeted() == 0)) { if (mandatory) { return debuffMandatoryTarget(ai, sa, mandatory); } - tgt.resetTargets(); + sa.resetTargets(); return false; } else { // TODO is this good enough? for up to amounts? @@ -163,7 +163,7 @@ public class DebuffAi extends SpellAbilityAi { } t = ComputerUtilCard.getBestCreatureAI(list); - tgt.addTarget(t); + sa.getTargets().add(t); list.remove(t); } @@ -216,16 +216,16 @@ public class DebuffAi extends SpellAbilityAi { */ private boolean debuffMandatoryTarget(final Player ai, final SpellAbility sa, final boolean mandatory) { List list = ai.getGame().getCardsIn(ZoneType.Battlefield); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard()); if (list.size() < tgt.getMinTargets(sa.getSourceCard(), sa)) { - tgt.resetTargets(); + sa.resetTargets(); return false; } // Remove anything that's already been targeted - for (final Card c : tgt.getTargetCards()) { + for (final Card c : sa.getTargets().getTargetCards()) { list.remove(c); } @@ -233,7 +233,7 @@ public class DebuffAi extends SpellAbilityAi { final List forced = CardLists.filterControlledBy(list, ai); final Card source = sa.getSourceCard(); - while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) { if (pref.isEmpty()) { break; } @@ -247,10 +247,10 @@ public class DebuffAi extends SpellAbilityAi { pref.remove(c); - tgt.addTarget(c); + sa.getTargets().add(c); } - while (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { if (forced.isEmpty()) { break; } @@ -266,11 +266,11 @@ public class DebuffAi extends SpellAbilityAi { forced.remove(c); - tgt.addTarget(c); + sa.getTargets().add(c); } - if (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { - tgt.resetTargets(); + if (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { + sa.resetTargets(); return false; } @@ -281,7 +281,7 @@ public class DebuffAi extends SpellAbilityAi { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { final List kws = sa.hasParam("Keywords") ? Arrays.asList(sa.getParam("Keywords").split(" & ")) : new ArrayList(); - if (sa.getTarget() == null) { + if (sa.getTargetRestrictions() == null) { if (mandatory) { return true; } diff --git a/src/main/java/forge/card/ability/ai/DestroyAi.java b/src/main/java/forge/card/ability/ai/DestroyAi.java index 0ef05b45e15..d52757477c7 100644 --- a/src/main/java/forge/card/ability/ai/DestroyAi.java +++ b/src/main/java/forge/card/ability/ai/DestroyAi.java @@ -15,7 +15,7 @@ import forge.card.cost.Cost; import forge.card.cost.CostPart; import forge.card.cost.CostSacrifice; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCost; @@ -41,7 +41,7 @@ public class DestroyAi extends SpellAbilityAi { // based on what the expected targets could be final Random r = MyRandom.getRandom(); final Cost abCost = sa.getPayCosts(); - final Target abTgt = sa.getTarget(); + final TargetRestrictions abTgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); final boolean noRegen = sa.hasParam("NoRegen"); List list; @@ -65,7 +65,7 @@ public class DestroyAi extends SpellAbilityAi { // Targeting if (abTgt != null) { - abTgt.resetTargets(); + sa.resetTargets(); list = CardLists.getTargetableCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), sa); list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source); if (sa.hasParam("AITgts")) { @@ -113,11 +113,11 @@ public class DestroyAi extends SpellAbilityAi { return false; } // target loop - while (abTgt.getNumTargeted() < abTgt.getMaxTargets(sa.getSourceCard(), sa)) { + while (sa.getTargets().getNumTargeted() < abTgt.getMaxTargets(sa.getSourceCard(), sa)) { if (list.size() == 0) { - if ((abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) - || (abTgt.getNumTargeted() == 0)) { - abTgt.resetTargets(); + if ((sa.getTargets().getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) + || (sa.getTargets().getNumTargeted() == 0)) { + sa.resetTargets(); return false; } else { // TODO is this good enough? for up to amounts? @@ -136,9 +136,9 @@ public class DestroyAi extends SpellAbilityAi { } if (choice == null) { // can't find anything left - if ((abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) - || (abTgt.getNumTargeted() == 0)) { - abTgt.resetTargets(); + if ((sa.getTargets().getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) + || (sa.getTargets().getNumTargeted() == 0)) { + sa.resetTargets(); return false; } else { // TODO is this good enough? for up to amounts? @@ -146,7 +146,7 @@ public class DestroyAi extends SpellAbilityAi { } } list.remove(choice); - abTgt.addTarget(choice); + sa.getTargets().add(choice); } } else { if (sa.hasParam("Defined")) { @@ -164,7 +164,7 @@ public class DestroyAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); final boolean noRegen = sa.hasParam("NoRegen"); final Player opp = ai.getOpponent(); @@ -178,7 +178,7 @@ public class DestroyAi extends SpellAbilityAi { return false; } - tgt.resetTargets(); + sa.resetTargets(); List preferred = CardLists.getNotKeyword(list, "Indestructible"); preferred = CardLists.filterControlledBy(preferred, opp); @@ -200,12 +200,12 @@ public class DestroyAi extends SpellAbilityAi { list.remove(c); } - while (tgt.getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) { if (preferred.size() == 0) { - if ((tgt.getNumTargeted() == 0) - || (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa))) { + if ((sa.getTargets().getNumTargeted() == 0) + || (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa))) { if (!mandatory) { - tgt.resetTargets(); + sa.resetTargets(); return false; } else { break; @@ -222,12 +222,12 @@ public class DestroyAi extends SpellAbilityAi { } else { c = ComputerUtilCard.getMostExpensivePermanentAI(preferred, sa, false); } - tgt.addTarget(c); + sa.getTargets().add(c); preferred.remove(c); } } - while (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { if (list.size() == 0) { break; } else { @@ -237,12 +237,12 @@ public class DestroyAi extends SpellAbilityAi { } else { c = ComputerUtilCard.getCheapestPermanentAI(list, sa, false); } - tgt.addTarget(c); + sa.getTargets().add(c); list.remove(c); } } - if (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { + if (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { return false; } } else { diff --git a/src/main/java/forge/card/ability/ai/DestroyAllAi.java b/src/main/java/forge/card/ability/ai/DestroyAllAi.java index cf61e8a5b57..f403f25b5cc 100644 --- a/src/main/java/forge/card/ability/ai/DestroyAllAi.java +++ b/src/main/java/forge/card/ability/ai/DestroyAllAi.java @@ -10,7 +10,6 @@ import forge.CardLists; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilMana; @@ -33,7 +32,6 @@ public class DestroyAllAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { final Card source = sa.getSourceCard(); - final Target tgt = sa.getTarget(); String valid = ""; if (mandatory) { return true; @@ -41,13 +39,12 @@ public class DestroyAllAi extends SpellAbilityAi { if (sa.hasParam("ValidCards")) { valid = sa.getParam("ValidCards"); } - List humanlist = - CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source); - List computerlist = - CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source); - if (sa.getTarget() != null) { - tgt.resetTargets(); - sa.getTarget().addTarget(ai.getOpponent()); + List humanlist = CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source); + List computerlist = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source); + + if (sa.usesTargeting()) { + sa.resetTargets(); + sa.getTargets().add(ai.getOpponent()); computerlist.clear(); } @@ -98,15 +95,11 @@ public class DestroyAllAi extends SpellAbilityAi { valid = valid.replace("X", Integer.toString(xPay)); } - final Target tgt = sa.getTarget(); - - List humanlist = - CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source); - List computerlist = - CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source); - if (sa.getTarget() != null) { - tgt.resetTargets(); - sa.getTarget().addTarget(ai.getOpponent()); + List humanlist = CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source); + List computerlist = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source); + if (sa.usesTargeting()) { + sa.resetTargets(); + sa.getTargets().add(ai.getOpponent()); computerlist.clear(); } diff --git a/src/main/java/forge/card/ability/ai/DigAi.java b/src/main/java/forge/card/ability/ai/DigAi.java index e0402343f11..4cd8429e955 100644 --- a/src/main/java/forge/card/ability/ai/DigAi.java +++ b/src/main/java/forge/card/ability/ai/DigAi.java @@ -6,7 +6,6 @@ import forge.Card; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.game.ai.ComputerUtil; import forge.game.phase.PhaseType; import forge.game.player.Player; @@ -24,15 +23,14 @@ public class DigAi extends SpellAbilityAi { Player opp = ai.getOpponent(); final Card host = sa.getSourceCard(); - final Target tgt = sa.getTarget(); Player libraryOwner = ai; - if (sa.getTarget() != null) { - tgt.resetTargets(); + if (sa.usesTargeting()) { + sa.resetTargets(); if (!opp.canBeTargetedBy(sa)) { return false; } else { - sa.getTarget().addTarget(opp); + sa.getTargets().add(opp); } libraryOwner = opp; } @@ -68,11 +66,9 @@ public class DigAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { - final Target tgt = sa.getTarget(); - - if (sa.getTarget() != null) { - tgt.resetTargets(); - sa.getTarget().addTarget(ai); + if (sa.usesTargeting()) { + sa.resetTargets(); + sa.getTargets().add(ai); } return true; diff --git a/src/main/java/forge/card/ability/ai/DigUntilAi.java b/src/main/java/forge/card/ability/ai/DigUntilAi.java index 0baee0c1a58..abed6fd5f16 100644 --- a/src/main/java/forge/card/ability/ai/DigUntilAi.java +++ b/src/main/java/forge/card/ability/ai/DigUntilAi.java @@ -7,7 +7,6 @@ import forge.CardLists; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.AbilitySub; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.game.ai.ComputerUtilMana; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -26,16 +25,15 @@ public class DigUntilAi extends SpellAbilityAi { final Random r = MyRandom.getRandom(); final boolean randomReturn = r.nextFloat() <= Math.pow(chance, sa.getActivationsThisTurn() + 1); - final Target tgt = sa.getTarget(); Player libraryOwner = ai; Player opp = ai.getOpponent(); - if (sa.getTarget() != null) { - tgt.resetTargets(); + if (sa.usesTargeting()) { + sa.resetTargets(); if (!opp.canBeTargetedBy(sa)) { return false; } else { - sa.getTarget().addTarget(opp); + sa.getTargets().add(opp); } libraryOwner = opp; } else { @@ -70,14 +68,12 @@ public class DigUntilAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { - final Target tgt = sa.getTarget(); - - if (sa.getTarget() != null) { - tgt.resetTargets(); + if (sa.usesTargeting()) { + sa.resetTargets(); if (sa.isCurse()) { - sa.getTarget().addTarget(ai.getOpponent()); + sa.getTargets().add(ai.getOpponent()); } else { - sa.getTarget().addTarget(ai); + sa.getTargets().add(ai); } } diff --git a/src/main/java/forge/card/ability/ai/DiscardAi.java b/src/main/java/forge/card/ability/ai/DiscardAi.java index 2c5c794ce9c..ad4b4ce9888 100644 --- a/src/main/java/forge/card/ability/ai/DiscardAi.java +++ b/src/main/java/forge/card/ability/ai/DiscardAi.java @@ -8,7 +8,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilMana; @@ -22,7 +22,7 @@ public class DiscardAi extends SpellAbilityAi { @Override protected boolean canPlayAI(Player ai, SpellAbility sa) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); final Cost abCost = sa.getPayCosts(); @@ -113,14 +113,14 @@ public class DiscardAi extends SpellAbilityAi { } // discardCanPlayAI() private boolean discardTargetAI(final Player ai, final SpellAbility sa) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); Player opp = ai.getOpponent(); if (opp.getCardsIn(ZoneType.Hand).isEmpty()) { return false; } if (tgt != null) { if (sa.canTarget(opp)) { - tgt.addTarget(opp); + sa.getTargets().add(opp); return true; } } @@ -131,14 +131,14 @@ public class DiscardAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { Player opp = ai.getOpponent(); if (!discardTargetAI(ai, sa)) { if (mandatory && sa.canTarget(opp)) { - tgt.addTarget(opp); + sa.getTargets().add(opp); } else if (mandatory && sa.canTarget(ai)) { - tgt.addTarget(ai); + sa.getTargets().add(ai); } else { return false; } @@ -159,7 +159,7 @@ public class DiscardAi extends SpellAbilityAi { public boolean chkAIDrawback(SpellAbility sa, Player ai) { // Drawback AI improvements // if parent draws cards, make sure cards in hand + cards drawn > 0 - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { return discardTargetAI(ai, sa); } diff --git a/src/main/java/forge/card/ability/ai/DrainManaAi.java b/src/main/java/forge/card/ability/ai/DrainManaAi.java index bd9c620aed3..0f45772bdf4 100644 --- a/src/main/java/forge/card/ability/ai/DrainManaAi.java +++ b/src/main/java/forge/card/ability/ai/DrainManaAi.java @@ -7,7 +7,7 @@ import forge.Card; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.util.MyRandom; @@ -17,7 +17,7 @@ public class DrainManaAi extends SpellAbilityAi { protected boolean canPlayAI(Player ai, SpellAbility sa) { // AI cannot use this properly until he can use SAs during Humans turn - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); final Player opp = ai.getOpponent(); final Random r = MyRandom.getRandom(); @@ -33,8 +33,8 @@ public class DrainManaAi extends SpellAbilityAi { return false; } } else { - tgt.resetTargets(); - tgt.addTarget(opp); + sa.resetTargets(); + sa.getTargets().add(opp); } return randomReturn; @@ -44,7 +44,7 @@ public class DrainManaAi extends SpellAbilityAi { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { final Player opp = ai.getOpponent(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); if (null == tgt) { @@ -60,8 +60,8 @@ public class DrainManaAi extends SpellAbilityAi { return true; } else { - tgt.resetTargets(); - tgt.addTarget(opp); + sa.resetTargets(); + sa.getTargets().add(opp); } return true; @@ -70,7 +70,7 @@ public class DrainManaAi extends SpellAbilityAi { @Override public boolean chkAIDrawback(SpellAbility sa, Player ai) { // AI cannot use this properly until he can use SAs during Humans turn - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); boolean randomReturn = true; @@ -82,8 +82,8 @@ public class DrainManaAi extends SpellAbilityAi { return false; } } else { - tgt.resetTargets(); - tgt.addTarget(ai.getOpponent()); + sa.resetTargets(); + sa.getTargets().add(ai.getOpponent()); } return randomReturn; diff --git a/src/main/java/forge/card/ability/ai/DrawAi.java b/src/main/java/forge/card/ability/ai/DrawAi.java index 5cb90206545..2d48b6a05c8 100644 --- a/src/main/java/forge/card/ability/ai/DrawAi.java +++ b/src/main/java/forge/card/ability/ai/DrawAi.java @@ -18,7 +18,6 @@ */ package forge.card.ability.ai; -import java.util.List; import java.util.Random; import forge.Card; @@ -30,7 +29,7 @@ import forge.card.cost.CostPart; import forge.card.cost.PaymentDecision; import forge.card.spellability.AbilitySub; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCost; @@ -53,7 +52,7 @@ public class DrawAi extends SpellAbilityAi { */ @Override protected boolean canPlayAI(Player ai, SpellAbility sa) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); final Cost abCost = sa.getPayCosts(); final Game game = ai.getGame(); @@ -95,8 +94,8 @@ public class DrawAi extends SpellAbilityAi { } if (tgt != null) { - final List players = tgt.getTargetPlayers(); - if ((players.size() > 0) && players.get(0).isOpponentOf(ai)) { + final Player player = sa.getTargets().getFirstTargetedPlayer(); + if (player != null && player.isOpponentOf(ai)) { return true; } } @@ -139,7 +138,7 @@ public class DrawAi extends SpellAbilityAi { } private boolean targetAI(final Player ai, final SpellAbility sa, final boolean mandatory) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); final boolean drawback = (sa instanceof AbilitySub); final Game game = ai.getGame(); @@ -180,7 +179,7 @@ public class DrawAi extends SpellAbilityAi { if (tgt != null) { // ability is targeted - tgt.resetTargets(); + sa.resetTargets(); final boolean canTgtHuman = sa.canTarget(opp); final boolean canTgtComp = sa.canTarget(ai); @@ -192,7 +191,7 @@ public class DrawAi extends SpellAbilityAi { if (canTgtHuman && !opp.cantLose() && numCards >= humanLibrarySize) { // Deck the Human? DO IT! - tgt.addTarget(opp); + sa.getTargets().add(opp); return true; } @@ -228,9 +227,9 @@ public class DrawAi extends SpellAbilityAi { } if ((!tgtHuman || !canTgtHuman) && canTgtComp) { - tgt.addTarget(ai); + sa.getTargets().add(ai); } else if (mandatory && canTgtHuman) { - tgt.addTarget(opp); + sa.getTargets().add(opp); } else { return false; } diff --git a/src/main/java/forge/card/ability/ai/EffectAi.java b/src/main/java/forge/card/ability/ai/EffectAi.java index 90e9383056f..c7687f2a7c7 100644 --- a/src/main/java/forge/card/ability/ai/EffectAi.java +++ b/src/main/java/forge/card/ability/ai/EffectAi.java @@ -9,7 +9,7 @@ import forge.Card; import forge.CardLists; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCombat; @@ -58,9 +58,9 @@ public class EffectAi extends SpellAbilityAi { if (!ComputerUtilCombat.lifeInDanger(ai, game.getCombat())) { return false; } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.resetTargets(); + sa.resetTargets(); List list = game.getCombat().getAttackers(); list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard()); list = CardLists.getTargetableCards(list, sa); @@ -68,7 +68,7 @@ public class EffectAi extends SpellAbilityAi { if (target == null) { return false; } - tgt.addTarget(target); + sa.getTargets().add(target); } randomReturn = true; } else if (logic.equals("Always")) { @@ -109,13 +109,13 @@ public class EffectAi extends SpellAbilityAi { } } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null && tgt.canTgtPlayer()) { - tgt.resetTargets(); + sa.resetTargets(); if (tgt.canOnlyTgtOpponent() || logic.equals("BeginningOfOppTurn")) { - tgt.addTarget(ai.getOpponent()); + sa.getTargets().add(ai.getOpponent()); } else { - tgt.addTarget(ai); + sa.getTargets().add(ai); } } @@ -125,15 +125,14 @@ public class EffectAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player aiPlayer, SpellAbility sa, boolean mandatory) { - final Target tgt = sa.getTarget(); final Player opp = aiPlayer.getOpponent(); - if (sa.getTarget() != null) { - tgt.resetTargets(); + if (sa.usesTargeting()) { + sa.resetTargets(); if (mandatory && sa.canTarget(opp)) { - sa.getTarget().addTarget(opp); + sa.getTargets().add(opp); } else if (mandatory && sa.canTarget(aiPlayer)) { - sa.getTarget().addTarget(aiPlayer); + sa.getTargets().add(aiPlayer); } } diff --git a/src/main/java/forge/card/ability/ai/FightAi.java b/src/main/java/forge/card/ability/ai/FightAi.java index acaeb2f1181..e1b9f06b9e8 100644 --- a/src/main/java/forge/card/ability/ai/FightAi.java +++ b/src/main/java/forge/card/ability/ai/FightAi.java @@ -7,7 +7,6 @@ import forge.Card; import forge.CardLists; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCombat; import forge.game.player.Player; @@ -20,8 +19,7 @@ public class FightAi extends SpellAbilityAi { */ @Override protected boolean canPlayAI(Player ai, SpellAbility sa) { - Target tgt = sa.getTarget(); - tgt.resetTargets(); + sa.resetTargets(); List aiCreatures = ai.getCreaturesInPlay(); aiCreatures = CardLists.getTargetableCards(aiCreatures, sa); @@ -42,12 +40,12 @@ public class FightAi extends SpellAbilityAi { if (ComputerUtilCombat.getDamageToKill(humanCreature) <= aiCreature.getNetAttack() && humanCreature.getNetAttack() < ComputerUtilCombat.getDamageToKill(aiCreature)) { // todo: check min/max targets; see if we picked the best matchup - tgt.addTarget(humanCreature); - tgt.addTarget(aiCreature); + sa.getTargets().add(humanCreature); + sa.getTargets().add(aiCreature); return true; } else if (humanCreature.getSVar("Targeting").equals("Dies")) { - tgt.addTarget(humanCreature); - tgt.addTarget(aiCreature); + sa.getTargets().add(humanCreature); + sa.getTargets().add(aiCreature); return true; } } @@ -67,8 +65,8 @@ public class FightAi extends SpellAbilityAi { if (ComputerUtilCombat.getDamageToKill(creature1) <= creature2.getNetAttack() && creature1.getNetAttack() >= ComputerUtilCombat.getDamageToKill(creature2)) { // todo: check min/max targets; see if we picked the best matchup - tgt.addTarget(creature1); - tgt.addTarget(creature2); + sa.getTargets().add(creature1); + sa.getTargets().add(creature2); return true; } } diff --git a/src/main/java/forge/card/ability/ai/GameLossAi.java b/src/main/java/forge/card/ability/ai/GameLossAi.java index 8c5876051ec..133b5f4898a 100644 --- a/src/main/java/forge/card/ability/ai/GameLossAi.java +++ b/src/main/java/forge/card/ability/ai/GameLossAi.java @@ -2,7 +2,7 @@ package forge.card.ability.ai; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; public class GameLossAi extends SpellAbilityAi { @@ -16,10 +16,10 @@ public class GameLossAi extends SpellAbilityAi { // Only one SA Lose the Game card right now, which is Door to // Nothingness - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.resetTargets(); - tgt.addTarget(opp); + sa.resetTargets(); + sa.getTargets().add(opp); } // In general, don't return true. @@ -38,10 +38,10 @@ public class GameLossAi extends SpellAbilityAi { return false; } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.resetTargets(); - tgt.addTarget(ai.getOpponent()); + sa.resetTargets(); + sa.getTargets().add(ai.getOpponent()); } return true; diff --git a/src/main/java/forge/card/ability/ai/LifeExchangeAi.java b/src/main/java/forge/card/ability/ai/LifeExchangeAi.java index 362dc3199f6..4c6f2acd2e2 100644 --- a/src/main/java/forge/card/ability/ai/LifeExchangeAi.java +++ b/src/main/java/forge/card/ability/ai/LifeExchangeAi.java @@ -4,7 +4,7 @@ import java.util.Random; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.util.MyRandom; @@ -37,12 +37,12 @@ public class LifeExchangeAi extends SpellAbilityAi { * and one card that has a conditional (Psychic Transfer) that are * not currently handled */ - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.resetTargets(); + sa.resetTargets(); if (opponent.canBeTargetedBy(sa)) { // never target self, that would be silly for exchange - tgt.addTarget(opponent); + sa.getTargets().add(opponent); if (!opponent.canLoseLife()) { return false; } diff --git a/src/main/java/forge/card/ability/ai/LifeGainAi.java b/src/main/java/forge/card/ability/ai/LifeGainAi.java index 49f1ae6a9de..4f0c2f7e606 100644 --- a/src/main/java/forge/card/ability/ai/LifeGainAi.java +++ b/src/main/java/forge/card/ability/ai/LifeGainAi.java @@ -6,7 +6,7 @@ import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.AbilitySub; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCombat; @@ -112,11 +112,11 @@ public class LifeGainAi extends SpellAbilityAi { return false; } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.resetTargets(); + sa.resetTargets(); if (sa.canTarget(ai)) { - tgt.addTarget(ai); + sa.getTargets().add(ai); } else { return false; } @@ -146,13 +146,13 @@ public class LifeGainAi extends SpellAbilityAi { // If the Target is gaining life, target self. // if the Target is modifying how much life is gained, this needs to be // handled better - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.resetTargets(); + sa.resetTargets(); if (sa.canTarget(ai)) { - tgt.addTarget(ai); + sa.getTargets().add(ai); } else if (mandatory && sa.canTarget(ai.getOpponent())) { - tgt.addTarget(ai.getOpponent()); + sa.getTargets().add(ai.getOpponent()); } else { return false; } diff --git a/src/main/java/forge/card/ability/ai/LifeLoseAi.java b/src/main/java/forge/card/ability/ai/LifeLoseAi.java index c875b3a78be..e56846b5b63 100644 --- a/src/main/java/forge/card/ability/ai/LifeLoseAi.java +++ b/src/main/java/forge/card/ability/ai/LifeLoseAi.java @@ -6,7 +6,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilMana; @@ -18,13 +18,7 @@ public class LifeLoseAi extends SpellAbilityAi { @Override public boolean chkAIDrawback(SpellAbility sa, Player ai) { - final Target tgt = sa.getTarget(); - List tgtPlayers; - if (tgt != null) { - tgtPlayers = tgt.getTargetPlayers(); - } else { - tgtPlayers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa); - } + List tgtPlayers = getTargetPlayers(sa); final Card source = sa.getSourceCard(); final String amountStr = sa.getParam("LifeAmount"); @@ -98,12 +92,10 @@ public class LifeLoseAi extends SpellAbilityAi { return false; } - final Target tgt = sa.getTarget(); - - if (sa.getTarget() != null) { - tgt.resetTargets(); + if (sa.usesTargeting()) { + sa.resetTargets(); if (sa.canTarget(opp)) { - sa.getTarget().addTarget(opp); + sa.getTargets().add(opp); } else { return false; } @@ -138,12 +130,12 @@ public class LifeLoseAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(final Player ai, final SpellAbility sa, final boolean mandatory) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { if (sa.canTarget(ai.getOpponent())) { - tgt.addTarget(ai.getOpponent()); + sa.getTargets().add(ai.getOpponent()); } else if (mandatory && sa.canTarget(ai)) { - tgt.addTarget(ai); + sa.getTargets().add(ai); } else { return false; } @@ -161,12 +153,7 @@ public class LifeLoseAi extends SpellAbilityAi { amount = AbilityUtils.calculateAmount(source, amountStr, sa); } - List tgtPlayers; - if (tgt != null) { - tgtPlayers = tgt.getTargetPlayers(); - } else { - tgtPlayers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa); - } + List tgtPlayers = getTargetPlayers(sa); if (!mandatory && tgtPlayers.contains(ai) && amount > 0 && amount + 3 > ai.getLife()) { // For cards like Foul Imp, ETB you lose life diff --git a/src/main/java/forge/card/ability/ai/LifeSetAi.java b/src/main/java/forge/card/ability/ai/LifeSetAi.java index 5d751041cb4..f133c0b37a2 100644 --- a/src/main/java/forge/card/ability/ai/LifeSetAi.java +++ b/src/main/java/forge/card/ability/ai/LifeSetAi.java @@ -7,7 +7,7 @@ import forge.CounterType; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtilMana; import forge.game.phase.PhaseType; import forge.game.player.Player; @@ -51,11 +51,11 @@ public class LifeSetAi extends SpellAbilityAi { // prevent run-away activations - first time will always return true final boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn()); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.resetTargets(); + sa.resetTargets(); if (tgt.canOnlyTgtOpponent()) { - tgt.addTarget(opponent); + sa.getTargets().add(opponent); // if we can only target the human, and the Human's life // would // go up, don't play it. @@ -67,11 +67,11 @@ public class LifeSetAi extends SpellAbilityAi { } } else { if ((amount > myLife) && (myLife <= 10)) { - tgt.addTarget(ai); + sa.getTargets().add(ai); } else if (hlife > amount) { - tgt.addTarget(opponent); + sa.getTargets().add(opponent); } else if (amount > myLife) { - tgt.addTarget(ai); + sa.getTargets().add(ai); } else { return false; } @@ -128,18 +128,18 @@ public class LifeSetAi extends SpellAbilityAi { // if the Target is modifying how much life is gained, this needs to // be // handled better - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.resetTargets(); + sa.resetTargets(); if (tgt.canOnlyTgtOpponent()) { - tgt.addTarget(opponent); + sa.getTargets().add(opponent); } else { if ((amount > myLife) && (myLife <= 10)) { - tgt.addTarget(ai); + sa.getTargets().add(ai); } else if (hlife > amount) { - tgt.addTarget(opponent); + sa.getTargets().add(opponent); } else if (amount > myLife) { - tgt.addTarget(ai); + sa.getTargets().add(ai); } else { return false; } diff --git a/src/main/java/forge/card/ability/ai/MillAi.java b/src/main/java/forge/card/ability/ai/MillAi.java index 04f63f7162b..12c6a2512e7 100644 --- a/src/main/java/forge/card/ability/ai/MillAi.java +++ b/src/main/java/forge/card/ability/ai/MillAi.java @@ -8,7 +8,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilMana; @@ -92,14 +92,14 @@ public class MillAi extends SpellAbilityAi { } private boolean targetAI(final Player ai, final SpellAbility sa, final boolean mandatory) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); Player opp = ai.getOpponent(); if (tgt != null) { - tgt.resetTargets(); + sa.resetTargets(); if (!sa.canTarget(opp)) { if (mandatory && sa.canTarget(ai)) { - tgt.addTarget(ai); + sa.getTargets().add(ai); return true; } return false; @@ -114,22 +114,22 @@ public class MillAi extends SpellAbilityAi { return false; } - tgt.addTarget(opp); + sa.getTargets().add(opp); return true; } if (numCards >= pLibrary.size()) { // Can Mill out Human's deck? Do it! - tgt.addTarget(opp); + sa.getTargets().add(opp); return true; } // Obscure case when you know what your top card is so you might? // want to mill yourself here // if (AI wants to mill self) - // tgt.addTarget(AllZone.getComputerPlayer()); + // sa.getTargets().add(AllZone.getComputerPlayer()); // else - tgt.addTarget(opp); + sa.getTargets().add(opp); } return true; } diff --git a/src/main/java/forge/card/ability/ai/MustBlockAi.java b/src/main/java/forge/card/ability/ai/MustBlockAi.java index 1c3483dc821..d1934898a15 100644 --- a/src/main/java/forge/card/ability/ai/MustBlockAi.java +++ b/src/main/java/forge/card/ability/ai/MustBlockAi.java @@ -10,7 +10,7 @@ import forge.CardPredicates; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCombat; import forge.game.phase.CombatUtil; @@ -35,7 +35,7 @@ public class MustBlockAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(final Player ai, SpellAbility sa, boolean mandatory) { final Card source = sa.getSourceCard(); - final Target abTgt = sa.getTarget(); + final TargetRestrictions abTgt = sa.getTargetRestrictions(); // only use on creatures that can attack if (!ai.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)) { @@ -89,7 +89,7 @@ public class MustBlockAi extends SpellAbilityAi { if (blocker == null) { return false; } - abTgt.addTarget(blocker); + sa.getTargets().add(blocker); chance = true; } else { return false; diff --git a/src/main/java/forge/card/ability/ai/PhasesAi.java b/src/main/java/forge/card/ability/ai/PhasesAi.java index 409eb3a431f..6172f1fd5e3 100644 --- a/src/main/java/forge/card/ability/ai/PhasesAi.java +++ b/src/main/java/forge/card/ability/ai/PhasesAi.java @@ -8,7 +8,7 @@ import forge.CardLists; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -22,7 +22,7 @@ public class PhasesAi extends SpellAbilityAi { @Override protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) { // This still needs to be fleshed out - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); final Random r = MyRandom.getRandom(); @@ -51,7 +51,7 @@ public class PhasesAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player aiPlayer, SpellAbility sa, boolean mandatory) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt == null) { return mandatory; @@ -69,7 +69,7 @@ public class PhasesAi extends SpellAbilityAi { @Override public boolean chkAIDrawback(SpellAbility sa, Player aiPlayer) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); boolean randomReturn = true; @@ -89,7 +89,7 @@ public class PhasesAi extends SpellAbilityAi { *

* * @param tgt - * a {@link forge.card.spellability.Target} object. + * a {@link forge.card.spellability.TargetRestrictions} object. * @param af * a {@link forge.card.ability.AbilityFactory} object. * @param sa @@ -98,7 +98,7 @@ public class PhasesAi extends SpellAbilityAi { * a boolean. * @return a boolean. */ - private boolean phasesPrefTargeting(final Target tgt, final SpellAbility sa, + private boolean phasesPrefTargeting(final TargetRestrictions tgt, final SpellAbility sa, final boolean mandatory) { // Card source = sa.getSourceCard(); @@ -135,7 +135,7 @@ public class PhasesAi extends SpellAbilityAi { */ private boolean phasesUnpreferredTargeting(final Game game, final SpellAbility sa, final boolean mandatory) { final Card source = sa.getSourceCard(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); List list = game.getCardsIn(ZoneType.Battlefield); list = CardLists.getTargetableCards(CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source), sa); diff --git a/src/main/java/forge/card/ability/ai/PlayAi.java b/src/main/java/forge/card/ability/ai/PlayAi.java index be299264012..5210f8eda90 100644 --- a/src/main/java/forge/card/ability/ai/PlayAi.java +++ b/src/main/java/forge/card/ability/ai/PlayAi.java @@ -10,7 +10,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCost; import forge.game.player.Player; @@ -54,14 +54,14 @@ public class PlayAi extends SpellAbilityAi { boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getRestrictions().getNumberTurnActivations()); List cards; - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { ZoneType zone = tgt.getZone().get(0); cards = CardLists.getValidCards(ai.getGame().getCardsIn(zone), tgt.getValidTgts(), ai, source); if (cards.isEmpty()) { return false; } - tgt.addTarget(ComputerUtilCard.getBestAI(cards)); + sa.getTargets().add(ComputerUtilCard.getBestAI(cards)); } else if (!sa.hasParam("Valid")) { cards = new ArrayList(AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa)); if (cards.isEmpty()) { @@ -87,7 +87,7 @@ public class PlayAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(final Player ai, final SpellAbility sa, final boolean mandatory) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { return false; } diff --git a/src/main/java/forge/card/ability/ai/PoisonAi.java b/src/main/java/forge/card/ability/ai/PoisonAi.java index b6b0653a78d..a3c3070d460 100644 --- a/src/main/java/forge/card/ability/ai/PoisonAi.java +++ b/src/main/java/forge/card/ability/ai/PoisonAi.java @@ -7,7 +7,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCost; import forge.game.phase.PhaseType; @@ -59,11 +59,10 @@ public class PoisonAi extends SpellAbilityAi { return false; } - final Target tgt = sa.getTarget(); - if (sa.getTarget() != null) { - tgt.resetTargets(); - sa.getTarget().addTarget(ai.getOpponent()); + if (sa.usesTargeting()) { + sa.resetTargets(); + sa.getTargets().add(ai.getOpponent()); } return true; @@ -72,9 +71,9 @@ public class PoisonAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.addTarget(ai.getOpponent()); + sa.getTargets().add(ai.getOpponent()); } else { final List players = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa); for (final Player p : players) { diff --git a/src/main/java/forge/card/ability/ai/ProtectAi.java b/src/main/java/forge/card/ability/ai/ProtectAi.java index 34b0b7c59bf..2433e00ecdb 100644 --- a/src/main/java/forge/card/ability/ai/ProtectAi.java +++ b/src/main/java/forge/card/ability/ai/ProtectAi.java @@ -12,7 +12,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCard; @@ -117,7 +117,7 @@ public class ProtectAi extends SpellAbilityAi { final Card hostCard = sa.getSourceCard(); final Game game = ai.getGame(); // if there is no target and host card isn't in play, don't activate - if ((sa.getTarget() == null) && !hostCard.isInPlay()) { + if ((sa.getTargetRestrictions() == null) && !hostCard.isInPlay()) { return false; } @@ -153,7 +153,7 @@ public class ProtectAi extends SpellAbilityAi { return false; } - if ((sa.getTarget() == null) || !sa.getTarget().doesTarget()) { + if ((sa.getTargetRestrictions() == null) || !sa.getTargetRestrictions().doesTarget()) { final List cards = AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa); if (cards.size() == 0) { @@ -182,8 +182,8 @@ public class ProtectAi extends SpellAbilityAi { final Card source = sa.getSourceCard(); - final Target tgt = sa.getTarget(); - tgt.resetTargets(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); + sa.resetTargets(); List list = getProtectCreatures(ai, sa); list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard()); @@ -221,17 +221,17 @@ public class ProtectAi extends SpellAbilityAi { // Don't target cards that will die. list = ComputerUtil.getSafeTargets(ai, sa, list); - while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) { Card t = null; // boolean goodt = false; if (list.isEmpty()) { - if ((tgt.getNumTargeted() < tgt.getMinTargets(source, sa)) || (tgt.getNumTargeted() == 0)) { + if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(source, sa)) || (sa.getTargets().getNumTargeted() == 0)) { if (mandatory) { return protectMandatoryTarget(ai, sa, mandatory); } - tgt.resetTargets(); + sa.resetTargets(); return false; } else { // TODO is this good enough? for up to amounts? @@ -240,7 +240,7 @@ public class ProtectAi extends SpellAbilityAi { } t = ComputerUtilCard.getBestCreatureAI(list); - tgt.addTarget(t); + sa.getTargets().add(t); list.remove(t); } @@ -251,16 +251,16 @@ public class ProtectAi extends SpellAbilityAi { final Game game = ai.getGame(); List list = game.getCardsIn(ZoneType.Battlefield); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard()); if (list.size() < tgt.getMinTargets(sa.getSourceCard(), sa)) { - tgt.resetTargets(); + sa.resetTargets(); return false; } // Remove anything that's already been targeted - for (final Card c : tgt.getTargetCards()) { + for (final Card c : sa.getTargets().getTargetCards()) { list.remove(c); } @@ -281,7 +281,7 @@ public class ProtectAi extends SpellAbilityAi { final List forced = CardLists.filterControlledBy(list, ai); final Card source = sa.getSourceCard(); - while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) { if (pref.isEmpty()) { break; } @@ -295,10 +295,10 @@ public class ProtectAi extends SpellAbilityAi { pref.remove(c); - tgt.addTarget(c); + sa.getTargets().add(c); } - while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) { if (pref2.isEmpty()) { break; } @@ -312,10 +312,10 @@ public class ProtectAi extends SpellAbilityAi { pref2.remove(c); - tgt.addTarget(c); + sa.getTargets().add(c); } - while (tgt.getNumTargeted() < tgt.getMinTargets(source, sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMinTargets(source, sa)) { if (forced.isEmpty()) { break; } @@ -329,11 +329,11 @@ public class ProtectAi extends SpellAbilityAi { forced.remove(c); - tgt.addTarget(c); + sa.getTargets().add(c); } - if (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { - tgt.resetTargets(); + if (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { + sa.resetTargets(); return false; } @@ -342,7 +342,7 @@ public class ProtectAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { - if (sa.getTarget() == null) { + if (sa.getTargetRestrictions() == null) { if (mandatory) { return true; } @@ -356,7 +356,7 @@ public class ProtectAi extends SpellAbilityAi { @Override public boolean chkAIDrawback(SpellAbility sa, Player ai) { final Card host = sa.getSourceCard(); - if ((sa.getTarget() == null) || !sa.getTarget().doesTarget()) { + if ((sa.getTargetRestrictions() == null) || !sa.getTargetRestrictions().doesTarget()) { if (host.isCreature()) { // TODO } diff --git a/src/main/java/forge/card/ability/ai/ProtectAllAi.java b/src/main/java/forge/card/ability/ai/ProtectAllAi.java index 7126abe1a27..3fd32133065 100644 --- a/src/main/java/forge/card/ability/ai/ProtectAllAi.java +++ b/src/main/java/forge/card/ability/ai/ProtectAllAi.java @@ -14,7 +14,7 @@ public class ProtectAllAi extends SpellAbilityAi { protected boolean canPlayAI(Player ai, SpellAbility sa) { final Card hostCard = sa.getSourceCard(); // if there is no target and host card isn't in play, don't activate - if ((sa.getTarget() == null) && !hostCard.isInPlay()) { + if ((sa.getTargetRestrictions() == null) && !hostCard.isInPlay()) { return false; } diff --git a/src/main/java/forge/card/ability/ai/PumpAi.java b/src/main/java/forge/card/ability/ai/PumpAi.java index 37861c2825c..4a28c724f87 100644 --- a/src/main/java/forge/card/ability/ai/PumpAi.java +++ b/src/main/java/forge/card/ability/ai/PumpAi.java @@ -14,7 +14,7 @@ import forge.card.cost.CostPart; import forge.card.cost.CostTapType; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbilityRestriction; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCard; @@ -142,7 +142,7 @@ public class PumpAi extends PumpAiBase { } //Untargeted - if ((sa.getTarget() == null) || !sa.getTarget().doesTarget()) { + if ((sa.getTargetRestrictions() == null) || !sa.getTargetRestrictions().doesTarget()) { final List cards = AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa); @@ -192,8 +192,8 @@ public class PumpAi extends PumpAiBase { } final Player opp = ai.getOpponent(); - final Target tgt = sa.getTarget(); - tgt.resetTargets(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); + sa.resetTargets(); List list = new ArrayList(); if (sa.hasParam("AILogic")) { if (sa.getParam("AILogic").equals("HighestPower")) { @@ -201,7 +201,7 @@ public class PumpAi extends PumpAiBase { list = CardLists.getTargetableCards(list, sa); CardLists.sortByPowerDesc(list); if (!list.isEmpty()) { - tgt.addTarget(list.get(0)); + sa.getTargets().add(list.get(0)); return true; } else { return false; @@ -209,7 +209,7 @@ public class PumpAi extends PumpAiBase { } } else if (sa.isCurse()) { if (sa.canTarget(opp)) { - tgt.addTarget(opp); + sa.getTargets().add(opp); return true; } list = this.getCurseCreatures(ai, sa, defense, attack, keywords); @@ -221,7 +221,7 @@ public class PumpAi extends PumpAiBase { list = this.getPumpCreatures(ai, sa, defense, attack, keywords); } if (sa.canTarget(ai)) { - tgt.addTarget(ai); + sa.getTargets().add(ai); return true; } } @@ -251,17 +251,17 @@ public class PumpAi extends PumpAiBase { list = ComputerUtil.getSafeTargets(ai, sa, list); } - while (tgt.getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) { Card t = null; // boolean goodt = false; if (list.isEmpty()) { - if ((tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (tgt.getNumTargeted() == 0)) { + if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (sa.getTargets().getNumTargeted() == 0)) { if (mandatory) { return this.pumpMandatoryTarget(ai, sa, mandatory); } - tgt.resetTargets(); + sa.resetTargets(); return false; } else { // TODO is this good enough? for up to amounts? @@ -270,7 +270,7 @@ public class PumpAi extends PumpAiBase { } t = ComputerUtilCard.getBestAI(list); - tgt.addTarget(t); + sa.getTargets().add(t); list.remove(t); } @@ -280,18 +280,18 @@ public class PumpAi extends PumpAiBase { private boolean pumpMandatoryTarget(final Player ai, final SpellAbility sa, final boolean mandatory) { final Game game = ai.getGame(); List list = game.getCardsIn(ZoneType.Battlefield); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Player opp = ai.getOpponent(); list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard()); list = CardLists.getTargetableCards(list, sa); if (list.size() < tgt.getMinTargets(sa.getSourceCard(), sa)) { - tgt.resetTargets(); + sa.resetTargets(); return false; } // Remove anything that's already been targeted - for (final Card c : tgt.getTargetCards()) { + for (final Card c : sa.getTargets().getTargetCards()) { list.remove(c); } @@ -307,7 +307,7 @@ public class PumpAi extends PumpAiBase { forced = CardLists.filterControlledBy(list, opp); } - while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) { if (pref.isEmpty()) { break; } @@ -321,10 +321,10 @@ public class PumpAi extends PumpAiBase { pref.remove(c); - tgt.addTarget(c); + sa.getTargets().add(c); } - while (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { if (forced.isEmpty()) { break; } @@ -338,11 +338,11 @@ public class PumpAi extends PumpAiBase { forced.remove(c); - tgt.addTarget(c); + sa.getTargets().add(c); } - if (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { - tgt.resetTargets(); + if (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { + sa.resetTargets(); return false; } @@ -381,7 +381,7 @@ public class PumpAi extends PumpAiBase { attack = AbilityUtils.calculateAmount(sa.getSourceCard(), numAttack, sa); } - if (sa.getTarget() == null) { + if (sa.getTargetRestrictions() == null) { if (mandatory) { return true; } @@ -421,7 +421,7 @@ public class PumpAi extends PumpAiBase { attack = AbilityUtils.calculateAmount(sa.getSourceCard(), numAttack, sa); } - if ((sa.getTarget() == null) || !sa.getTarget().doesTarget()) { + if ((sa.getTargetRestrictions() == null) || !sa.getTargetRestrictions().doesTarget()) { if (source.isCreature()) { if (!source.hasKeyword("Indestructible") && ((source.getNetDefense() + defense) <= source.getDamage())) { diff --git a/src/main/java/forge/card/ability/ai/PumpAllAi.java b/src/main/java/forge/card/ability/ai/PumpAllAi.java index 4e7762f0a93..a2c27ed26e2 100644 --- a/src/main/java/forge/card/ability/ai/PumpAllAi.java +++ b/src/main/java/forge/card/ability/ai/PumpAllAi.java @@ -10,7 +10,7 @@ import forge.Card; import forge.CardLists; import forge.card.ability.AbilityUtils; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCard; @@ -49,10 +49,10 @@ public class PumpAllAi extends PumpAiBase { List comp = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source); List human = CardLists.getValidCards(opp.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null && sa.canTarget(opp) && sa.hasParam("IsCurse")) { - tgt.resetTargets(); - sa.getTarget().addTarget(opp); + sa.resetTargets(); + sa.getTargets().add(opp); comp = new ArrayList(); } diff --git a/src/main/java/forge/card/ability/ai/RearrangeTopOfLibraryAi.java b/src/main/java/forge/card/ability/ai/RearrangeTopOfLibraryAi.java index 3e6b2978538..d0728092079 100644 --- a/src/main/java/forge/card/ability/ai/RearrangeTopOfLibraryAi.java +++ b/src/main/java/forge/card/ability/ai/RearrangeTopOfLibraryAi.java @@ -3,7 +3,7 @@ package forge.card.ability.ai; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; public class RearrangeTopOfLibraryAi extends SpellAbilityAi { @@ -21,11 +21,11 @@ public class RearrangeTopOfLibraryAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { // ability is targeted - tgt.resetTargets(); + sa.resetTargets(); Player opp = ai.getOpponent(); final boolean canTgtHuman = opp.canBeTargetedBy(sa); @@ -33,7 +33,7 @@ public class RearrangeTopOfLibraryAi extends SpellAbilityAi { if (!canTgtHuman) { return false; } else { - tgt.addTarget(opp); + sa.getTargets().add(opp); } } else { // if it's just defined, no big deal diff --git a/src/main/java/forge/card/ability/ai/RegenerateAi.java b/src/main/java/forge/card/ability/ai/RegenerateAi.java index 410b414ed0b..088a88c9d8c 100644 --- a/src/main/java/forge/card/ability/ai/RegenerateAi.java +++ b/src/main/java/forge/card/ability/ai/RegenerateAi.java @@ -23,11 +23,12 @@ 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; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCard; @@ -77,14 +78,14 @@ public class RegenerateAi extends SpellAbilityAi { } } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt == null) { // As far as I can tell these Defined Cards will only have one of // them final List list = AbilityUtils.getDefinedCards(hostCard, sa.getParam("Defined"), sa); if (!game.getStack().isEmpty()) { - final List objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa); + final List objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa); for (final Card c : list) { if (objects.contains(c)) { @@ -108,7 +109,7 @@ public class RegenerateAi extends SpellAbilityAi { } } } else { - tgt.resetTargets(); + sa.resetTargets(); // filter AIs battlefield by what I can target List targetables = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, hostCard); targetables = CardLists.getTargetableCards(targetables, sa); @@ -120,7 +121,7 @@ public class RegenerateAi extends SpellAbilityAi { if (!game.getStack().isEmpty()) { // check stack for something on the stack will kill anything i // control - final ArrayList objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa); + final List objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa); final List threatenedTargets = new ArrayList(); @@ -132,7 +133,7 @@ public class RegenerateAi extends SpellAbilityAi { if (!threatenedTargets.isEmpty()) { // Choose "best" of the remaining to regenerate - tgt.addTarget(ComputerUtilCard.getBestCreatureAI(threatenedTargets)); + sa.getTargets().add(ComputerUtilCard.getBestCreatureAI(threatenedTargets)); chance = true; } } else { @@ -142,14 +143,14 @@ public class RegenerateAi extends SpellAbilityAi { for (final Card c : combatants) { if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) { - tgt.addTarget(c); + sa.getTargets().add(c); chance = true; break; } } } } - if (tgt.getTargets().isEmpty()) { + if (sa.getTargets().isEmpty()) { return false; } } @@ -161,7 +162,7 @@ public class RegenerateAi extends SpellAbilityAi { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { boolean chance = false; - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt == null) { // If there's no target on the trigger, just say yes. chance = true; @@ -175,8 +176,8 @@ public class RegenerateAi extends SpellAbilityAi { private static boolean regenMandatoryTarget(final Player ai, final SpellAbility sa, final boolean mandatory) { final Card hostCard = sa.getSourceCard(); final Game game = ai.getGame(); - final Target tgt = sa.getTarget(); - tgt.resetTargets(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); + sa.resetTargets(); // filter AIs battlefield by what I can target List targetables = game.getCardsIn(ZoneType.Battlefield); targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), ai, hostCard); @@ -197,7 +198,7 @@ public class RegenerateAi extends SpellAbilityAi { if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) { for (final Card c : combatants) { if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) { - tgt.addTarget(c); + sa.getTargets().add(c); return true; } } @@ -210,26 +211,26 @@ public class RegenerateAi extends SpellAbilityAi { if (CardLists.getNotType(compTargetables, "Creature").isEmpty()) { for (final Card c : combatants) { if (c.getShield() == 0) { - tgt.addTarget(c); + sa.getTargets().add(c); return true; } } - tgt.addTarget(combatants.get(0)); + sa.getTargets().add(combatants.get(0)); return true; } else { CardLists.sortByCmcDesc(compTargetables); for (final Card c : compTargetables) { if (c.getShield() == 0) { - tgt.addTarget(c); + sa.getTargets().add(c); return true; } } - tgt.addTarget(compTargetables.get(0)); + sa.getTargets().add(compTargetables.get(0)); return true; } } - tgt.addTarget(ComputerUtilCard.getCheapestPermanentAI(targetables, sa, true)); + sa.getTargets().add(ComputerUtilCard.getCheapestPermanentAI(targetables, sa, true)); return true; } diff --git a/src/main/java/forge/card/ability/ai/RegenerateAllAi.java b/src/main/java/forge/card/ability/ai/RegenerateAllAi.java index db5a0e329ec..ba884ba4c71 100644 --- a/src/main/java/forge/card/ability/ai/RegenerateAllAi.java +++ b/src/main/java/forge/card/ability/ai/RegenerateAllAi.java @@ -1,11 +1,11 @@ package forge.card.ability.ai; -import java.util.ArrayList; import java.util.List; import forge.Card; import forge.CardLists; import forge.CardPredicates; +import forge.ITargetable; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; @@ -57,7 +57,7 @@ public class RegenerateAllAi extends SpellAbilityAi { int numSaved = 0; if (!game.getStack().isEmpty()) { - final ArrayList objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa); + final List objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa); for (final Card c : list) { if (objects.contains(c) && c.getShield() == 0) { diff --git a/src/main/java/forge/card/ability/ai/RepeatAi.java b/src/main/java/forge/card/ability/ai/RepeatAi.java index 0af52f14586..18409ece607 100644 --- a/src/main/java/forge/card/ability/ai/RepeatAi.java +++ b/src/main/java/forge/card/ability/ai/RepeatAi.java @@ -3,7 +3,7 @@ package forge.card.ability.ai; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.game.player.PlayerActionConfirmMode; @@ -11,14 +11,14 @@ public class RepeatAi extends SpellAbilityAi { @Override protected boolean canPlayAI(Player ai, SpellAbility sa) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Player opp = ai.getOpponent(); if (tgt != null) { if (!opp.canBeTargetedBy(sa)) { return false; } - tgt.resetTargets(); - tgt.addTarget(opp); + sa.resetTargets(); + sa.getTargets().add(opp); } return true; } diff --git a/src/main/java/forge/card/ability/ai/RepeatEachAi.java b/src/main/java/forge/card/ability/ai/RepeatEachAi.java index fac0e1bc6ba..9a2919fae25 100644 --- a/src/main/java/forge/card/ability/ai/RepeatEachAi.java +++ b/src/main/java/forge/card/ability/ai/RepeatEachAi.java @@ -11,7 +11,6 @@ import forge.CardPredicates.Presets; import forge.CounterType; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -57,7 +56,6 @@ public class RepeatEachAi extends SpellAbilityAi { sa.setTargetCard(perms.get(0)); } else if ("RemoveAllCounters".equals(logic)) { // Break Dark Depths - Target tgt = sa.getTarget(); List depthsList = aiPlayer.getCardsIn(ZoneType.Battlefield, "Dark Depths"); depthsList = CardLists.filter(depthsList, new Predicate() { @Override @@ -67,7 +65,7 @@ public class RepeatEachAi extends SpellAbilityAi { }); if (depthsList.size() > 0) { - tgt.addTarget(depthsList.get(0)); + sa.getTargets().add(depthsList.get(0)); return true; } @@ -84,7 +82,7 @@ public class RepeatEachAi extends SpellAbilityAi { return false; } - tgt.addTarget(list.get(0)); + sa.getTargets().add(list.get(0)); } else if ("BalanceLands".equals(logic)) { if (CardLists.filter(aiPlayer.getCardsIn(ZoneType.Battlefield), Presets.LANDS).size() >= 5) { return false; diff --git a/src/main/java/forge/card/ability/ai/RevealAiBase.java b/src/main/java/forge/card/ability/ai/RevealAiBase.java index 4d1a9599b2a..2305c6191ea 100644 --- a/src/main/java/forge/card/ability/ai/RevealAiBase.java +++ b/src/main/java/forge/card/ability/ai/RevealAiBase.java @@ -3,28 +3,28 @@ package forge.card.ability.ai; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.game.zone.ZoneType; public abstract class RevealAiBase extends SpellAbilityAi { protected boolean revealHandTargetAI(final Player ai, final SpellAbility sa) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); Player opp = ai.getOpponent(); final int humanHandSize = opp.getCardsIn(ZoneType.Hand).size(); if (tgt != null) { // ability is targeted - tgt.resetTargets(); + sa.resetTargets(); final boolean canTgtHuman = opp.canBeTargetedBy(sa); if (!canTgtHuman || (humanHandSize == 0)) { return false; } else { - tgt.addTarget(opp); + sa.getTargets().add(opp); } } else { // if it's just defined, no big deal diff --git a/src/main/java/forge/card/ability/ai/SacrificeAi.java b/src/main/java/forge/card/ability/ai/SacrificeAi.java index c5106a419aa..7fb2ac360a1 100644 --- a/src/main/java/forge/card/ability/ai/SacrificeAi.java +++ b/src/main/java/forge/card/ability/ai/SacrificeAi.java @@ -8,7 +8,7 @@ import forge.CardPredicates; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilMana; import forge.game.player.Player; @@ -50,16 +50,16 @@ public class SacrificeAi extends SpellAbilityAi { private boolean sacrificeTgtAI(final Player ai, final SpellAbility sa) { final Card source = sa.getSourceCard(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final boolean destroy = sa.hasParam("Destroy"); Player opp = ai.getOpponent(); if (tgt != null) { - tgt.resetTargets(); + sa.resetTargets(); if (!opp.canBeTargetedBy(sa)) { return false; } - tgt.addTarget(opp); + sa.getTargets().add(opp); final String valid = sa.getParam("SacValid"); String num = sa.getParam("Amount"); num = (num == null) ? "1" : num; diff --git a/src/main/java/forge/card/ability/ai/ScryAi.java b/src/main/java/forge/card/ability/ai/ScryAi.java index 47ac3ed1e51..9e1da576fbe 100644 --- a/src/main/java/forge/card/ability/ai/ScryAi.java +++ b/src/main/java/forge/card/ability/ai/ScryAi.java @@ -4,7 +4,7 @@ import java.util.Random; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.util.MyRandom; @@ -15,13 +15,13 @@ public class ScryAi extends SpellAbilityAi { */ @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { // It doesn't appear that Scry ever targets // ability is targeted - tgt.resetTargets(); + sa.resetTargets(); - tgt.addTarget(ai); + sa.getTargets().add(ai); } return true; diff --git a/src/main/java/forge/card/ability/ai/SetStateAi.java b/src/main/java/forge/card/ability/ai/SetStateAi.java index f0c03e61eac..890f92c5d88 100644 --- a/src/main/java/forge/card/ability/ai/SetStateAi.java +++ b/src/main/java/forge/card/ability/ai/SetStateAi.java @@ -8,7 +8,7 @@ import forge.game.player.Player; public class SetStateAi extends SpellAbilityAi { @Override protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) { - if (sa.getTarget() == null && "Transform".equals(sa.getParam("Mode"))) { + if (sa.getTargetRestrictions() == null && "Transform".equals(sa.getParam("Mode"))) { return true; } return false; diff --git a/src/main/java/forge/card/ability/ai/TapAi.java b/src/main/java/forge/card/ability/ai/TapAi.java index 5a5d827a82c..21a7a61ef28 100644 --- a/src/main/java/forge/card/ability/ai/TapAi.java +++ b/src/main/java/forge/card/ability/ai/TapAi.java @@ -7,7 +7,7 @@ import forge.Card; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; import forge.game.player.Player; @@ -31,7 +31,7 @@ public class TapAi extends TapAiBase { return false; } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); final Random r = MyRandom.getRandom(); @@ -49,7 +49,7 @@ public class TapAi extends TapAiBase { return false; } } else { - tgt.resetTargets(); + sa.resetTargets(); if (!tapPrefTargeting(ai, source, tgt, sa, false)) { return false; } diff --git a/src/main/java/forge/card/ability/ai/TapAiBase.java b/src/main/java/forge/card/ability/ai/TapAiBase.java index 2b32ce616f1..89b9e754329 100644 --- a/src/main/java/forge/card/ability/ai/TapAiBase.java +++ b/src/main/java/forge/card/ability/ai/TapAiBase.java @@ -11,7 +11,7 @@ import forge.CardPredicates; import forge.CardPredicates.Presets; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCard; @@ -40,9 +40,9 @@ public abstract class TapAiBase extends SpellAbilityAi { */ private boolean tapTargetList(final Player ai, final SpellAbility sa, final List tapList, final boolean mandatory) { final Card source = sa.getSourceCard(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); - for (final Card c : tgt.getTargetCards()) { + for (final Card c : sa.getTargets().getTargetCards()) { tapList.remove(c); } @@ -50,13 +50,13 @@ public abstract class TapAiBase extends SpellAbilityAi { return false; } - while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) { Card choice = null; if (tapList.size() == 0) { - if ((tgt.getNumTargeted() < tgt.getMinTargets(source, sa)) || (tgt.getNumTargeted() == 0)) { + if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(source, sa)) || (sa.getTargets().getNumTargeted() == 0)) { if (!mandatory) { - tgt.resetTargets(); + sa.resetTargets(); } return false; } else { @@ -75,9 +75,9 @@ public abstract class TapAiBase extends SpellAbilityAi { } if (choice == null) { // can't find anything left - if ((tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (tgt.getNumTargeted() == 0)) { + if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (sa.getTargets().getNumTargeted() == 0)) { if (!mandatory) { - tgt.resetTargets(); + sa.resetTargets(); } return false; } else { @@ -89,7 +89,7 @@ public abstract class TapAiBase extends SpellAbilityAi { } tapList.remove(choice); - tgt.addTarget(choice); + sa.getTargets().add(choice); } return true; @@ -103,7 +103,7 @@ public abstract class TapAiBase extends SpellAbilityAi { * @param source * a {@link forge.Card} object. * @param tgt - * a {@link forge.card.spellability.Target} object. + * a {@link forge.card.spellability.TargetRestrictions} object. * @param af * a {@link forge.card.ability.AbilityFactory} object. * @param sa @@ -112,7 +112,7 @@ public abstract class TapAiBase extends SpellAbilityAi { * a boolean. * @return a boolean. */ - protected boolean tapPrefTargeting(final Player ai, final Card source, final Target tgt, final SpellAbility sa, final boolean mandatory) { + protected boolean tapPrefTargeting(final Player ai, final Card source, final TargetRestrictions tgt, final SpellAbility sa, final boolean mandatory) { final Player opp = ai.getOpponent(); final Game game = ai.getGame(); List tapList = opp.getCardsIn(ZoneType.Battlefield); @@ -142,13 +142,13 @@ public abstract class TapAiBase extends SpellAbilityAi { return false; } - while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) { Card choice = null; if (tapList.size() == 0) { - if ((tgt.getNumTargeted() < tgt.getMinTargets(source, sa)) || (tgt.getNumTargeted() == 0)) { + if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(source, sa)) || (sa.getTargets().getNumTargeted() == 0)) { if (!mandatory) { - tgt.resetTargets(); + sa.resetTargets(); } return false; } else { @@ -204,9 +204,9 @@ public abstract class TapAiBase extends SpellAbilityAi { } if (choice == null) { // can't find anything left - if ((tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (tgt.getNumTargeted() == 0)) { + if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (sa.getTargets().getNumTargeted() == 0)) { if (!mandatory) { - tgt.resetTargets(); + sa.resetTargets(); } return false; } else { @@ -218,7 +218,7 @@ public abstract class TapAiBase extends SpellAbilityAi { } tapList.remove(choice); - tgt.addTarget(choice); + sa.getTargets().add(choice); } return true; @@ -239,7 +239,7 @@ public abstract class TapAiBase extends SpellAbilityAi { */ protected boolean tapUnpreferredTargeting(final Player ai, final SpellAbility sa, final boolean mandatory) { final Card source = sa.getSourceCard(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Game game = ai.getGame(); List list = game.getCardsIn(ZoneType.Battlefield); @@ -280,7 +280,7 @@ public abstract class TapAiBase extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); if (tgt == null) { @@ -292,7 +292,7 @@ public abstract class TapAiBase extends SpellAbilityAi { return true; } else { - tgt.resetTargets(); + sa.resetTargets(); if (tapPrefTargeting(ai, source, tgt, sa, mandatory)) { return true; } else if (mandatory) { @@ -306,7 +306,7 @@ public abstract class TapAiBase extends SpellAbilityAi { @Override public boolean chkAIDrawback(SpellAbility sa, Player ai) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); boolean randomReturn = true; @@ -315,7 +315,7 @@ public abstract class TapAiBase extends SpellAbilityAi { // either self or defined, either way should be fine } else { // target section, maybe pull this out? - tgt.resetTargets(); + sa.resetTargets(); if (!tapPrefTargeting(ai, source, tgt, sa, false)) { return false; } diff --git a/src/main/java/forge/card/ability/ai/TapAllAi.java b/src/main/java/forge/card/ability/ai/TapAllAi.java index 2ded0dbc056..8af60b465e2 100644 --- a/src/main/java/forge/card/ability/ai/TapAllAi.java +++ b/src/main/java/forge/card/ability/ai/TapAllAi.java @@ -11,7 +11,7 @@ import forge.CardLists; import forge.CardPredicates.Presets; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.phase.CombatUtil; import forge.game.phase.PhaseType; @@ -45,11 +45,9 @@ public class TapAllAi extends SpellAbilityAi { List validTappables = game.getCardsIn(ZoneType.Battlefield); - final Target tgt = sa.getTarget(); - - if (sa.getTarget() != null) { - tgt.resetTargets(); - tgt.addTarget(opp); + if (sa.usesTargeting()) { + sa.resetTargets(); + sa.getTargets().add(opp); validTappables = opp.getCardsIn(ZoneType.Battlefield); } @@ -126,11 +124,11 @@ public class TapAllAi extends SpellAbilityAi { List validTappables = getTapAllTargets(valid, source); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.resetTargets(); - tgt.addTarget(ai.getOpponent()); + sa.resetTargets(); + sa.getTargets().add(ai.getOpponent()); validTappables = ai.getOpponent().getCardsIn(ZoneType.Battlefield); } diff --git a/src/main/java/forge/card/ability/ai/TapOrUntapAi.java b/src/main/java/forge/card/ability/ai/TapOrUntapAi.java index 1d67a7bc6b0..5cdf75e407d 100644 --- a/src/main/java/forge/card/ability/ai/TapOrUntapAi.java +++ b/src/main/java/forge/card/ability/ai/TapOrUntapAi.java @@ -6,7 +6,7 @@ import java.util.Random; import forge.Card; import forge.card.ability.AbilityUtils; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.util.MyRandom; @@ -17,7 +17,7 @@ public class TapOrUntapAi extends TapAiBase { */ @Override protected boolean canPlayAI(Player ai, SpellAbility sa) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); final Random r = MyRandom.getRandom(); @@ -38,7 +38,7 @@ public class TapOrUntapAi extends TapAiBase { return false; } } else { - tgt.resetTargets(); + sa.resetTargets(); if (!tapPrefTargeting(ai, source, tgt, sa, false)) { return false; } diff --git a/src/main/java/forge/card/ability/ai/TokenAi.java b/src/main/java/forge/card/ability/ai/TokenAi.java index e7c5deb9c1e..80b42cccf5a 100644 --- a/src/main/java/forge/card/ability/ai/TokenAi.java +++ b/src/main/java/forge/card/ability/ai/TokenAi.java @@ -7,7 +7,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCost; @@ -126,13 +126,13 @@ public class TokenAi extends SpellAbilityAi { final Random r = MyRandom.getRandom(); final Card source = sa.getSourceCard(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.resetTargets(); + sa.resetTargets(); if (tgt.canOnlyTgtOpponent() || "Opponent".equals(sa.getParam("AITgts"))) { - tgt.addTarget(opp); + sa.getTargets().add(opp); } else { - tgt.addTarget(ai); + sa.getTargets().add(ai); } } @@ -184,13 +184,13 @@ public class TokenAi extends SpellAbilityAi { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { readParameters(sa); final Card source = sa.getSourceCard(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.resetTargets(); + sa.resetTargets(); if (tgt.canOnlyTgtOpponent()) { - tgt.addTarget(ai.getOpponent()); + sa.getTargets().add(ai.getOpponent()); } else { - tgt.addTarget(ai); + sa.getTargets().add(ai); } } if ("X".equals(this.tokenAmount) || "X".equals(this.tokenPower) || "X".equals(this.tokenToughness)) { diff --git a/src/main/java/forge/card/ability/ai/TwoPilesAi.java b/src/main/java/forge/card/ability/ai/TwoPilesAi.java index 7e91e6c2459..9bf065732a9 100644 --- a/src/main/java/forge/card/ability/ai/TwoPilesAi.java +++ b/src/main/java/forge/card/ability/ai/TwoPilesAi.java @@ -8,7 +8,7 @@ import forge.CardLists; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -31,20 +31,19 @@ public class TwoPilesAi extends SpellAbilityAi { valid = sa.getParam("ValidCards"); } - List tgtPlayers; + final Player opp = ai.getOpponent(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.resetTargets(); + sa.resetTargets(); if (tgt.canTgtPlayer()) { - tgt.addTarget(opp); + sa.getTargets().add(opp); } - tgtPlayers = tgt.getTargetPlayers(); - } else { - tgtPlayers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa); } - + + List tgtPlayers = getTargetPlayers(sa); + final Player p = tgtPlayers.get(0); List pool = new ArrayList(); if (sa.hasParam("DefinedCards")) { diff --git a/src/main/java/forge/card/ability/ai/UnattachAllAi.java b/src/main/java/forge/card/ability/ai/UnattachAllAi.java index b398379152d..3250efe1f57 100644 --- a/src/main/java/forge/card/ability/ai/UnattachAllAi.java +++ b/src/main/java/forge/card/ability/ai/UnattachAllAi.java @@ -10,7 +10,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilMana; import forge.game.phase.PhaseType; @@ -36,9 +36,9 @@ public class UnattachAllAi extends SpellAbilityAi { boolean chance = r.nextFloat() <= .9; // Attach spells always have a target - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - tgt.resetTargets(); + sa.resetTargets(); } if (abCost != null && abCost.getTotalMana().countX() > 0 && source.getSVar("X").equals("Count$xPaid")) { @@ -69,7 +69,7 @@ public class UnattachAllAi extends SpellAbilityAi { final Player opp = ai.getOpponent(); // Check if there are any valid targets List targets = new ArrayList(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt == null) { targets = AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam("Defined"), sa); } diff --git a/src/main/java/forge/card/ability/ai/UntapAi.java b/src/main/java/forge/card/ability/ai/UntapAi.java index f83c1f583ee..a3d14dd6538 100644 --- a/src/main/java/forge/card/ability/ai/UntapAi.java +++ b/src/main/java/forge/card/ability/ai/UntapAi.java @@ -10,7 +10,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCost; import forge.game.player.Player; @@ -24,7 +24,7 @@ public class UntapAi extends SpellAbilityAi { */ @Override protected boolean canPlayAI(Player ai, SpellAbility sa) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card source = sa.getSourceCard(); final Cost cost = sa.getPayCosts(); @@ -51,7 +51,7 @@ public class UntapAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt == null) { if (mandatory) { @@ -79,7 +79,7 @@ public class UntapAi extends SpellAbilityAi { @Override public boolean chkAIDrawback(SpellAbility sa, Player ai) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); boolean randomReturn = true; @@ -100,7 +100,7 @@ public class UntapAi extends SpellAbilityAi { *

* * @param tgt - * a {@link forge.card.spellability.Target} object. + * a {@link forge.card.spellability.TargetRestrictions} object. * @param af * a {@link forge.card.ability.AbilityFactory} object. * @param sa @@ -109,7 +109,7 @@ public class UntapAi extends SpellAbilityAi { * a boolean. * @return a boolean. */ - private static boolean untapPrefTargeting(final Player ai, final Target tgt, final SpellAbility sa, final boolean mandatory) { + private static boolean untapPrefTargeting(final Player ai, final TargetRestrictions tgt, final SpellAbility sa, final boolean mandatory) { final Card source = sa.getSourceCard(); Player targetController = ai; @@ -132,12 +132,12 @@ public class UntapAi extends SpellAbilityAi { return false; } - while (tgt.getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) { Card choice = null; if (untapList.size() == 0) { - if ((tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (tgt.getNumTargeted() == 0)) { - tgt.resetTargets(); + if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (sa.getTargets().getNumTargeted() == 0)) { + sa.resetTargets(); return false; } else { // TODO is this good enough? for up to amounts? @@ -157,8 +157,8 @@ public class UntapAi extends SpellAbilityAi { } if (choice == null) { // can't find anything left - if ((tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (tgt.getNumTargeted() == 0)) { - tgt.resetTargets(); + if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (sa.getTargets().getNumTargeted() == 0)) { + sa.resetTargets(); return false; } else { // TODO is this good enough? for up to amounts? @@ -167,7 +167,7 @@ public class UntapAi extends SpellAbilityAi { } untapList.remove(choice); - tgt.addTarget(choice); + sa.getTargets().add(choice); } return true; } @@ -187,7 +187,7 @@ public class UntapAi extends SpellAbilityAi { */ private boolean untapUnpreferredTargeting(final SpellAbility sa, final boolean mandatory) { final Card source = sa.getSourceCard(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); List list = sa.getActivatingPlayer().getGame().getCardsIn(ZoneType.Battlefield); @@ -228,7 +228,7 @@ public class UntapAi extends SpellAbilityAi { * @param source * a {@link forge.Card} object. * @param tgt - * a {@link forge.card.spellability.Target} object. + * a {@link forge.card.spellability.TargetRestrictions} object. * @param af * a {@link forge.card.ability.AbilityFactory} object. * @param sa @@ -239,8 +239,9 @@ public class UntapAi extends SpellAbilityAi { * a {@link forge.CardList} object. * @return a boolean. */ - private boolean untapTargetList(final Card source, final Target tgt, final SpellAbility sa, final boolean mandatory, final List tapList) { - for (final Card c : tgt.getTargetCards()) { + private boolean untapTargetList(final Card source, final TargetRestrictions tgt, final SpellAbility sa, final boolean mandatory, final List tapList) { + + for (final Card c : sa.getTargets().getTargetCards()) { tapList.remove(c); } @@ -248,13 +249,13 @@ public class UntapAi extends SpellAbilityAi { return false; } - while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { + while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) { Card choice = null; if (tapList.size() == 0) { - if ((tgt.getNumTargeted() < tgt.getMinTargets(source, sa)) || (tgt.getNumTargeted() == 0)) { + if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(source, sa)) || (sa.getTargets().getNumTargeted() == 0)) { if (!mandatory) { - tgt.resetTargets(); + sa.resetTargets(); } return false; } else { @@ -274,9 +275,9 @@ public class UntapAi extends SpellAbilityAi { } if (choice == null) { // can't find anything left - if ((tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (tgt.getNumTargeted() == 0)) { + if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (sa.getTargets().getNumTargeted() == 0)) { if (!mandatory) { - tgt.resetTargets(); + sa.resetTargets(); } return false; } else { @@ -286,7 +287,7 @@ public class UntapAi extends SpellAbilityAi { } tapList.remove(choice); - tgt.addTarget(choice); + sa.getTargets().add(choice); } return true; diff --git a/src/main/java/forge/card/ability/effects/AddTurnEffect.java b/src/main/java/forge/card/ability/effects/AddTurnEffect.java index e3792d20283..47ca309296c 100644 --- a/src/main/java/forge/card/ability/effects/AddTurnEffect.java +++ b/src/main/java/forge/card/ability/effects/AddTurnEffect.java @@ -5,7 +5,6 @@ import java.util.List; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.game.phase.ExtraTurn; import forge.game.player.Player; @@ -39,17 +38,10 @@ public class AddTurnEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { final int numTurns = AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("NumTurns"), sa); - List tgtPlayers; - - final Target tgt = sa.getTarget(); - if (tgt != null) { - tgtPlayers = tgt.getTargetPlayers(); - } else { - tgtPlayers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa); - } + List tgtPlayers = getTargetPlayers(sa); for (final Player p : tgtPlayers) { - if ((tgt == null) || p.canBeTargetedBy(sa)) { + if ((sa.getTargetRestrictions() == null) || p.canBeTargetedBy(sa)) { for (int i = 0; i < numTurns; i++) { ExtraTurn extra = p.getGame().getPhaseHandler().addExtraTurn(p); if (sa.hasParam("LoseAtEndStep")) { diff --git a/src/main/java/forge/card/ability/effects/AnimateAllEffect.java b/src/main/java/forge/card/ability/effects/AnimateAllEffect.java index 14f41a6cdae..582a25054d7 100644 --- a/src/main/java/forge/card/ability/effects/AnimateAllEffect.java +++ b/src/main/java/forge/card/ability/effects/AnimateAllEffect.java @@ -14,7 +14,6 @@ import forge.card.ability.AbilityFactory; import forge.card.ability.AbilityUtils; import forge.card.replacement.ReplacementEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.card.staticability.StaticAbility; import forge.card.trigger.Trigger; import forge.card.trigger.TriggerHandler; @@ -121,16 +120,8 @@ public class AnimateAllEffect extends AnimateEffectBase { } List list; - List tgtPlayers = null; - - final Target tgt = sa.getTarget(); - if (tgt != null) { - tgtPlayers = tgt.getTargetPlayers(); - } else if (sa.hasParam("Defined")) { - // use it - tgtPlayers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa); - } - + List tgtPlayers = getTargetPlayers(sa); + if ((tgtPlayers == null) || tgtPlayers.isEmpty()) { list = game.getCardsIn(ZoneType.Battlefield); } else { diff --git a/src/main/java/forge/card/ability/effects/AnimateEffect.java b/src/main/java/forge/card/ability/effects/AnimateEffect.java index 6cb24d40ad6..60539cac9a7 100644 --- a/src/main/java/forge/card/ability/effects/AnimateEffect.java +++ b/src/main/java/forge/card/ability/effects/AnimateEffect.java @@ -13,7 +13,6 @@ import forge.card.ability.AbilityFactory; import forge.card.ability.AbilityUtils; import forge.card.replacement.ReplacementEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.card.staticability.StaticAbility; import forge.card.trigger.Trigger; import forge.card.trigger.TriggerHandler; @@ -27,8 +26,7 @@ public class AnimateEffect extends AnimateEffectBase { @Override public void resolve(final SpellAbility sa) { final Card source = sa.getSourceCard(); - final Card host = sa.getSourceCard(); - final Map svars = host.getSVars(); + final Map svars = source.getSVars(); String animateRemembered = null; @@ -46,11 +44,11 @@ public class AnimateEffect extends AnimateEffectBase { // AF specific sa int power = -1; if (sa.hasParam("Power")) { - power = AbilityUtils.calculateAmount(host, sa.getParam("Power"), sa); + power = AbilityUtils.calculateAmount(source, sa.getParam("Power"), sa); } int toughness = -1; if (sa.hasParam("Toughness")) { - toughness = AbilityUtils.calculateAmount(host, sa.getParam("Toughness"), sa); + toughness = AbilityUtils.calculateAmount(source, sa.getParam("Toughness"), sa); } final Game game = sa.getActivatingPlayer().getGame(); @@ -74,7 +72,7 @@ public class AnimateEffect extends AnimateEffectBase { // allow ChosenType - overrides anything else specified if (types.contains("ChosenType")) { types.clear(); - types.add(host.getChosenType()); + types.add(source.getChosenType()); } final ArrayList keywords = new ArrayList(); @@ -106,7 +104,7 @@ public class AnimateEffect extends AnimateEffectBase { final String colors = sa.getParam("Colors"); if (colors.equals("ChosenColor")) { - tmpDesc = CardUtil.getShortColorsString(host.getChosenColor()); + tmpDesc = CardUtil.getShortColorsString(source.getChosenColor()); } else { tmpDesc = CardUtil.getShortColorsString(new ArrayList(Arrays.asList(colors.split(",")))); } @@ -137,8 +135,7 @@ public class AnimateEffect extends AnimateEffectBase { sVars.addAll(Arrays.asList(sa.getParam("sVars").split(","))); } - final Target tgt = sa.getTarget(); - List tgts = tgt != null ? tgts = tgt.getTargetCards() : AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa); + List tgts = getTargetCards(sa); for (final Card c : tgts) { @@ -165,7 +162,7 @@ public class AnimateEffect extends AnimateEffectBase { final ArrayList addedAbilities = new ArrayList(); if (abilities.size() > 0) { for (final String s : abilities) { - final String actualAbility = host.getSVar(s); + final String actualAbility = source.getSVar(s); final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, c); addedAbilities.add(grantedAbility); c.addSpellAbility(grantedAbility); @@ -176,7 +173,7 @@ public class AnimateEffect extends AnimateEffectBase { final ArrayList addedTriggers = new ArrayList(); if (triggers.size() > 0) { for (final String s : triggers) { - final String actualTrigger = host.getSVar(s); + final String actualTrigger = source.getSVar(s); final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, c, false); addedTriggers.add(c.addTrigger(parsedTrigger)); } @@ -196,7 +193,7 @@ public class AnimateEffect extends AnimateEffectBase { // itself a static ability) if (stAbs.size() > 0) { for (final String s : stAbs) { - final String actualAbility = host.getSVar(s); + final String actualAbility = source.getSVar(s); c.addStaticAbility(actualAbility); } } @@ -204,7 +201,7 @@ public class AnimateEffect extends AnimateEffectBase { // give sVars if (sVars.size() > 0) { for (final String s : sVars) { - final String actualsVar = host.getSVar(s); + final String actualsVar = source.getSVar(s); c.setSVar(s, actualsVar); } } @@ -230,7 +227,7 @@ public class AnimateEffect extends AnimateEffectBase { // give Remembered if (animateRemembered != null) { - for (final Object o : AbilityUtils.getDefinedObjects(host, animateRemembered, sa)) { + for (final Object o : AbilityUtils.getDefinedObjects(source, animateRemembered, sa)) { c.addRemembered(o); } } @@ -266,13 +263,13 @@ public class AnimateEffect extends AnimateEffectBase { if (sa.hasParam("UntilEndOfCombat")) { game.getEndOfCombat().addUntil(unanimate); } else if (sa.hasParam("UntilHostLeavesPlay")) { - host.addLeavesPlayCommand(unanimate); + source.addLeavesPlayCommand(unanimate); } else if (sa.hasParam("UntilYourNextUpkeep")) { - game.getUpkeep().addUntil(host.getController(), unanimate); + game.getUpkeep().addUntil(source.getController(), unanimate); } else if (sa.hasParam("UntilControllerNextUntap")) { game.getUntap().addUntil(c.getController(), unanimate); } else if (sa.hasParam("UntilYourNextTurn")) { - game.getCleanup().addUntil(host.getController(), unanimate); + game.getCleanup().addUntil(source.getController(), unanimate); } else { game.getEndOfTurn().addUntil(unanimate); } @@ -321,8 +318,7 @@ public class AnimateEffect extends AnimateEffectBase { final StringBuilder sb = new StringBuilder(); - final Target tgt = sa.getTarget(); - final List tgts = tgt != null ? tgt.getTargetCards() : AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa); + final List tgts = getTargetCards(sa); for (final Card c : tgts) { sb.append(c).append(" "); diff --git a/src/main/java/forge/card/ability/effects/AttachEffect.java b/src/main/java/forge/card/ability/effects/AttachEffect.java index 19bbb708e5a..b2bc8fbc5b3 100644 --- a/src/main/java/forge/card/ability/effects/AttachEffect.java +++ b/src/main/java/forge/card/ability/effects/AttachEffect.java @@ -12,10 +12,11 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.ApiType; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.player.Player; import forge.game.zone.ZoneType; +import forge.util.Lang; public class AttachEffect extends SpellAbilityEffect { @@ -38,7 +39,7 @@ public class AttachEffect extends SpellAbilityEffect { Card source = sa.getSourceCard(); Card card = sa.getSourceCard(); - final List targets = getTargetObjects(sa); + final List targets = getTargets(sa); if (sa.hasParam("Object")) { card = AbilityUtils.getDefinedCards(source, sa.getParam("Object"), sa).get(0); @@ -61,13 +62,10 @@ public class AttachEffect extends SpellAbilityEffect { sb.append(" Attach to "); - final List targets = getTargetObjects(sa); + final List targets = getTargets(sa); // Should never allow more than one Attachment per card - for (final Object o : targets) { - sb.append(o).append(" "); - } - + sb.append(Lang.joinHomogenous(targets)); return sb.toString(); } @@ -179,7 +177,7 @@ public class AttachEffect extends SpellAbilityEffect { } aura.setActivatingPlayer(source.getController()); final Game game = source.getGame(); - final Target tgt = aura.getTarget(); + final TargetRestrictions tgt = aura.getTargetRestrictions(); Player p = source.getController(); if (tgt.canTgtPlayer()) { diff --git a/src/main/java/forge/card/ability/effects/BecomesBlockedEffect.java b/src/main/java/forge/card/ability/effects/BecomesBlockedEffect.java index 6f23e47fe1f..a8fedbd21ef 100644 --- a/src/main/java/forge/card/ability/effects/BecomesBlockedEffect.java +++ b/src/main/java/forge/card/ability/effects/BecomesBlockedEffect.java @@ -11,7 +11,7 @@ import forge.card.ability.SpellAbilityEffect; import forge.card.cardfactory.CardFactoryUtil; import forge.card.spellability.Ability; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.card.trigger.TriggerType; import forge.game.Game; @@ -33,7 +33,7 @@ public class BecomesBlockedEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { final Game game = sa.getActivatingPlayer().getGame(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); for (final Card c : getTargetCards(sa)) { if ((tgt == null) || c.canBeTargetedBy(sa)) { game.getCombat().setBlocked(c); diff --git a/src/main/java/forge/card/ability/effects/ChangeTargetsEffect.java b/src/main/java/forge/card/ability/effects/ChangeTargetsEffect.java index 424e2fb1bf3..588c2751a5c 100644 --- a/src/main/java/forge/card/ability/effects/ChangeTargetsEffect.java +++ b/src/main/java/forge/card/ability/effects/ChangeTargetsEffect.java @@ -5,6 +5,7 @@ import java.util.List; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbilityStackInstance; +import forge.card.spellability.TargetChoices; import forge.game.zone.MagicStack; /** @@ -18,7 +19,7 @@ public class ChangeTargetsEffect extends SpellAbilityEffect { */ @Override public void resolve(SpellAbility sa) { - final List sas = getTargetSpellAbilities(sa); + final List sas = getTargetSpells(sa); final boolean remember = sa.hasParam("RememberTargetedCard"); final MagicStack stack = sa.getActivatingPlayer().getGame().getStack(); @@ -33,7 +34,8 @@ public class ChangeTargetsEffect extends SpellAbilityEffect { while(changingTgtSI != null) { // Update targets, with a potential new target SpellAbility changingTgtSA = changingTgtSI.getSpellAbility(); - changingTgtSI.updateTarget(sa.getActivatingPlayer().getController().chooseTargets(changingTgtSA)); + TargetChoices newTarget = sa.getActivatingPlayer().getController().chooseTargets(changingTgtSA); + changingTgtSI.updateTarget(newTarget); changingTgtSI = changingTgtSI.getSubInstace(); } diff --git a/src/main/java/forge/card/ability/effects/ChangeZoneAllEffect.java b/src/main/java/forge/card/ability/effects/ChangeZoneAllEffect.java index 19e7a7a7cfe..46617b333ac 100644 --- a/src/main/java/forge/card/ability/effects/ChangeZoneAllEffect.java +++ b/src/main/java/forge/card/ability/effects/ChangeZoneAllEffect.java @@ -46,7 +46,7 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect { List cards = new ArrayList(); - List tgtPlayers = getTargetPlayersEmptyAsDefault(sa); + List tgtPlayers = getTargetPlayers(sa); final Game game = sa.getActivatingPlayer().getGame(); if ((tgtPlayers == null) || tgtPlayers.isEmpty() || sa.hasParam("UseAllOriginZones")) { @@ -106,7 +106,7 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect { // Auras without Candidates stay in their current location if (c.isAura()) { final SpellAbility saAura = AttachEffect.getAttachSpellAbility(c); - if (!saAura.getTarget().hasCandidates(saAura, false)) { + if (!saAura.getTargetRestrictions().hasCandidates(saAura, false)) { continue; } } diff --git a/src/main/java/forge/card/ability/effects/ChangeZoneEffect.java b/src/main/java/forge/card/ability/effects/ChangeZoneEffect.java index 6f66d772bd6..aaa22295c56 100644 --- a/src/main/java/forge/card/ability/effects/ChangeZoneEffect.java +++ b/src/main/java/forge/card/ability/effects/ChangeZoneEffect.java @@ -5,6 +5,8 @@ import java.util.HashMap; import java.util.List; import com.google.common.base.Predicates; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; import forge.Card; import forge.CardCharacteristicName; @@ -18,7 +20,7 @@ import forge.card.ability.ai.ChangeZoneAi; import forge.card.spellability.AbilitySub; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbilityStackInstance; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.card.trigger.TriggerType; import forge.game.Game; import forge.game.player.Player; @@ -70,15 +72,15 @@ public class ChangeZoneEffect extends SpellAbilityEffect { sb.append(" "); // Player whose cards will change zones - List fetchers = new ArrayList(); + List fetchers = null; if (sa.hasParam("DefinedPlayer")) { fetchers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("DefinedPlayer"), sa); } - if (fetchers.isEmpty() && sa.hasParam("ValidTgts") && sa.getTarget() != null) { - fetchers = sa.getTarget().getTargetPlayers(); + if (fetchers == null && sa.hasParam("ValidTgts") && sa.usesTargeting()) { + fetchers = Lists.newArrayList(sa.getTargets().getTargetPlayers()); } - if (fetchers.isEmpty()) { - fetchers.add(sa.getSourceCard().getController()); + if (fetchers == null) { + fetchers = Lists.newArrayList(sa.getSourceCard().getController()); } final String fetcherNames = Lang.joinHomogenous(fetchers, Player.Accessors.FN_GET_NAME); @@ -238,15 +240,12 @@ public class ChangeZoneEffect extends SpellAbilityEffect { final StringBuilder sbTargets = new StringBuilder(); - List tgts; - if (sa.getTarget() != null) { - tgts = sa.getTarget().getTargetCards(); + Iterable tgts; + if (sa.usesTargeting()) { + tgts = sa.getTargets().getTargetCards(); } else { // otherwise add self to list and go from there - tgts = new ArrayList(); - for (final Card c : sa.knownDetermineDefined(sa.getParam("Defined"))) { - tgts.add(c); - } + tgts = sa.knownDetermineDefined(sa.getParam("Defined")); } for (final Card c : tgts) { @@ -255,7 +254,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { final String targetname = sbTargets.toString(); - final String pronoun = tgts.size() > 1 ? " their " : " its "; + final String pronoun = Iterables.size(tgts) > 1 ? " their " : " its "; final String fromGraveyard = " from the graveyard"; @@ -367,11 +366,9 @@ public class ChangeZoneEffect extends SpellAbilityEffect { * @param sa * a {@link forge.card.spellability.SpellAbility} object. */ - private static void changeKnownOriginResolve(final SpellAbility sa) { - List tgtCards; - List sas; - - final Target tgt = sa.getTarget(); + private void changeKnownOriginResolve(final SpellAbility sa) { + Iterable tgtCards = getTargetCards(sa); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Player player = sa.getActivatingPlayer(); final Card hostCard = sa.getSourceCard(); final Game game = player.getGame(); @@ -379,23 +376,8 @@ public class ChangeZoneEffect extends SpellAbilityEffect { final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination")); final List origin = ZoneType.listValueOf(sa.getParam("Origin")); - if (tgt != null) { - tgtCards = tgt.getTargetCards(); - } else { - tgtCards = new ArrayList(); - for (final Card c : AbilityUtils.getDefinedCards(hostCard, sa.getParam("Defined"), sa)) { - tgtCards.add(c); - } - } - // changing zones for spells on the stack - if (tgt != null) { - sas = tgt.getTargetSAs(); - } else { - sas = AbilityUtils.getDefinedSpellAbilities(hostCard, sa.getParam("Defined"), sa); - } - - for (final SpellAbility tgtSA : sas) { + for (final SpellAbility tgtSA : getTargetSpells(sa)) { if (!tgtSA.isSpell()) { // Catch any abilities or triggers that slip through somehow continue; } @@ -422,135 +404,134 @@ public class ChangeZoneEffect extends SpellAbilityEffect { boolean optional = sa.hasParam("Optional"); - if (tgtCards.size() != 0) { - for (final Card tgtC : tgtCards) { - if (tgt != null && tgtC.isInPlay() && !tgtC.canBeTargetedBy(sa)) { - continue; + + for (final Card tgtC : tgtCards) { + if (tgt != null && tgtC.isInPlay() && !tgtC.canBeTargetedBy(sa)) { + continue; + } + + final String prompt = String.format("Do you want to move %s from %s to %s?", tgtC, origin, destination); + if (optional && false == player.getController().confirmAction(sa, null, prompt) ) + continue; + + final Zone originZone = game.getZoneOf(tgtC); + + // if Target isn't in the expected Zone, continue + + if (originZone == null || !origin.contains(originZone.getZoneType())) { + continue; + } + + Card movedCard = null; + + if (destination.equals(ZoneType.Library)) { + // library position is zero indexed + final int libraryPosition = sa.hasParam("LibraryPosition") ? Integer.parseInt(sa.getParam("LibraryPosition")) : 0; + + movedCard = game.getAction().moveToLibrary(tgtC, libraryPosition); + + // for things like Gaea's Blessing + if (sa.hasParam("Shuffle")) { + tgtC.getOwner().shuffle(); } + } else { + if (destination.equals(ZoneType.Battlefield)) { + if (sa.hasParam("Tapped") || sa.hasParam("Ninjutsu")) { + tgtC.setTapped(true); + } + if (sa.hasParam("GainControl")) { + if (sa.hasParam("NewController")) { + final Player p = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("NewController"), sa).get(0); + tgtC.setController(p, game.getNextTimestamp()); + } else { + tgtC.setController(player, game.getNextTimestamp()); + } + } + if (sa.hasParam("AttachedTo")) { + List list = AbilityUtils.getDefinedCards(hostCard, sa.getParam("AttachedTo"), sa); + if (list.isEmpty()) { + list = game.getCardsIn(ZoneType.Battlefield); + list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), tgtC.getController(), tgtC); + } + if (!list.isEmpty()) { + Card attachedTo = player.getController().chooseSingleCardForEffect(list, sa, tgtC + " - Select a card to attach to."); + if (tgtC.isAura()) { + if (tgtC.isEnchanting()) { + // If this Card is already Enchanting something, need + // to unenchant it, then clear out the commands + final GameEntity oldEnchanted = tgtC.getEnchanting(); + tgtC.removeEnchanting(oldEnchanted); + } + tgtC.enchantEntity(attachedTo); + } else if (tgtC.isEquipment()) { //Equipment + if (tgtC.isEquipping()) { + final Card oldEquiped = tgtC.getEquippingCard(); + tgtC.removeEquipping(oldEquiped); + } + tgtC.equipCard(attachedTo); + } else { // fortification + if (tgtC.isFortifying()) { + final Card oldFortified = tgtC.getFortifyingCard(); + tgtC.removeFortifying(oldFortified); + } + tgtC.fortifyCard(attachedTo); + } + } else { // When it should enter the battlefield attached to an illegal permanent it fails + continue; + } + } - final String prompt = String.format("Do you want to move %s from %s to %s?", tgtC, origin, destination); - if (optional && false == player.getController().confirmAction(sa, null, prompt) ) - continue; + // Auras without Candidates stay in their current + // location + if (tgtC.isAura()) { + final SpellAbility saAura = AttachEffect.getAttachSpellAbility(tgtC); + saAura.setActivatingPlayer(sa.getActivatingPlayer()); + if (!saAura.getTargetRestrictions().hasCandidates(saAura, false)) { + continue; + } + } - final Zone originZone = game.getZoneOf(tgtC); + movedCard = game.getAction().moveTo(tgtC.getController().getZone(destination), tgtC); - // if Target isn't in the expected Zone, continue - - if (originZone == null || !origin.contains(originZone.getZoneType())) { - continue; - } - - Card movedCard = null; - - if (destination.equals(ZoneType.Library)) { - // library position is zero indexed - final int libraryPosition = sa.hasParam("LibraryPosition") ? Integer.parseInt(sa.getParam("LibraryPosition")) : 0; - - movedCard = game.getAction().moveToLibrary(tgtC, libraryPosition); - - // for things like Gaea's Blessing - if (sa.hasParam("Shuffle")) { - tgtC.getOwner().shuffle(); + if (sa.hasParam("Ninjutsu") || sa.hasParam("Attacking")) { + // What should they attack? + // TODO Ninjutsu needs to actually select the Defender, instead of auto selecting player + List defenders = game.getCombat().getDefenders(); + if (!defenders.isEmpty()) { + // Blockeres are already declared, set this to unblocked + game.getCombat().addAttacker(tgtC, defenders.get(0), false); + } + } + if (sa.hasParam("Tapped") || sa.hasParam("Ninjutsu")) { + tgtC.setTapped(true); } } else { - if (destination.equals(ZoneType.Battlefield)) { - if (sa.hasParam("Tapped") || sa.hasParam("Ninjutsu")) { - tgtC.setTapped(true); - } - if (sa.hasParam("GainControl")) { - if (sa.hasParam("NewController")) { - final Player p = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("NewController"), sa).get(0); - tgtC.setController(p, game.getNextTimestamp()); - } else { - tgtC.setController(player, game.getNextTimestamp()); - } - } - if (sa.hasParam("AttachedTo")) { - List list = AbilityUtils.getDefinedCards(hostCard, sa.getParam("AttachedTo"), sa); - if (list.isEmpty()) { - list = game.getCardsIn(ZoneType.Battlefield); - list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), tgtC.getController(), tgtC); - } - if (!list.isEmpty()) { - Card attachedTo = player.getController().chooseSingleCardForEffect(list, sa, tgtC + " - Select a card to attach to."); - if (tgtC.isAura()) { - if (tgtC.isEnchanting()) { - // If this Card is already Enchanting something, need - // to unenchant it, then clear out the commands - final GameEntity oldEnchanted = tgtC.getEnchanting(); - tgtC.removeEnchanting(oldEnchanted); - } - tgtC.enchantEntity(attachedTo); - } else if (tgtC.isEquipment()) { //Equipment - if (tgtC.isEquipping()) { - final Card oldEquiped = tgtC.getEquippingCard(); - tgtC.removeEquipping(oldEquiped); - } - tgtC.equipCard(attachedTo); - } else { // fortification - if (tgtC.isFortifying()) { - final Card oldFortified = tgtC.getFortifyingCard(); - tgtC.removeFortifying(oldFortified); - } - tgtC.fortifyCard(attachedTo); - } - } else { // When it should enter the battlefield attached to an illegal permanent it fails - continue; - } - } - - // Auras without Candidates stay in their current - // location - if (tgtC.isAura()) { - final SpellAbility saAura = AttachEffect.getAttachSpellAbility(tgtC); - saAura.setActivatingPlayer(sa.getActivatingPlayer()); - if (!saAura.getTarget().hasCandidates(saAura, false)) { - continue; - } - } - - movedCard = game.getAction().moveTo(tgtC.getController().getZone(destination), tgtC); - - if (sa.hasParam("Ninjutsu") || sa.hasParam("Attacking")) { - // What should they attack? - // TODO Ninjutsu needs to actually select the Defender, instead of auto selecting player - List defenders = game.getCombat().getDefenders(); - if (!defenders.isEmpty()) { - // Blockeres are already declared, set this to unblocked - game.getCombat().addAttacker(tgtC, defenders.get(0), false); - } - } - if (sa.hasParam("Tapped") || sa.hasParam("Ninjutsu")) { - tgtC.setTapped(true); - } - } else { - movedCard = game.getAction().moveTo(destination, tgtC); - // If a card is Exiled from the stack, remove its spells from the stack - if (sa.hasParam("Fizzle")) { - ArrayList spells = tgtC.getSpellAbilities(); - for (SpellAbility spell : spells) { - if (tgtC.isInZone(ZoneType.Exile)) { - final SpellAbilityStackInstance si = game.getStack().getInstanceFromSpellAbility(spell); - if (si != null) { - game.getStack().remove(si); - } + movedCard = game.getAction().moveTo(destination, tgtC); + // If a card is Exiled from the stack, remove its spells from the stack + if (sa.hasParam("Fizzle")) { + ArrayList spells = tgtC.getSpellAbilities(); + for (SpellAbility spell : spells) { + if (tgtC.isInZone(ZoneType.Exile)) { + final SpellAbilityStackInstance si = game.getStack().getInstanceFromSpellAbility(spell); + if (si != null) { + game.getStack().remove(si); } } } - if (sa.hasParam("ExileFaceDown")) { - movedCard.setState(CardCharacteristicName.FaceDown); - } + } + if (sa.hasParam("ExileFaceDown")) { + movedCard.setState(CardCharacteristicName.FaceDown); } } - if (remember != null) { - hostCard.addRemembered(movedCard); - } - if (forget != null) { - hostCard.getRemembered().remove(movedCard); - } - if (imprint != null) { - hostCard.addImprinted(movedCard); - } + } + if (remember != null) { + hostCard.addRemembered(movedCard); + } + if (forget != null) { + hostCard.getRemembered().remove(movedCard); + } + if (imprint != null) { + hostCard.addImprinted(movedCard); } } } @@ -582,8 +563,8 @@ public class ChangeZoneEffect extends SpellAbilityEffect { Player chooser = null; if (sa.hasParam("Chooser")) { final String choose = sa.getParam("Chooser"); - if (choose.equals("Targeted") && (sa.getTarget().getTargetPlayers() != null)) { - chooser = sa.getTarget().getTargetPlayers().get(0); + if (choose.equals("Targeted") && sa.getTargets().isTargetingAnyPlayer()) { + chooser = sa.getTargets().getFirstTargetedPlayer(); } else { chooser = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), choose, sa).get(0); } @@ -621,9 +602,9 @@ public class ChangeZoneEffect extends SpellAbilityEffect { final boolean optional = sa.hasParam("Optional"); final Game game = player.getGame(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - final List players = tgt.getTargetPlayers(); + final List players = Lists.newArrayList(sa.getTargets().getTargetPlayers()); player = sa.hasParam("DefinedPlayer") ? player : players.get(0); if (players.contains(player) && !player.canBeTargetedBy(sa)) { return; diff --git a/src/main/java/forge/card/ability/effects/ChooseCardEffect.java b/src/main/java/forge/card/ability/effects/ChooseCardEffect.java index 909a7f05ba3..f308c7e90a9 100644 --- a/src/main/java/forge/card/ability/effects/ChooseCardEffect.java +++ b/src/main/java/forge/card/ability/effects/ChooseCardEffect.java @@ -12,7 +12,7 @@ import forge.card.CardType; import forge.card.ability.SpellAbilityEffect; import forge.card.cardfactory.CardFactoryUtil; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -37,7 +37,7 @@ public class ChooseCardEffect extends SpellAbilityEffect { final Game game = sa.getActivatingPlayer().getGame(); final ArrayList chosen = new ArrayList(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final List tgtPlayers = getTargetPlayers(sa); ZoneType choiceZone = ZoneType.Battlefield; diff --git a/src/main/java/forge/card/ability/effects/ChooseCardNameEffect.java b/src/main/java/forge/card/ability/effects/ChooseCardNameEffect.java index 95ad9b9cc1f..db7355976f5 100644 --- a/src/main/java/forge/card/ability/effects/ChooseCardNameEffect.java +++ b/src/main/java/forge/card/ability/effects/ChooseCardNameEffect.java @@ -19,7 +19,7 @@ import forge.card.CardRulesPredicates; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtilCard; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -46,7 +46,7 @@ public class ChooseCardNameEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { final Card host = sa.getSourceCard(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final List tgtPlayers = getTargetPlayers(sa); String valid = "Card"; diff --git a/src/main/java/forge/card/ability/effects/ChooseColorEffect.java b/src/main/java/forge/card/ability/effects/ChooseColorEffect.java index d42c35fefa0..b0ee32eacfe 100644 --- a/src/main/java/forge/card/ability/effects/ChooseColorEffect.java +++ b/src/main/java/forge/card/ability/effects/ChooseColorEffect.java @@ -11,7 +11,7 @@ import forge.CardPredicates; import forge.Constant; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtilCard; import forge.game.player.Player; @@ -42,7 +42,7 @@ public class ChooseColorEffect extends SpellAbilityEffect { final List tgtPlayers = getTargetPlayers(sa); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); for (final Player p : tgtPlayers) { if ((tgt == null) || p.canBeTargetedBy(sa)) { diff --git a/src/main/java/forge/card/ability/effects/ChooseGenericEffect.java b/src/main/java/forge/card/ability/effects/ChooseGenericEffect.java index c0dedc6f317..c2a27f9ff9a 100644 --- a/src/main/java/forge/card/ability/effects/ChooseGenericEffect.java +++ b/src/main/java/forge/card/ability/effects/ChooseGenericEffect.java @@ -13,7 +13,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.AbilitySub; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.gui.GuiChoose; import forge.util.Aggregates; @@ -41,9 +41,9 @@ public class ChooseGenericEffect extends SpellAbilityEffect { choices.put(s, theseParams.get("ChoiceDescription")); } - final List tgtPlayers = getDefinedPlayersBeforeTargetOnes(sa); + final List tgtPlayers = getDefinedPlayersOrTargeted(sa); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); for (final Player p : tgtPlayers) { if (tgt != null && !p.canBeTargetedBy(sa)) { diff --git a/src/main/java/forge/card/ability/effects/ChooseNumberEffect.java b/src/main/java/forge/card/ability/effects/ChooseNumberEffect.java index a34f74e2452..19a866feb35 100644 --- a/src/main/java/forge/card/ability/effects/ChooseNumberEffect.java +++ b/src/main/java/forge/card/ability/effects/ChooseNumberEffect.java @@ -9,7 +9,7 @@ import forge.Card; import forge.card.ability.SpellAbilityEffect; import forge.card.cardfactory.CardFactoryUtil; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.gui.GuiDialog; @@ -43,7 +43,7 @@ public class ChooseNumberEffect extends SpellAbilityEffect { final int max = StringUtils.isNumeric(sMax) ? Integer.parseInt(sMax) : CardFactoryUtil.xCount(card, card.getSVar(sMax)); final List tgtPlayers = getTargetPlayers(sa); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); for (final Player p : tgtPlayers) { if ((tgt == null) || p.canBeTargetedBy(sa)) { diff --git a/src/main/java/forge/card/ability/effects/ChoosePlayerEffect.java b/src/main/java/forge/card/ability/effects/ChoosePlayerEffect.java index eefd4603e9c..f9570efe5f4 100644 --- a/src/main/java/forge/card/ability/effects/ChoosePlayerEffect.java +++ b/src/main/java/forge/card/ability/effects/ChoosePlayerEffect.java @@ -6,7 +6,7 @@ import forge.Card; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; public class ChoosePlayerEffect extends SpellAbilityEffect { @@ -29,7 +29,7 @@ public class ChoosePlayerEffect extends SpellAbilityEffect { final List tgtPlayers = getTargetPlayers(sa); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final List choices = sa.hasParam("Choices") ? AbilityUtils.getDefinedPlayers( sa.getSourceCard(), sa.getParam("Choices"), sa) : sa.getActivatingPlayer().getGame().getPlayers(); diff --git a/src/main/java/forge/card/ability/effects/ChooseSourceEffect.java b/src/main/java/forge/card/ability/effects/ChooseSourceEffect.java index 3e3cdf8152c..6edfe7d024a 100644 --- a/src/main/java/forge/card/ability/effects/ChooseSourceEffect.java +++ b/src/main/java/forge/card/ability/effects/ChooseSourceEffect.java @@ -5,8 +5,6 @@ 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; @@ -16,7 +14,7 @@ import forge.card.ability.SpellAbilityEffect; import forge.card.cardfactory.CardFactoryUtil; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbilityStackInstance; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCombat; @@ -42,7 +40,7 @@ public class ChooseSourceEffect extends SpellAbilityEffect { final Card host = sa.getSourceCard(); final Game game = sa.getActivatingPlayer().getGame(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final List tgtPlayers = getTargetPlayers(sa); @@ -190,19 +188,10 @@ public class ChooseSourceEffect extends SpellAbilityEffect { } - final List objects; - final Target threatTgt = abilityOnStack.getTarget(); + List objects = getTargets(abilityOnStack); - if (threatTgt == null) { - if (abilityOnStack.hasParam("Defined")) { - objects = AbilityUtils.getDefinedObjects(source, abilityOnStack.getParam("Defined"), abilityOnStack); - } else if (abilityOnStack.hasParam("ValidPlayers")) { - objects = AbilityUtils.getDefinedPlayers(source, abilityOnStack.getParam("ValidPlayers"), abilityOnStack); - } else - objects = Lists.newArrayList(); - } else { - objects = threatTgt.getTargetPlayers(); - } + if (!abilityOnStack.usesTargeting() && !abilityOnStack.hasParam("Defined") && abilityOnStack.hasParam("ValidPlayers")) + objects = AbilityUtils.getDefinedPlayers(source, abilityOnStack.getParam("ValidPlayers"), abilityOnStack); if (!objects.contains(ai) || abilityOnStack.hasParam("NoPrevention")) { continue; diff --git a/src/main/java/forge/card/ability/effects/ChooseTypeEffect.java b/src/main/java/forge/card/ability/effects/ChooseTypeEffect.java index 03ce88fdcf4..cfec03eb3b5 100644 --- a/src/main/java/forge/card/ability/effects/ChooseTypeEffect.java +++ b/src/main/java/forge/card/ability/effects/ChooseTypeEffect.java @@ -10,7 +10,7 @@ import forge.Constant; import forge.card.CardType; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; public class ChooseTypeEffect extends SpellAbilityEffect { @@ -53,7 +53,7 @@ public class ChooseTypeEffect extends SpellAbilityEffect { } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final List tgtPlayers = getTargetPlayers(sa); if( !validTypes.isEmpty()) { diff --git a/src/main/java/forge/card/ability/effects/CloneEffect.java b/src/main/java/forge/card/ability/effects/CloneEffect.java index a78079f396d..0051e23706c 100644 --- a/src/main/java/forge/card/ability/effects/CloneEffect.java +++ b/src/main/java/forge/card/ability/effects/CloneEffect.java @@ -15,7 +15,7 @@ import forge.card.ability.SpellAbilityEffect; import forge.card.cardfactory.CardFactory; import forge.card.cardfactory.CardFactoryUtil; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.card.trigger.Trigger; import forge.card.trigger.TriggerHandler; import forge.game.Game; @@ -32,14 +32,14 @@ public class CloneEffect extends SpellAbilityEffect { Card tgtCard = host; Card cardToCopy = host; - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (sa.hasParam("Defined")) { List cloneSources = AbilityUtils.getDefinedCards(host, sa.getParam("Defined"), sa); if (!cloneSources.isEmpty()) { cardToCopy = cloneSources.get(0); } } else if (tgt != null) { - cardToCopy = tgt.getTargetCards().get(0); + cardToCopy = sa.getTargets().getFirstTargetedCard(); } List cloneTargets = AbilityUtils.getDefinedCards(host, sa.getParam("CloneTarget"), sa); @@ -61,14 +61,14 @@ public class CloneEffect extends SpellAbilityEffect { // find cloning source i.e. thing to be copied Card cardToCopy = null; - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (sa.hasParam("Defined")) { List cloneSources = AbilityUtils.getDefinedCards(host, sa.getParam("Defined"), sa); if (!cloneSources.isEmpty()) { cardToCopy = cloneSources.get(0); } } else if (tgt != null) { - cardToCopy = tgt.getTargetCards().get(0); + cardToCopy = sa.getTargets().getFirstTargetedCard(); } if (cardToCopy == null) { return; diff --git a/src/main/java/forge/card/ability/effects/ControlExchangeEffect.java b/src/main/java/forge/card/ability/effects/ControlExchangeEffect.java index 6beff52e453..f03bf8abefa 100644 --- a/src/main/java/forge/card/ability/effects/ControlExchangeEffect.java +++ b/src/main/java/forge/card/ability/effects/ControlExchangeEffect.java @@ -3,11 +3,13 @@ package forge.card.ability.effects; import java.util.ArrayList; import java.util.List; +import com.google.common.collect.Lists; + import forge.Card; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; @@ -20,8 +22,8 @@ public class ControlExchangeEffect extends SpellAbilityEffect { protected String getStackDescription(SpellAbility sa) { Card object1 = null; Card object2 = null; - final Target tgt = sa.getTarget(); - List tgts = tgt == null ? new ArrayList() : tgt.getTargetCards(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); + List tgts = tgt == null ? new ArrayList() : Lists.newArrayList(sa.getTargets().getTargetCards()); if (tgts.size() > 0) { object1 = tgts.get(0); } @@ -45,8 +47,8 @@ public class ControlExchangeEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { Card object1 = null; Card object2 = null; - final Target tgt = sa.getTarget(); - List tgts = tgt == null ? new ArrayList() : tgt.getTargetCards(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); + List tgts = tgt == null ? new ArrayList() : Lists.newArrayList(sa.getTargets().getTargetCards()); if (tgts.size() > 0) { object1 = tgts.get(0); } diff --git a/src/main/java/forge/card/ability/effects/ControlGainEffect.java b/src/main/java/forge/card/ability/effects/ControlGainEffect.java index 81582e4a498..5ccb5681ee3 100644 --- a/src/main/java/forge/card/ability/effects/ControlGainEffect.java +++ b/src/main/java/forge/card/ability/effects/ControlGainEffect.java @@ -1,6 +1,5 @@ package forge.card.ability.effects; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -11,7 +10,6 @@ import forge.card.ability.SpellAbilityEffect; import forge.card.mana.ManaCost; import forge.card.spellability.Ability; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.game.Game; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -24,13 +22,7 @@ public class ControlGainEffect extends SpellAbilityEffect { protected String getStackDescription(SpellAbility sa) { final StringBuilder sb = new StringBuilder(); - - final Target tgt = sa.getTarget(); - - List newController = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("NewController"), sa); - if ((tgt != null) && tgt.getTargetPlayers() != null && !tgt.getTargetPlayers().isEmpty()) { - newController = tgt.getTargetPlayers(); - } + List newController = getTargetPlayers(sa, "NewController"); if (newController.size() == 0) { newController.add(sa.getActivatingPlayer()); } @@ -74,7 +66,6 @@ public class ControlGainEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { - List tgtCards = new ArrayList(); Card source = sa.getSourceCard(); final boolean bUntap = sa.hasParam("Untap"); @@ -86,28 +77,16 @@ public class ControlGainEffect extends SpellAbilityEffect { final List kws = sa.hasParam("AddKWs") ? Arrays.asList(sa.getParam("AddKWs").split(" & ")) : null; final List lose = sa.hasParam("LoseControl") ? Arrays.asList(sa.getParam("LoseControl").split(",")) : null; - final Target tgt = sa.getTarget(); - final List controllers; - - if (sa.hasParam("NewController")) { - controllers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("NewController"), sa); - } else if (tgt != null && tgt.getTargetPlayers() != null && tgt.canTgtPlayer()) { - controllers = tgt.getTargetPlayers(); - } else - controllers = new ArrayList(); + final List controllers = getDefinedPlayersOrTargeted(sa, "NewController"); final Player newController = controllers.isEmpty() ? sa.getActivatingPlayer() : controllers.get(0); final Game game = newController.getGame(); + final List tgtCards; if (sa.hasParam("AllValid")) { - tgtCards = game.getCardsIn(ZoneType.Battlefield); - tgtCards = AbilityUtils.filterListByType(tgtCards, sa.getParam("AllValid"), sa); - } else if (sa.hasParam("Defined")) { - tgtCards = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa); - } else { + tgtCards = AbilityUtils.filterListByType(game.getCardsIn(ZoneType.Battlefield), sa.getParam("AllValid"), sa); + } else tgtCards = getTargetCards(sa); - } - // check for lose control criteria right away if (lose != null && lose.contains("LeavesPlay") && !source.isInZone(ZoneType.Battlefield)) { diff --git a/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java b/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java index 84b76fbb47d..d520dae68f1 100644 --- a/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java +++ b/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java @@ -25,7 +25,7 @@ import forge.card.cardfactory.CardFactoryUtil; import forge.card.mana.ManaCost; import forge.card.spellability.Ability; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtilCard; import forge.game.player.Player; @@ -70,7 +70,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect { sa.getParam("NumCopies"), sa) : 1; List tgtCards = getTargetCards(sa); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (sa.hasParam("ValidSupportedCopy")) { List cards = Lists.newArrayList(CardDb.instance().getUniqueCards()); diff --git a/src/main/java/forge/card/ability/effects/CopySpellAbilityEffect.java b/src/main/java/forge/card/ability/effects/CopySpellAbilityEffect.java index c1e7038b242..48d3277f213 100644 --- a/src/main/java/forge/card/ability/effects/CopySpellAbilityEffect.java +++ b/src/main/java/forge/card/ability/effects/CopySpellAbilityEffect.java @@ -6,6 +6,7 @@ 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.CardFactory; @@ -15,14 +16,10 @@ import forge.gui.GuiChoose; public class CopySpellAbilityEffect extends SpellAbilityEffect { - // ************************************************************************* - // ************************* CopySpell ************************************* - // ************************************************************************* - @Override protected String getStackDescription(SpellAbility sa) { final StringBuilder sb = new StringBuilder(); - final List tgtSpells = getTargetSpellAbilities(sa); + final List tgtSpells = getTargetSpells(sa); sb.append("Copy "); // TODO Someone fix this Description when Copying Charms @@ -62,7 +59,7 @@ public class CopySpellAbilityEffect extends SpellAbilityEffect { controller = AbilityUtils.getDefinedPlayers(card, sa.getParam("Controller"), sa).get(0); } - final List tgtSpells = getTargetSpellAbilities(sa); + final List tgtSpells = getTargetSpells(sa); if (tgtSpells.size() == 0) { @@ -112,12 +109,13 @@ public class CopySpellAbilityEffect extends SpellAbilityEffect { chosenSA = GuiChoose.one("Select a spell to copy", tgtSpells); } chosenSA.setActivatingPlayer(controller); - List candidates = chosenSA.getTarget().getAllCandidates(chosenSA, true); + List candidates = chosenSA.getTargetRestrictions().getAllCandidates(chosenSA, true); if (sa.hasParam("CanTargetPlayer")) { // Radiate // Remove targeted players because getAllCandidates include all the valid players - candidates.removeAll(chosenSA.getTarget().getTargetPlayers()); - for (Object o : candidates) { + for(Player p : chosenSA.getTargets().getTargetPlayers()) + candidates.remove(p); + for (ITargetable o : candidates) { CardFactory.copySpellontoStack(card, chosenSA.getSourceCard(), chosenSA, true, o); } } else {// Precursor Golem, Ink-Treader Nephilim diff --git a/src/main/java/forge/card/ability/effects/CounterEffect.java b/src/main/java/forge/card/ability/effects/CounterEffect.java index 251f3212fd3..7bb41e3a411 100644 --- a/src/main/java/forge/card/ability/effects/CounterEffect.java +++ b/src/main/java/forge/card/ability/effects/CounterEffect.java @@ -37,7 +37,7 @@ public class CounterEffect extends SpellAbilityEffect { sas.add(spell); } } else { - sas = getTargetSpellAbilities(sa); + sas = getTargetSpells(sa); } sb.append("countering"); @@ -82,7 +82,7 @@ public class CounterEffect extends SpellAbilityEffect { sas.add(spell); } } else { - sas = getTargetSpellAbilities(sa); + sas = getTargetSpells(sa); } if (sa.hasParam("ForgetOtherTargets")) { diff --git a/src/main/java/forge/card/ability/effects/CountersMoveEffect.java b/src/main/java/forge/card/ability/effects/CountersMoveEffect.java index 4d4878f4bbe..611f5b47898 100644 --- a/src/main/java/forge/card/ability/effects/CountersMoveEffect.java +++ b/src/main/java/forge/card/ability/effects/CountersMoveEffect.java @@ -9,7 +9,6 @@ import forge.CounterType; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.gui.GuiChoose; public class CountersMoveEffect extends SpellAbilityEffect { @@ -17,16 +16,10 @@ public class CountersMoveEffect extends SpellAbilityEffect { @Override protected String getStackDescription(SpellAbility sa) { final StringBuilder sb = new StringBuilder(); - final Card host = sa.getSourceCard(); Card source = null; - List srcCards; - final Target tgt = sa.getTarget(); - if (!sa.hasParam("Source") && tgt != null) { - srcCards = tgt.getTargetCards(); - } else { - srcCards = AbilityUtils.getDefinedCards(host, sa.getParam("Source"), sa); - } + List srcCards = getDefinedCardsOrTargeted(sa, "Source"); + if (srcCards.size() > 0) { source = srcCards.get(0); } @@ -74,25 +67,14 @@ public class CountersMoveEffect extends SpellAbilityEffect { } Card source = null; - List srcCards; - final Target tgt = sa.getTarget(); - if (!sa.hasParam("Source") && tgt != null) { - srcCards = tgt.getTargetCards(); - } else { - srcCards = AbilityUtils.getDefinedCards(host, sa.getParam("Source"), sa); - } + List srcCards = getDefinedCardsOrTargeted(sa, "Source"); if (srcCards.size() > 0) { source = srcCards.get(0); } if (sa.getParam("CounterNum").equals("All")) { amount = source.getCounters(cType); } - List tgtCards; - if (!sa.hasParam("Defined") && tgt != null) { - tgtCards = tgt.getTargetCards(); - } else { - tgtCards = AbilityUtils.getDefinedCards(host, sa.getParam("Defined"), sa); - } + List tgtCards = getTargetCards(sa); for (final Card dest : tgtCards) { if ((null != source) && (null != dest)) { diff --git a/src/main/java/forge/card/ability/effects/CountersPutAllEffect.java b/src/main/java/forge/card/ability/effects/CountersPutAllEffect.java index 5c0fe2fe562..3e5feb63ffa 100644 --- a/src/main/java/forge/card/ability/effects/CountersPutAllEffect.java +++ b/src/main/java/forge/card/ability/effects/CountersPutAllEffect.java @@ -8,7 +8,7 @@ import forge.CounterType; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -48,9 +48,9 @@ public class CountersPutAllEffect extends SpellAbilityEffect { List cards = game.getCardsIn(zone); cards = CardLists.getValidCards(cards, valid, sa.getSourceCard().getController(), sa.getSourceCard()); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { - final Player pl = sa.getTargetPlayer(); + final Player pl = sa.getTargets().getFirstTargetedPlayer(); cards = CardLists.filterControlledBy(cards, pl); } diff --git a/src/main/java/forge/card/ability/effects/CountersPutEffect.java b/src/main/java/forge/card/ability/effects/CountersPutEffect.java index 2b9b98fc88e..dc91ff11254 100644 --- a/src/main/java/forge/card/ability/effects/CountersPutEffect.java +++ b/src/main/java/forge/card/ability/effects/CountersPutEffect.java @@ -9,7 +9,6 @@ import forge.CounterType; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.card.trigger.TriggerType; import forge.game.zone.Zone; import forge.game.zone.ZoneType; @@ -41,8 +40,7 @@ public class CountersPutEffect extends SpellAbilityEffect { } else { sb.append(" on "); } - final Target tgt = sa.getTarget(); - final List tgtCards = tgt != null ? tgt.getTargetCards() : AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa); + final List tgtCards = getTargetCards(sa); final Iterator it = tgtCards.iterator(); while (it.hasNext()) { @@ -92,18 +90,11 @@ public class CountersPutEffect extends SpellAbilityEffect { } } - List tgtCards; - - final Target tgt = sa.getTarget(); - if (tgt != null && (tgt.getTargetPlayers().size() == 0)) { - tgtCards = tgt.getTargetCards(); - } else { - tgtCards = AbilityUtils.getDefinedCards(card, sa.getParam("Defined"), sa); - } + List tgtCards = getTargetCards(sa); for (final Card tgtCard : tgtCards) { - counterAmount = (sa.getTarget() != null && sa.hasParam("DividedAsYouChoose")) ? sa.getTarget().getDividedValue(tgtCard) : counterAmount; - if ((tgt == null) || tgtCard.canBeTargetedBy(sa)) { + counterAmount = (sa.usesTargeting() && sa.hasParam("DividedAsYouChoose")) ? sa.getTargetRestrictions().getDividedValue(tgtCard) : counterAmount; + if (!sa.usesTargeting() || tgtCard.canBeTargetedBy(sa)) { if (max != -1) { counterAmount = max - tgtCard.getCounters(counterType); } diff --git a/src/main/java/forge/card/ability/effects/CountersRemoveAllEffect.java b/src/main/java/forge/card/ability/effects/CountersRemoveAllEffect.java index 2b823122cd9..8552efbb3bf 100644 --- a/src/main/java/forge/card/ability/effects/CountersRemoveAllEffect.java +++ b/src/main/java/forge/card/ability/effects/CountersRemoveAllEffect.java @@ -8,7 +8,6 @@ import forge.CounterType; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.game.Game; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -52,9 +51,8 @@ public class CountersRemoveAllEffect extends SpellAbilityEffect { List cards = game.getCardsIn(zone); cards = CardLists.getValidCards(cards, valid, sa.getSourceCard().getController(), sa.getSourceCard()); - final Target tgt = sa.getTarget(); - if (tgt != null) { - final Player pl = sa.getTargetPlayer(); + if (sa.usesTargeting()) { + final Player pl = sa.getTargets().getFirstTargetedPlayer(); cards = CardLists.filterControlledBy(cards, pl); } diff --git a/src/main/java/forge/card/ability/effects/CountersRemoveEffect.java b/src/main/java/forge/card/ability/effects/CountersRemoveEffect.java index a20ed4d0f74..5902917eb08 100644 --- a/src/main/java/forge/card/ability/effects/CountersRemoveEffect.java +++ b/src/main/java/forge/card/ability/effects/CountersRemoveEffect.java @@ -9,7 +9,7 @@ import forge.CounterType; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.zone.Zone; import forge.game.zone.ZoneType; @@ -73,7 +73,7 @@ public class CountersRemoveEffect extends SpellAbilityEffect { } } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); boolean rememberRemoved = false; if (sa.hasParam("RememberRemoved")) { diff --git a/src/main/java/forge/card/ability/effects/DamageAllEffect.java b/src/main/java/forge/card/ability/effects/DamageAllEffect.java index a694de55df2..96f47aaac25 100644 --- a/src/main/java/forge/card/ability/effects/DamageAllEffect.java +++ b/src/main/java/forge/card/ability/effects/DamageAllEffect.java @@ -8,7 +8,6 @@ import forge.CardLists; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.game.Game; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -51,11 +50,7 @@ public class DamageAllEffect extends SpellAbilityEffect { final String damage = sa.getParam("NumDmg"); final int dmg = AbilityUtils.calculateAmount(sa.getSourceCard(), damage, sa); - final Target tgt = sa.getTarget(); - Player targetPlayer = null; - if (tgt != null) { - targetPlayer = tgt.getTargetPlayers().get(0); - } + Player targetPlayer = sa.getTargets().getFirstTargetedPlayer(); String players = ""; List list = new ArrayList(); diff --git a/src/main/java/forge/card/ability/effects/DamageDealEffect.java b/src/main/java/forge/card/ability/effects/DamageDealEffect.java index 5a4efbb7d46..f337ff187dc 100644 --- a/src/main/java/forge/card/ability/effects/DamageDealEffect.java +++ b/src/main/java/forge/card/ability/effects/DamageDealEffect.java @@ -25,7 +25,7 @@ public class DamageDealEffect extends SpellAbilityEffect { final int dmg = AbilityUtils.calculateAmount(sa.getSourceCard(), damage, sa); - List tgts = getTargetObjects(sa); + List tgts = getTargets(sa); if (tgts.isEmpty()) return ""; @@ -73,12 +73,7 @@ public class DamageDealEffect extends SpellAbilityEffect { final boolean combatDmg = sa.hasParam("CombatDamage"); final boolean removeDamage = sa.hasParam("Remove"); - List tgts; - if (sa.getTarget() == null) { - tgts = AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam("Defined"), sa) ; - } else { - tgts = sa.getTarget().getTargets(); - } + List tgts = getTargets(sa); // Right now for Fireball, maybe later for other stuff if (sa.hasParam("DivideEvenly")) { @@ -88,7 +83,7 @@ public class DamageDealEffect extends SpellAbilityEffect { } } - final boolean targeted = (sa.getTarget() != null); + final boolean targeted = (sa.usesTargeting()); if (sa.hasParam("Radiance") && targeted) { Card origin = null; @@ -116,7 +111,7 @@ public class DamageDealEffect extends SpellAbilityEffect { final Card source = definedSources.get(0); for (final Object o : tgts) { - dmg = (sa.getTarget() != null && sa.hasParam("DividedAsYouChoose")) ? sa.getTarget().getDividedValue(o) : dmg; + dmg = (sa.usesTargeting() && sa.hasParam("DividedAsYouChoose")) ? sa.getTargetRestrictions().getDividedValue(o) : dmg; if (o instanceof Card) { final Card c = (Card) o; if (c.isInPlay() && (!targeted || c.canBeTargetedBy(sa))) { diff --git a/src/main/java/forge/card/ability/effects/DamageEachEffect.java b/src/main/java/forge/card/ability/effects/DamageEachEffect.java index bc4f6208dd8..4ef613a46da 100644 --- a/src/main/java/forge/card/ability/effects/DamageEachEffect.java +++ b/src/main/java/forge/card/ability/effects/DamageEachEffect.java @@ -65,14 +65,9 @@ public class DamageEachEffect extends SpellAbilityEffect { sources = CardLists.getValidCards(sources, sa.getParam("ValidCards"), card.getController(), card); } - final List tgts; - if (sa.getTarget() == null) { - tgts = AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam("DefinedPlayers"), sa); - } else { - tgts = sa.getTarget().getTargets(); - } + final List tgts = getTargets(sa, "DefinedPlayers"); - final boolean targeted = (sa.getTarget() != null); + final boolean targeted = (sa.usesTargeting()); for (final Object o : tgts) { for (final Card source : sources) { diff --git a/src/main/java/forge/card/ability/effects/DamagePreventEffect.java b/src/main/java/forge/card/ability/effects/DamagePreventEffect.java index 78f9f7f8869..4cc66d78dc3 100644 --- a/src/main/java/forge/card/ability/effects/DamagePreventEffect.java +++ b/src/main/java/forge/card/ability/effects/DamagePreventEffect.java @@ -17,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 = getTargets(sa); sb.append("Prevent the next "); sb.append(sa.getParam("Amount")); @@ -45,7 +45,7 @@ public class DamagePreventEffect extends SpellAbilityEffect { } } - if (sa.hasParam("Radiance") && (sa.getTarget() != null)) { + if (sa.hasParam("Radiance") && (sa.usesTargeting())) { sb.append(" and each other ").append(sa.getParam("ValidTgts")) .append(" that shares a color with "); if (tgts.size() > 1) { @@ -66,15 +66,10 @@ public class DamagePreventEffect extends SpellAbilityEffect { Card host = sa.getSourceCard(); int numDam = AbilityUtils.calculateAmount(host, sa.getParam("Amount"), sa); - final List tgts; + final List tgts = getTargets(sa); final ArrayList untargetedCards = new ArrayList(); - if (sa.getTarget() == null) { - tgts = AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam("Defined"), sa); - } else { - tgts = sa.getTarget().getTargets(); - } - - if (sa.hasParam("Radiance") && (sa.getTarget() != null)) { + + if (sa.hasParam("Radiance") && (sa.usesTargeting())) { Card origin = null; for (int i = 0; i < tgts.size(); i++) { if (tgts.get(i) instanceof Card) { @@ -90,10 +85,10 @@ public class DamagePreventEffect extends SpellAbilityEffect { } } - final boolean targeted = (sa.getTarget() != null); + final boolean targeted = (sa.usesTargeting()); for (final Object o : tgts) { - numDam = (sa.getTarget() != null && sa.hasParam("DividedAsYouChoose")) ? sa.getTarget().getDividedValue(o) : numDam; + numDam = (sa.usesTargeting() && sa.hasParam("DividedAsYouChoose")) ? sa.getTargetRestrictions().getDividedValue(o) : numDam; if (o instanceof Card) { final Card c = (Card) o; if (c.isInPlay() && (!targeted || c.canBeTargetedBy(sa))) { diff --git a/src/main/java/forge/card/ability/effects/DeclareCombatantsEffect.java b/src/main/java/forge/card/ability/effects/DeclareCombatantsEffect.java index 06f25473f6d..aed24f2539c 100644 --- a/src/main/java/forge/card/ability/effects/DeclareCombatantsEffect.java +++ b/src/main/java/forge/card/ability/effects/DeclareCombatantsEffect.java @@ -13,7 +13,7 @@ public class DeclareCombatantsEffect extends SpellAbilityEffect { @Override protected String getStackDescription(SpellAbility sa) { - List tgtPlayers = getDefinedPlayersBeforeTargetOnes(sa); + List tgtPlayers = getDefinedPlayersOrTargeted(sa); boolean attackers = sa.hasParam("DeclareAttackers"); final String attDesc = "which creatures attack"; @@ -31,7 +31,7 @@ public class DeclareCombatantsEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { - List tgtPlayers = getDefinedPlayersBeforeTargetOnes(sa); + List tgtPlayers = getDefinedPlayersOrTargeted(sa); final boolean attackers = sa.hasParam("DeclareAttackers"); final boolean blockers = sa.hasParam("DeclareBlockers"); diff --git a/src/main/java/forge/card/ability/effects/DestroyAllEffect.java b/src/main/java/forge/card/ability/effects/DestroyAllEffect.java index f30a7674619..191c89cb1e4 100644 --- a/src/main/java/forge/card/ability/effects/DestroyAllEffect.java +++ b/src/main/java/forge/card/ability/effects/DestroyAllEffect.java @@ -7,7 +7,6 @@ import forge.CardLists; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.game.Game; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -42,15 +41,7 @@ public class DestroyAllEffect extends SpellAbilityEffect { final Card card = sa.getSourceCard(); final Game game = sa.getActivatingPlayer().getGame(); - final Target tgt = sa.getTarget(); - Player targetPlayer = null; - if (tgt != null) { - for (final Object o : tgt.getTargets()) { - if (o instanceof Player) { - targetPlayer = (Player) o; - } - } - } + Player targetPlayer = sa.getTargets().getFirstTargetedPlayer(); String valid = ""; diff --git a/src/main/java/forge/card/ability/effects/DestroyEffect.java b/src/main/java/forge/card/ability/effects/DestroyEffect.java index f9028296365..d271f85bd04 100644 --- a/src/main/java/forge/card/ability/effects/DestroyEffect.java +++ b/src/main/java/forge/card/ability/effects/DestroyEffect.java @@ -8,7 +8,7 @@ import forge.Card; import forge.CardUtil; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; public class DestroyEffect extends SpellAbilityEffect { @@ -82,7 +82,7 @@ public class DestroyEffect extends SpellAbilityEffect { final List tgtCards = getTargetCards(sa); final ArrayList untargetedCards = new ArrayList(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (sa.hasParam("Radiance")) { for (final Card c : CardUtil.getRadiance(card, tgtCards.get(0), diff --git a/src/main/java/forge/card/ability/effects/DigEffect.java b/src/main/java/forge/card/ability/effects/DigEffect.java index 7ad34ece831..ca026f098bf 100644 --- a/src/main/java/forge/card/ability/effects/DigEffect.java +++ b/src/main/java/forge/card/ability/effects/DigEffect.java @@ -12,7 +12,7 @@ import forge.CardLists; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtilCard; import forge.game.player.Player; @@ -85,7 +85,7 @@ public class DigEffect extends SpellAbilityEffect { } } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final List tgtPlayers = getTargetPlayers(sa); if (sa.hasParam("Choser")) { diff --git a/src/main/java/forge/card/ability/effects/DigUntilEffect.java b/src/main/java/forge/card/ability/effects/DigUntilEffect.java index 8027b8cd0e0..6c1fe98121a 100644 --- a/src/main/java/forge/card/ability/effects/DigUntilEffect.java +++ b/src/main/java/forge/card/ability/effects/DigUntilEffect.java @@ -10,7 +10,7 @@ import forge.Card; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.player.Player; import forge.game.zone.PlayerZone; @@ -94,7 +94,7 @@ public class DigUntilEffect extends SpellAbilityEffect { final boolean remember = sa.hasParam("RememberFound"); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final ZoneType foundDest = ZoneType.smartValueOf(sa.getParam("FoundDestination")); final int foundLibPos = AbilityUtils.calculateAmount(host, sa.getParam("FoundLibraryPosition"), sa); diff --git a/src/main/java/forge/card/ability/effects/DiscardEffect.java b/src/main/java/forge/card/ability/effects/DiscardEffect.java index aa4ab76b91c..d5d745c5d72 100644 --- a/src/main/java/forge/card/ability/effects/DiscardEffect.java +++ b/src/main/java/forge/card/ability/effects/DiscardEffect.java @@ -13,7 +13,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.cardfactory.CardFactoryUtil; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.game.player.PlayerActionConfirmMode; import forge.game.zone.ZoneType; @@ -90,7 +90,7 @@ public class DiscardEffect extends SpellAbilityEffect { final String mode = sa.getParam("Mode"); //final boolean anyNumber = sa.hasParam("AnyNumber"); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final List discarded = new ArrayList(); diff --git a/src/main/java/forge/card/ability/effects/DrainManaEffect.java b/src/main/java/forge/card/ability/effects/DrainManaEffect.java index 27da97bae80..9ac6f94b6cc 100644 --- a/src/main/java/forge/card/ability/effects/DrainManaEffect.java +++ b/src/main/java/forge/card/ability/effects/DrainManaEffect.java @@ -6,7 +6,7 @@ import org.apache.commons.lang3.StringUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; public class DrainManaEffect extends SpellAbilityEffect { @@ -24,7 +24,7 @@ public class DrainManaEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); for (final Player p : getTargetPlayers(sa)) { if ((tgt == null) || p.canBeTargetedBy(sa)) { diff --git a/src/main/java/forge/card/ability/effects/DrawEffect.java b/src/main/java/forge/card/ability/effects/DrawEffect.java index fbdd6f4a180..de97548c27d 100644 --- a/src/main/java/forge/card/ability/effects/DrawEffect.java +++ b/src/main/java/forge/card/ability/effects/DrawEffect.java @@ -6,7 +6,7 @@ import forge.Card; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.util.Lang; @@ -15,7 +15,7 @@ public class DrawEffect extends SpellAbilityEffect { protected String getStackDescription(SpellAbility sa) { final StringBuilder sb = new StringBuilder(); - final List tgtPlayers = getDefinedPlayersBeforeTargetOnes(sa); + final List tgtPlayers = getDefinedPlayersOrTargeted(sa); if (!tgtPlayers.isEmpty()) { @@ -40,13 +40,13 @@ public class DrawEffect extends SpellAbilityEffect { final int numCards = sa.hasParam("NumCards") ? AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("NumCards"), sa) : 1; - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final boolean optional = sa.hasParam("OptionalDecider"); final boolean upto = sa.hasParam("Upto"); - for (final Player p : getDefinedPlayersBeforeTargetOnes(sa)) { + for (final Player p : getDefinedPlayersOrTargeted(sa)) { if ((tgt == null) || p.canBeTargetedBy(sa)) if (optional && !p.getController().confirmAction(sa, null, "Do you want to draw " + Lang.nounWithAmount(numCards, " card") + "?")) continue; diff --git a/src/main/java/forge/card/ability/effects/FightEffect.java b/src/main/java/forge/card/ability/effects/FightEffect.java index 3e70a4278ef..28a77babffd 100644 --- a/src/main/java/forge/card/ability/effects/FightEffect.java +++ b/src/main/java/forge/card/ability/effects/FightEffect.java @@ -3,11 +3,13 @@ package forge.card.ability.effects; import java.util.ArrayList; import java.util.List; +import com.google.common.collect.Lists; + import forge.Card; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; public class FightEffect extends SpellAbilityEffect { @@ -48,10 +50,10 @@ public class FightEffect extends SpellAbilityEffect { Card fighter1 = null; Card fighter2 = null; - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); List tgts = null; if (tgt != null) { - tgts = tgt.getTargetCards(); + tgts = Lists.newArrayList(sa.getTargets().getTargetCards()); if (tgts.size() > 0) { fighter1 = tgts.get(0); } diff --git a/src/main/java/forge/card/ability/effects/LifeGainEffect.java b/src/main/java/forge/card/ability/effects/LifeGainEffect.java index 79a830f2a8c..9650d817493 100644 --- a/src/main/java/forge/card/ability/effects/LifeGainEffect.java +++ b/src/main/java/forge/card/ability/effects/LifeGainEffect.java @@ -1,13 +1,12 @@ package forge.card.ability.effects; -import java.util.ArrayList; import java.util.List; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; public class LifeGainEffect extends SpellAbilityEffect { @@ -36,14 +35,9 @@ public class LifeGainEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { final int lifeAmount = AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("LifeAmount"), sa); - final Target tgt = sa.getTarget(); - List tgtPlayers = new ArrayList(); - - if (sa.hasParam("Defined")) { - tgtPlayers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa); - } else if (tgt != null) { - tgtPlayers = tgt.getTargetPlayers(); - } else { + final TargetRestrictions tgt = sa.getTargetRestrictions(); + List tgtPlayers = getTargetPlayers(sa); + if( tgtPlayers.isEmpty() ) { tgtPlayers.add(sa.getActivatingPlayer()); } diff --git a/src/main/java/forge/card/ability/effects/LifeLoseEffect.java b/src/main/java/forge/card/ability/effects/LifeLoseEffect.java index c7072230e7b..64f6efa62bf 100644 --- a/src/main/java/forge/card/ability/effects/LifeLoseEffect.java +++ b/src/main/java/forge/card/ability/effects/LifeLoseEffect.java @@ -4,7 +4,7 @@ package forge.card.ability.effects; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; public class LifeLoseEffect extends SpellAbilityEffect { @@ -41,7 +41,7 @@ public class LifeLoseEffect extends SpellAbilityEffect { final int lifeAmount = AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("LifeAmount"), sa); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); for (final Player p : getTargetPlayers(sa)) { if ((tgt == null) || p.canBeTargetedBy(sa)) { lifeLost += p.loseLife(lifeAmount); diff --git a/src/main/java/forge/card/ability/effects/LifeSetEffect.java b/src/main/java/forge/card/ability/effects/LifeSetEffect.java index 7405eca6bbb..a00fd8d1261 100644 --- a/src/main/java/forge/card/ability/effects/LifeSetEffect.java +++ b/src/main/java/forge/card/ability/effects/LifeSetEffect.java @@ -7,7 +7,7 @@ import java.util.List; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.gui.GuiChoose; @@ -20,7 +20,7 @@ public class LifeSetEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { final boolean redistribute = sa.hasParam("Redistribute"); final int lifeAmount = redistribute ? 20 : AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("LifeAmount"), sa); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final List lifetotals = new ArrayList(); if (redistribute) { diff --git a/src/main/java/forge/card/ability/effects/ManaEffect.java b/src/main/java/forge/card/ability/effects/ManaEffect.java index 35a58ba918f..e8dcc8c7e0b 100644 --- a/src/main/java/forge/card/ability/effects/ManaEffect.java +++ b/src/main/java/forge/card/ability/effects/ManaEffect.java @@ -11,7 +11,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.AbilityManaPart; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.GameActionUtil; import forge.game.Game; import forge.game.ai.ComputerUtilCard; @@ -33,7 +33,7 @@ public class ManaEffect extends SpellAbilityEffect { sa.setUndoable(sa.isAbility() && sa.isUndoable()); final List tgtPlayers = getTargetPlayers(sa); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final boolean optional = sa.hasParam("Optional"); final Game game = sa.getActivatingPlayer().getGame(); diff --git a/src/main/java/forge/card/ability/effects/MillEffect.java b/src/main/java/forge/card/ability/effects/MillEffect.java index 9381a458d0c..2713cb8631d 100644 --- a/src/main/java/forge/card/ability/effects/MillEffect.java +++ b/src/main/java/forge/card/ability/effects/MillEffect.java @@ -7,7 +7,7 @@ import forge.CardCharacteristicName; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -23,7 +23,7 @@ public class MillEffect extends SpellAbilityEffect { source.clearRemembered(); } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination")); if (destination == null) { diff --git a/src/main/java/forge/card/ability/effects/MustAttackEffect.java b/src/main/java/forge/card/ability/effects/MustAttackEffect.java index 9a82e8e4755..5688be81a39 100644 --- a/src/main/java/forge/card/ability/effects/MustAttackEffect.java +++ b/src/main/java/forge/card/ability/effects/MustAttackEffect.java @@ -6,7 +6,7 @@ import forge.Card; import forge.GameEntity; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; public class MustAttackEffect extends SpellAbilityEffect { @@ -42,7 +42,7 @@ public class MustAttackEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { final List tgtPlayers = getTargetPlayers(sa); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); for (final Player p : tgtPlayers) { if ((tgt == null) || p.canBeTargetedBy(sa)) { diff --git a/src/main/java/forge/card/ability/effects/MustBlockEffect.java b/src/main/java/forge/card/ability/effects/MustBlockEffect.java index cd528ff5bd9..500eb9d2db3 100644 --- a/src/main/java/forge/card/ability/effects/MustBlockEffect.java +++ b/src/main/java/forge/card/ability/effects/MustBlockEffect.java @@ -7,7 +7,7 @@ import forge.Card; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; public class MustBlockEffect extends SpellAbilityEffect { @@ -15,14 +15,8 @@ public class MustBlockEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { final Card host = sa.getSourceCard(); - List tgtCards; - - final Target tgt = sa.getTarget(); - if (tgt != null) { - tgtCards = tgt.getTargetCards(); - } else { - tgtCards = AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa); - } + List tgtCards = getTargetCards(sa); + final TargetRestrictions tgt = sa.getTargetRestrictions(); List cards; if (sa.hasParam("DefinedAttacker")) { diff --git a/src/main/java/forge/card/ability/effects/PlayEffect.java b/src/main/java/forge/card/ability/effects/PlayEffect.java index cef26c29558..5e21266e2ee 100644 --- a/src/main/java/forge/card/ability/effects/PlayEffect.java +++ b/src/main/java/forge/card/ability/effects/PlayEffect.java @@ -230,8 +230,8 @@ public class PlayEffect extends SpellAbilityEffect { boolean noManaCost = sa.hasParam("WithoutManaCost"); tgtSA = noManaCost ? tgtSA.copyWithNoManaCost() : tgtSA; - if (tgtSA.getTarget() != null && !optional) { - tgtSA.getTarget().setMandatory(true); + if (tgtSA.usesTargeting() && !optional) { + tgtSA.getTargetRestrictions().setMandatory(true); } if (controller.isHuman()) { diff --git a/src/main/java/forge/card/ability/effects/PoisonEffect.java b/src/main/java/forge/card/ability/effects/PoisonEffect.java index e308d15cb17..e5a0e60556d 100644 --- a/src/main/java/forge/card/ability/effects/PoisonEffect.java +++ b/src/main/java/forge/card/ability/effects/PoisonEffect.java @@ -7,7 +7,7 @@ import org.apache.commons.lang3.StringUtils; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; /** @@ -24,7 +24,7 @@ import forge.game.player.Player; public void resolve(SpellAbility sa) { final int amount = AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("Num"), sa); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); for (final Player p : getTargetPlayers(sa)) { if ((tgt == null) || p.canBeTargetedBy(sa)) { p.addPoisonCounters(amount, sa.getSourceCard()); diff --git a/src/main/java/forge/card/ability/effects/ProtectAllEffect.java b/src/main/java/forge/card/ability/effects/ProtectAllEffect.java index 6bf3c817aa6..9462e363f41 100644 --- a/src/main/java/forge/card/ability/effects/ProtectAllEffect.java +++ b/src/main/java/forge/card/ability/effects/ProtectAllEffect.java @@ -64,7 +64,7 @@ public class ProtectAllEffect extends SpellAbilityEffect { gains.add(color.toLowerCase()); } } else if (sa.getParam("Gains").equals("TargetedCardColor")) { - for (final Card c : sa.getSATargetingCard().getTarget().getTargetCards()) { + for (final Card c : sa.getSATargetingCard().getTargets().getTargetCards()) { ColorSet cs = CardUtil.getColors(c); for(byte col : MagicColor.WUBRG) { if (cs.hasAnyColor(col)) diff --git a/src/main/java/forge/card/ability/effects/ProtectEffect.java b/src/main/java/forge/card/ability/effects/ProtectEffect.java index 7ca54a65a3b..f1415d00cb8 100644 --- a/src/main/java/forge/card/ability/effects/ProtectEffect.java +++ b/src/main/java/forge/card/ability/effects/ProtectEffect.java @@ -11,7 +11,7 @@ import forge.Command; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.ai.ComputerUtilCard; import forge.game.player.Player; @@ -52,7 +52,7 @@ public class ProtectEffect extends SpellAbilityEffect { } } - if (sa.hasParam("Radiance") && (sa.getTarget() != null)) { + if (sa.hasParam("Radiance") && (sa.usesTargeting())) { sb.append(" and each other ").append(sa.getParam("ValidTgts")) .append(" that shares a color with "); if (tgtCards.size() > 1) { @@ -141,7 +141,7 @@ public class ProtectEffect extends SpellAbilityEffect { final List tgtCards = getTargetCards(sa); final ArrayList untargetedCards = new ArrayList(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (sa.hasParam("Radiance") && (tgt != null)) { for (final Card c : CardUtil.getRadiance(host, tgtCards.get(0), diff --git a/src/main/java/forge/card/ability/effects/PumpAllEffect.java b/src/main/java/forge/card/ability/effects/PumpAllEffect.java index b9c0c8dbed8..752c94e69c2 100644 --- a/src/main/java/forge/card/ability/effects/PumpAllEffect.java +++ b/src/main/java/forge/card/ability/effects/PumpAllEffect.java @@ -113,7 +113,7 @@ public class PumpAllEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { List list; - final List tgtPlayers = getTargetPlayersEmptyAsDefault(sa); + final List tgtPlayers = getTargetPlayers(sa); final ArrayList affectedZones = new ArrayList(); final Game game = sa.getActivatingPlayer().getGame(); diff --git a/src/main/java/forge/card/ability/effects/PumpEffect.java b/src/main/java/forge/card/ability/effects/PumpEffect.java index c1bd3552103..c7db6a63a82 100644 --- a/src/main/java/forge/card/ability/effects/PumpEffect.java +++ b/src/main/java/forge/card/ability/effects/PumpEffect.java @@ -12,7 +12,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.cardfactory.CardFactoryUtil; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -122,20 +122,9 @@ public class PumpEffect extends SpellAbilityEffect { protected String getStackDescription(SpellAbility sa) { final StringBuilder sb = new StringBuilder(); - ArrayList tgts = new ArrayList(); - - final Target tgt = sa.getTarget(); - if (tgt != null) { - tgts.addAll(tgt.getTargetCards()); - tgts.addAll(tgt.getTargetPlayers()); - } else { - if (sa.hasParam("Defined")) { - tgts.addAll(AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa)); - } - if (tgts.isEmpty()) { - tgts.addAll(AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa)); - } - } + List tgts = new ArrayList(); + tgts.addAll(getTargetCards(sa)); + tgts.addAll(getTargetPlayers(sa)); if (tgts.size() > 0) { @@ -188,7 +177,7 @@ public class PumpEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { List tgtCards = new ArrayList(); final ArrayList untargetedCards = new ArrayList(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Game game = sa.getActivatingPlayer().getGame(); List tgtPlayers = new ArrayList(); String pumpRemembered = null; @@ -199,17 +188,10 @@ public class PumpEffect extends SpellAbilityEffect { final int a = AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("NumAtt"), sa); final int d = AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("NumDef"), sa); - if (tgt != null) { - tgtCards = tgt.getTargetCards(); - tgtPlayers = tgt.getTargetPlayers(); - } else { - if (sa.hasParam("Defined")) { - tgtPlayers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa); - } - if (tgtPlayers.isEmpty()) { - tgtCards = AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa); - } - } + List tgts = new ArrayList(); + tgts.addAll(getTargetCards(sa)); + tgts.addAll(getTargetPlayers(sa)); + if (sa.hasParam("DefinedChosenKW")) { if (sa.getParam("DefinedChosenKW").equals("Type")) { final String t = sa.getSourceCard().getChosenType(); diff --git a/src/main/java/forge/card/ability/effects/RearrangeTopOfLibraryEffect.java b/src/main/java/forge/card/ability/effects/RearrangeTopOfLibraryEffect.java index 0897064959f..33d6f13d58f 100644 --- a/src/main/java/forge/card/ability/effects/RearrangeTopOfLibraryEffect.java +++ b/src/main/java/forge/card/ability/effects/RearrangeTopOfLibraryEffect.java @@ -7,7 +7,7 @@ import forge.Card; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.game.zone.PlayerZone; import forge.game.zone.ZoneType; @@ -74,7 +74,7 @@ public class RearrangeTopOfLibraryEffect extends SpellAbilityEffect { boolean shuffle = false; if (sa.getActivatingPlayer().isHuman()) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); numCards = AbilityUtils.calculateAmount(host, sa.getParam("NumCards"), sa); diff --git a/src/main/java/forge/card/ability/effects/RegenerateEffect.java b/src/main/java/forge/card/ability/effects/RegenerateEffect.java index b071bb7cb45..b3c9154bfb9 100644 --- a/src/main/java/forge/card/ability/effects/RegenerateEffect.java +++ b/src/main/java/forge/card/ability/effects/RegenerateEffect.java @@ -7,7 +7,7 @@ import forge.Card; import forge.Command; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; public class RegenerateEffect extends SpellAbilityEffect { @@ -44,7 +44,7 @@ public class RegenerateEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final Game game = sa.getActivatingPlayer().getGame(); for (final Card tgtC : getTargetCards(sa)) { diff --git a/src/main/java/forge/card/ability/effects/RemoveFromCombatEffect.java b/src/main/java/forge/card/ability/effects/RemoveFromCombatEffect.java index 982c7e25309..4e7220024e3 100644 --- a/src/main/java/forge/card/ability/effects/RemoveFromCombatEffect.java +++ b/src/main/java/forge/card/ability/effects/RemoveFromCombatEffect.java @@ -7,7 +7,7 @@ import org.apache.commons.lang3.StringUtils; import forge.Card; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.player.Player; @@ -32,7 +32,7 @@ public class RemoveFromCombatEffect extends SpellAbilityEffect { final Game game = activator.getGame(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); for (final Card c : getTargetCards(sa)) { if ((tgt == null) || c.canBeTargetedBy(sa)) { game.getCombat().removeFromCombat(c); diff --git a/src/main/java/forge/card/ability/effects/ReorderZoneEffect.java b/src/main/java/forge/card/ability/effects/ReorderZoneEffect.java index 86c500d3be5..ad5f771defb 100644 --- a/src/main/java/forge/card/ability/effects/ReorderZoneEffect.java +++ b/src/main/java/forge/card/ability/effects/ReorderZoneEffect.java @@ -9,7 +9,7 @@ import com.google.common.collect.Lists; import forge.Card; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.game.zone.ZoneType; import forge.util.Lang; @@ -42,7 +42,7 @@ public class ReorderZoneEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { final ZoneType zone = ZoneType.smartValueOf(sa.getParam("Zone")); boolean shuffle = sa.hasParam("Random"); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); for (final Player p : getTargetPlayers(sa)) { diff --git a/src/main/java/forge/card/ability/effects/RevealEffect.java b/src/main/java/forge/card/ability/effects/RevealEffect.java index 2f0fbc0fde0..f2ce0b5e700 100644 --- a/src/main/java/forge/card/ability/effects/RevealEffect.java +++ b/src/main/java/forge/card/ability/effects/RevealEffect.java @@ -8,7 +8,7 @@ import forge.CardLists; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -23,7 +23,7 @@ public class RevealEffect extends SpellAbilityEffect { int cnt = sa.hasParam("NumCards") ? AbilityUtils.calculateAmount(host, sa.getParam("NumCards"), sa) : 1; - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); for (final Player p : getTargetPlayers(sa)) { final Game game = p.getGame(); diff --git a/src/main/java/forge/card/ability/effects/RevealHandEffect.java b/src/main/java/forge/card/ability/effects/RevealHandEffect.java index 895d4345710..95031980122 100644 --- a/src/main/java/forge/card/ability/effects/RevealHandEffect.java +++ b/src/main/java/forge/card/ability/effects/RevealHandEffect.java @@ -5,7 +5,7 @@ import java.util.List; import forge.Card; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -35,7 +35,7 @@ public class RevealHandEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { final Card host = sa.getSourceCard(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); for (final Player p : getTargetPlayers(sa)) { if ((tgt == null) || p.canBeTargetedBy(sa)) { diff --git a/src/main/java/forge/card/ability/effects/ScryEffect.java b/src/main/java/forge/card/ability/effects/ScryEffect.java index 34e7af9cd27..2b7ef554f32 100644 --- a/src/main/java/forge/card/ability/effects/ScryEffect.java +++ b/src/main/java/forge/card/ability/effects/ScryEffect.java @@ -10,7 +10,7 @@ import forge.Card; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.game.zone.PlayerZone; import forge.game.zone.ZoneType; @@ -44,7 +44,7 @@ public class ScryEffect extends SpellAbilityEffect { num = AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("ScryNum"), sa); } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final List tgtPlayers = getTargetPlayers(sa); for (final Player p : tgtPlayers) { diff --git a/src/main/java/forge/card/ability/effects/SetStateEffect.java b/src/main/java/forge/card/ability/effects/SetStateEffect.java index 9345dd6dda1..31ecc174062 100644 --- a/src/main/java/forge/card/ability/effects/SetStateEffect.java +++ b/src/main/java/forge/card/ability/effects/SetStateEffect.java @@ -48,7 +48,7 @@ public class SetStateEffect extends SpellAbilityEffect { final boolean remChanged = sa.hasParam("RememberChanged"); for (final Card tgt : tgtCards) { - if (sa.getTarget() != null && !tgt.canBeTargetedBy(sa)) { + if (sa.usesTargeting() && !tgt.canBeTargetedBy(sa)) { continue; } diff --git a/src/main/java/forge/card/ability/effects/ShuffleEffect.java b/src/main/java/forge/card/ability/effects/ShuffleEffect.java index 8c03948851a..08672350706 100644 --- a/src/main/java/forge/card/ability/effects/ShuffleEffect.java +++ b/src/main/java/forge/card/ability/effects/ShuffleEffect.java @@ -5,7 +5,7 @@ import java.util.List; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; public class ShuffleEffect extends SpellAbilityEffect { @@ -16,7 +16,7 @@ public class ShuffleEffect extends SpellAbilityEffect { final List tgtPlayers = getTargetPlayers(sa); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); for (final Player p : tgtPlayers) { if ((tgt == null) || p.canBeTargetedBy(sa)) { diff --git a/src/main/java/forge/card/ability/effects/TapAllEffect.java b/src/main/java/forge/card/ability/effects/TapAllEffect.java index e715cdfceea..1fd79ecce56 100644 --- a/src/main/java/forge/card/ability/effects/TapAllEffect.java +++ b/src/main/java/forge/card/ability/effects/TapAllEffect.java @@ -38,7 +38,7 @@ public class TapAllEffect extends SpellAbilityEffect { List cards = null; - final List tgtPlayers = getTargetPlayersEmptyAsDefault(sa); + final List tgtPlayers = getTargetPlayers(sa); if ((tgtPlayers == null) || tgtPlayers.isEmpty()) { cards = game.getCardsIn(ZoneType.Battlefield); diff --git a/src/main/java/forge/card/ability/effects/TapEffect.java b/src/main/java/forge/card/ability/effects/TapEffect.java index 132b1e60615..00a6a0b3efa 100644 --- a/src/main/java/forge/card/ability/effects/TapEffect.java +++ b/src/main/java/forge/card/ability/effects/TapEffect.java @@ -7,7 +7,7 @@ import org.apache.commons.lang3.StringUtils; import forge.Card; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; public class TapEffect extends SpellAbilityEffect { @@ -22,7 +22,7 @@ public class TapEffect extends SpellAbilityEffect { card.clearRemembered(); } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final List tgtCards = getTargetCards(sa); for (final Card tgtC : tgtCards) { diff --git a/src/main/java/forge/card/ability/effects/TapOrUntapAllEffect.java b/src/main/java/forge/card/ability/effects/TapOrUntapAllEffect.java index de3455b61c4..fcd1153339b 100644 --- a/src/main/java/forge/card/ability/effects/TapOrUntapAllEffect.java +++ b/src/main/java/forge/card/ability/effects/TapOrUntapAllEffect.java @@ -48,7 +48,7 @@ public class TapOrUntapAllEffect extends SpellAbilityEffect { final Game game = activator.getGame(); - List targetedPlayers = getTargetPlayersEmptyAsDefault(sa); + List targetedPlayers = getTargetPlayers(sa); if (sa.hasParam("ValidCards")) { validCards = game.getCardsIn(ZoneType.Battlefield); diff --git a/src/main/java/forge/card/ability/effects/TapOrUntapEffect.java b/src/main/java/forge/card/ability/effects/TapOrUntapEffect.java index 2761649317f..1ccdd9aaf56 100644 --- a/src/main/java/forge/card/ability/effects/TapOrUntapEffect.java +++ b/src/main/java/forge/card/ability/effects/TapOrUntapEffect.java @@ -7,7 +7,7 @@ import org.apache.commons.lang3.StringUtils; import forge.Card; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.gui.GuiChoose; public class TapOrUntapEffect extends SpellAbilityEffect { @@ -33,7 +33,7 @@ public class TapOrUntapEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { final List tgtCards = getTargetCards(sa); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); for (final Card tgtC : tgtCards) { if (tgtC.isInPlay() && ((tgt == null) || tgtC.canBeTargetedBy(sa))) { diff --git a/src/main/java/forge/card/ability/effects/TwoPilesEffect.java b/src/main/java/forge/card/ability/effects/TwoPilesEffect.java index a022b1dae4d..3af4da33655 100644 --- a/src/main/java/forge/card/ability/effects/TwoPilesEffect.java +++ b/src/main/java/forge/card/ability/effects/TwoPilesEffect.java @@ -10,7 +10,7 @@ import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.AbilitySub; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtilCard; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -64,7 +64,7 @@ public class TwoPilesEffect extends SpellAbilityEffect { valid = sa.getParam("ValidCards"); } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); final List tgtPlayers = getTargetPlayers(sa); Player separator = card.getController(); diff --git a/src/main/java/forge/card/ability/effects/UnattachAllEffect.java b/src/main/java/forge/card/ability/effects/UnattachAllEffect.java index eaae52e172f..61656e04434 100644 --- a/src/main/java/forge/card/ability/effects/UnattachAllEffect.java +++ b/src/main/java/forge/card/ability/effects/UnattachAllEffect.java @@ -143,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 = getTargets(sa); sb.append(StringUtils.join(targets, " ")); return sb.toString(); } @@ -155,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 = getTargets(sa); // If Cast Targets will be checked on the Stack for (final Object o : targets) { diff --git a/src/main/java/forge/card/ability/effects/UntapAllEffect.java b/src/main/java/forge/card/ability/effects/UntapAllEffect.java index b0f2017cf93..c850db3a13b 100644 --- a/src/main/java/forge/card/ability/effects/UntapAllEffect.java +++ b/src/main/java/forge/card/ability/effects/UntapAllEffect.java @@ -32,7 +32,7 @@ public class UntapAllEffect extends SpellAbilityEffect { String valid = ""; List list = null; - List tgtPlayers = getTargetPlayersEmptyAsDefault(sa); + List tgtPlayers = getTargetPlayers(sa); if (sa.hasParam("ValidCards")) { valid = sa.getParam("ValidCards"); diff --git a/src/main/java/forge/card/ability/effects/UntapEffect.java b/src/main/java/forge/card/ability/effects/UntapEffect.java index 934ef7f2a5c..d11518ba63a 100644 --- a/src/main/java/forge/card/ability/effects/UntapEffect.java +++ b/src/main/java/forge/card/ability/effects/UntapEffect.java @@ -11,7 +11,7 @@ import forge.CardPredicates.Presets; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.ai.ComputerUtilCard; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -43,7 +43,7 @@ public class UntapEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (sa.hasParam("UntapUpTo")) { untapChooseUpTo(sa); diff --git a/src/main/java/forge/card/cardfactory/CardFactory.java b/src/main/java/forge/card/cardfactory/CardFactory.java index fe25a3a583c..7ab7fd6fb3e 100644 --- a/src/main/java/forge/card/cardfactory/CardFactory.java +++ b/src/main/java/forge/card/cardfactory/CardFactory.java @@ -28,6 +28,7 @@ import forge.CardColor; import forge.CardUtil; import forge.Command; import forge.CounterType; +import forge.ITargetable; import forge.ImageCache; import forge.card.CardCharacteristics; import forge.card.CardDb; @@ -43,7 +44,7 @@ import forge.card.spellability.AbilitySub; import forge.card.spellability.OptionalCost; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellPermanent; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.card.trigger.Trigger; import forge.card.trigger.TriggerHandler; import forge.game.player.Player; @@ -138,7 +139,7 @@ public class CardFactory { * a boolean. */ public final static void copySpellontoStack(final Card source, final Card original, final SpellAbility sa, - final boolean bCopyDetails, final Object definedTarget) { + final boolean bCopyDetails, final ITargetable definedTarget) { //Player originalController = original.getController(); Player controller = sa.getActivatingPlayer(); final Card c = copyCard(original); @@ -188,14 +189,9 @@ public class CardFactory { copySA.setCopied(true); //remove all costs copySA.setPayCosts(new Cost("", sa.isAbility())); - if (definedTarget != null) { - Target target = new Target(); - target.setDefinedTarget(definedTarget); - copySA.setTarget(target); - } - else if (sa.getTarget() != null) { - Target target = new Target(sa.getTarget()); - copySA.setTarget(target); + if (sa.getTargetRestrictions() != null) { + TargetRestrictions target = new TargetRestrictions(sa.getTargetRestrictions()); + copySA.setTargetRestrictions(target); } copySA.setActivatingPlayer(controller); diff --git a/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java b/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java index 809b40b55b5..a1af176638a 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java @@ -38,7 +38,7 @@ import forge.card.spellability.AbilityActivated; import forge.card.spellability.AbilityStatic; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellPermanent; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.card.trigger.Trigger; import forge.card.trigger.TriggerHandler; import forge.game.Game; @@ -132,16 +132,16 @@ public class CardFactoryCreatures { private static void getCard_MasterOfTheWildHunt(final Card card) { final Cost abCost = new Cost("T", true); - final Target abTgt = new Target("Target a creature to Hunt", new String[]{"Creature"}, "1", "1"); + final TargetRestrictions abTgt = new TargetRestrictions("Target a creature to Hunt", new String[]{"Creature"}, "1", "1"); class MasterOfTheWildHuntAbility extends AbilityActivated { - public MasterOfTheWildHuntAbility(final Card ca, final Cost co, final Target t) { + public MasterOfTheWildHuntAbility(final Card ca, final Cost co, final TargetRestrictions t) { super(ca, co, t); } @Override public AbilityActivated getCopy() { return new MasterOfTheWildHuntAbility(getSourceCard(), - getPayCosts(), new Target(getTarget())); + getPayCosts(), new TargetRestrictions(getTargetRestrictions())); } private static final long serialVersionUID = 35050145102566898L; @@ -170,7 +170,7 @@ public class CardFactoryCreatures { return false; } - this.getTarget().resetTargets(); + this.resetTargets(); this.setTargetCard(ComputerUtilCard.getBestCreatureAI(targetables)); return true; diff --git a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java index e4127313db1..d39e25f61e1 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java @@ -57,7 +57,7 @@ import forge.card.spellability.Spell; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbilityRestriction; import forge.card.spellability.SpellPermanent; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.card.trigger.Trigger; import forge.card.trigger.TriggerHandler; import forge.card.trigger.TriggerType; @@ -100,14 +100,14 @@ public class CardFactoryUtil { final Cost cost = new Cost(manaCost, true); class AbilityUnearth extends AbilityActivated { - public AbilityUnearth(final Card ca, final Cost co, final Target t) { + public AbilityUnearth(final Card ca, final Cost co, final TargetRestrictions t) { super(ca, co, t); } @Override public AbilityActivated getCopy() { AbilityActivated res = new AbilityUnearth(getSourceCard(), - getPayCosts(), getTarget() == null ? null : new Target(getTarget())); + getPayCosts(), getTargetRestrictions() == null ? null : new TargetRestrictions(getTargetRestrictions())); CardFactory.copySpellAbility(this, res); final SpellAbilityRestriction restrict = new SpellAbilityRestriction(); restrict.setZone(ZoneType.Graveyard); @@ -311,14 +311,14 @@ public class CardFactoryUtil { transmuteCost += " Discard<1/CARDNAME>"; final Cost abCost = new Cost(transmuteCost, true); class AbilityTransmute extends AbilityActivated { - public AbilityTransmute(final Card ca, final Cost co, final Target t) { + public AbilityTransmute(final Card ca, final Cost co, final TargetRestrictions t) { super(ca, co, t); } @Override public AbilityActivated getCopy() { AbilityActivated res = new AbilityTransmute(getSourceCard(), - getPayCosts(), getTarget() == null ? null : new Target(getTarget())); + getPayCosts(), getTargetRestrictions() == null ? null : new TargetRestrictions(getTargetRestrictions())); CardFactory.copySpellAbility(this, res); res.getRestrictions().setZone(ZoneType.Hand); return res; @@ -695,7 +695,7 @@ public class CardFactoryUtil { } final Card source = ability.getSourceCard(); - final Target tgt = ability.getTarget(); + final TargetRestrictions tgt = ability.getTargetRestrictions(); if (tgt != null) { // Reconfirm the Validity of a TgtValid, or if the Creature is still // a Creature @@ -923,7 +923,7 @@ public class CardFactoryUtil { * a {@link forge.Card} object. * @return a int. */ - public static int objectXCount(final ArrayList objects, final String s, final Card source) { + public static int objectXCount(final List objects, final String s, final Card source) { if (objects.isEmpty()) { return 0; } @@ -1303,7 +1303,7 @@ public class CardFactoryUtil { for (final SpellAbility sa : c.getCharacteristics().getSpellAbility()) { final SpellAbility saTargeting = sa.getSATargetingPlayer(); if (saTargeting != null) { - for (final Player tgtP : saTargeting.getTarget().getTargetPlayers()) { + for (final Player tgtP : saTargeting.getTargets().getTargetPlayers()) { return doXMath(tgtP.getLife(), m, c); } } @@ -1712,7 +1712,7 @@ public class CardFactoryUtil { for (final SpellAbility sa : c.getCharacteristics().getSpellAbility()) { final SpellAbility saTargeting = sa.getSATargetingPlayer(); if (saTargeting != null) { - for (final Player tgtP : saTargeting.getTarget().getTargetPlayers()) { + for (final Player tgtP : saTargeting.getTargets().getTargetPlayers()) { someCards.addAll(tgtP.getCardsIn(ZoneType.Hand)); } } diff --git a/src/main/java/forge/card/spellability/AbilityActivated.java b/src/main/java/forge/card/spellability/AbilityActivated.java index 221c036861b..8a762b9fbc9 100644 --- a/src/main/java/forge/card/spellability/AbilityActivated.java +++ b/src/main/java/forge/card/spellability/AbilityActivated.java @@ -64,12 +64,12 @@ public abstract class AbilityActivated extends SpellAbility implements java.io.S * @param abCost * a {@link forge.card.cost.Cost} object. * @param tgt - * a {@link forge.card.spellability.Target} object. + * a {@link forge.card.spellability.TargetRestrictions} object. */ - public AbilityActivated(final Card sourceCard, final Cost abCost, final Target tgt) { + public AbilityActivated(final Card sourceCard, final Cost abCost, final TargetRestrictions tgt) { super(sourceCard, abCost); if ((tgt != null) && tgt.doesTarget()) { - this.setTarget(tgt); + this.setTargetRestrictions(tgt); } } diff --git a/src/main/java/forge/card/spellability/AbilityStatic.java b/src/main/java/forge/card/spellability/AbilityStatic.java index a8b87f27ad9..3bfbc0101cb 100644 --- a/src/main/java/forge/card/spellability/AbilityStatic.java +++ b/src/main/java/forge/card/spellability/AbilityStatic.java @@ -44,10 +44,10 @@ public abstract class AbilityStatic extends Ability { super(sourceCard, manaCost); } - public AbilityStatic(final Card sourceCard, final Cost abCost, final Target tgt) { + public AbilityStatic(final Card sourceCard, final Cost abCost, final TargetRestrictions tgt) { super(sourceCard, abCost); if ((tgt != null) && tgt.doesTarget()) { - this.setTarget(tgt); + this.setTargetRestrictions(tgt); } } } diff --git a/src/main/java/forge/card/spellability/AbilitySub.java b/src/main/java/forge/card/spellability/AbilitySub.java index a33cd2e5b11..f9364631c98 100644 --- a/src/main/java/forge/card/spellability/AbilitySub.java +++ b/src/main/java/forge/card/spellability/AbilitySub.java @@ -90,9 +90,9 @@ public final class AbilitySub extends SpellAbility implements java.io.Serializab return ai; } - public AbilitySub(ApiType api0, final Card ca, final Target tgt, Map params0) { + public AbilitySub(ApiType api0, final Card ca, final TargetRestrictions tgt, Map params0) { super(ca, Cost.Zero); - this.setTarget(tgt); + this.setTargetRestrictions(tgt); api = api0; params = params0; @@ -109,7 +109,7 @@ public final class AbilitySub extends SpellAbility implements java.io.Serializab } public AbilitySub getCopy() { - Target t = getTarget() == null ? null : new Target(getTarget()); + TargetRestrictions t = getTargetRestrictions() == null ? null : new TargetRestrictions(getTargetRestrictions()); AbilitySub res = new AbilitySub(api, getSourceCard(), t, params); CardFactory.copySpellAbility(this, res); return res; diff --git a/src/main/java/forge/card/spellability/HumanPlaySpellAbility.java b/src/main/java/forge/card/spellability/HumanPlaySpellAbility.java index 0511aafb84a..ff58593cc7f 100644 --- a/src/main/java/forge/card/spellability/HumanPlaySpellAbility.java +++ b/src/main/java/forge/card/spellability/HumanPlaySpellAbility.java @@ -18,10 +18,10 @@ package forge.card.spellability; import java.util.ArrayList; -import java.util.List; - import org.apache.commons.lang3.StringUtils; +import com.google.common.collect.Iterables; + import forge.Card; import forge.CardCharacteristicName; import forge.ITargetable; @@ -102,7 +102,7 @@ public class HumanPlaySpellAbility { // (or trigger case where its already targeted) SpellAbility beingTargeted = ability; do { - Target tgt = beingTargeted.getTarget(); + TargetRestrictions tgt = beingTargeted.getTargetRestrictions(); if( tgt != null && tgt.doesTarget()) { clearTargets(beingTargeted); final TargetSelection select = new TargetSelection(beingTargeted); @@ -116,9 +116,9 @@ public class HumanPlaySpellAbility { } public final void clearTargets(SpellAbility ability) { - Target tg = ability.getTarget(); + TargetRestrictions tg = ability.getTargetRestrictions(); if (tg != null) { - tg.resetTargets(); + ability.resetTargets(); tg.calculateStillToDivide(ability.getParam("DividedAsYouChoose"), ability.getSourceCard(), ability); } } @@ -203,11 +203,11 @@ public class HumanPlaySpellAbility { // For older abilities that don't setStackDescription set it here final StringBuilder sb = new StringBuilder(); sb.append(ability.getSourceCard().getName()); - if (ability.getTarget() != null) { - final List targets = ability.getTarget().getTargets(); - if (targets.size() > 0) { + if (ability.getTargetRestrictions() != null) { + final Iterable targets = ability.getTargets().getTargets(); + if (!Iterables.isEmpty(targets)) { sb.append(" - Targeting "); - for (final Object o : targets) { + for (final ITargetable o : targets) { sb.append(o.toString()).append(" "); } } diff --git a/src/main/java/forge/card/spellability/SpellAbility.java b/src/main/java/forge/card/spellability/SpellAbility.java index 85323fd455b..1cb943c65f7 100644 --- a/src/main/java/forge/card/spellability/SpellAbility.java +++ b/src/main/java/forge/card/spellability/SpellAbility.java @@ -26,6 +26,10 @@ import java.util.Set; import org.apache.commons.lang3.StringUtils; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; + import forge.Card; import forge.GameEntity; import forge.ITargetable; @@ -427,29 +431,6 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable { this.payCosts = abCost; } - /** - *

- * getTarget. - *

- * - * @return a {@link forge.card.spellability.Target} object. - */ - public Target getTarget() { - return this.getChosenTarget(); - } - - /** - *

- * setTarget. - *

- * - * @param tgt - * a {@link forge.card.spellability.Target} object. - */ - public void setTarget(final Target tgt) { - this.setChosenTarget(tgt); - } - /** *

* Setter for the field restrictions. @@ -748,11 +729,7 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable { */ public void resetOnceResolved() { this.resetPaidHash(); - - if (this.getChosenTarget() != null) { - this.getChosenTarget().resetTargets(); - } - + this.resetTargets(); this.resetTriggeringObjects(); // Clear SVars @@ -1033,32 +1010,6 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable { return false; } - /** - *

- * getAllTargetChoices. - *

- * - * @return a {@link java.util.ArrayList} object. - * @since 1.0.15 - */ - public final ArrayList getAllTargetChoices() { - final ArrayList res = new ArrayList(); - - SpellAbility sa = this.getRootAbility(); - if (sa.getTarget() != null) { - res.add(sa.getTarget().getTargetChoices()); - } - while (sa.getSubAbility() != null) { - sa = sa.getSubAbility(); - - if (sa.getTarget() != null) { - res.add(sa.getTarget().getTargetChoices()); - } - } - - return res; - } - /** *

* canTarget. @@ -1069,14 +1020,14 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable { * @return a boolean. */ public final boolean canTarget(final GameEntity entity) { - if (this.getTarget() == null) { + if (this.getTargetRestrictions() == null) { if (entity.canBeTargetedBy(this)) { return true; } return false; } - if (entity.isValid(this.getTarget().getValidTgts(), this.getActivatingPlayer(), this.getSourceCard()) - && (!this.getTarget().isUniqueTargets() || !this.getUniqueTargets().contains(entity)) + if (entity.isValid(this.getTargetRestrictions().getValidTgts(), this.getActivatingPlayer(), this.getSourceCard()) + && (!this.getTargetRestrictions().isUniqueTargets() || !this.getUniqueTargets().contains(entity)) && entity.canBeTargetedBy(this)) { return true; } @@ -1352,32 +1303,74 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable { // THE CODE BELOW IS RELATED TO TARGETING. It shall await extraction to other class from here // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - private Card targetCard; + + @Override + public boolean canBeTargetedBy(SpellAbility sa) { + return sa.canBeTargetedBy(this); + } + /** The chosen target. */ - private Target chosenTarget = null; + private TargetRestrictions targetRestricions = null; + private TargetChoices targetChosen = new TargetChoices(); + + public boolean usesTargeting() { + return targetRestricions != null; + } + + public TargetRestrictions getTargetRestrictions() { + return targetRestricions; + } + + + public void setTargetRestrictions(final TargetRestrictions tgt) { + targetRestricions = tgt; + } + + /** + * Gets the chosen target. + * + * @return the chosenTarget + */ + public TargetChoices getTargets() { + return this.targetChosen; + } + + public void setTargets(TargetChoices targets) { + this.targetChosen = targets; + } + + public void resetTargets() { + targetChosen = new TargetChoices(); + } /** *

- * Getter for the field targetCard. + * getAllTargetChoices. *

* - * @return a {@link forge.Card} object. + * @return a {@link java.util.ArrayList} object. + * @since 1.0.15 */ - public Card getTargetCard() { - if (this.targetCard == null) { - final Target tgt = this.getTarget(); - if (tgt != null) { - final List list = tgt.getTargetCards(); + public final ArrayList getAllTargetChoices() { + final ArrayList res = new ArrayList(); - if (!list.isEmpty()) { - return list.get(0); - } + SpellAbility sa = this.getRootAbility(); + if (sa.getTargetRestrictions() != null) { + res.add(sa.getTargets()); + } + while (sa.getSubAbility() != null) { + sa = sa.getSubAbility(); + + if (sa.getTargetRestrictions() != null) { + res.add(sa.getTargets()); } - return null; } - return this.targetCard; + return res; + } + + public Card getTargetCard() { + return targetChosen.getFirstTargetedCard(); } /** @@ -1395,13 +1388,10 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable { return; } - final Target tgt = this.getTarget(); - if (tgt != null) { - tgt.addTarget(card); - } else { - this.targetCard = card; - } - String desc = ""; + resetTargets(); + targetChosen.add(card); + + final String desc; if (!card.isFaceDown()) { desc = this.getSourceCard().getName() + " - targeting " + card; @@ -1411,44 +1401,6 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable { 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. @@ -1457,129 +1409,66 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable { * @return a {@link forge.card.spellability.SpellAbility} object. */ public List findTargetedCards() { - 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(); + if (targetChosen.isTargetingAnyCard()) { + return Lists.newArrayList(targetChosen.getTargetCards()); } - List list = new ArrayList(); + // Next search for source cards of targeted SAs associated with current ability - if (tgt != null && tgt.getTargetSAs() != null && !tgt.getTargetSAs().isEmpty()) { - for (final SpellAbility ability : tgt.getTargetSAs()) { - list.add(ability.getSourceCard()); + if (targetChosen.isTargetingAnySpell()) { + List res = Lists.newArrayList(); + for (final SpellAbility ability : targetChosen.getTargetSpells()) { + res.add(ability.getSourceCard()); } - return list; + return res; } - // Lastly Search parent SAs for target cards - // 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()); - } - } + // Lastly Search parent SAs that targets a card + SpellAbility parent = this.getParentTargetingCard(); + if (null != parent) { + return parent.findTargetedCards(); + } - return list; + // Lastly Search parent SAs that targets an SA + parent = this.getParentTargetingSA(); + if (null != parent) { + return parent.findTargetedCards(); + } + + return ImmutableList.of(); } - /** - *

- * 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(); - } + return targetChosen.isTargetingAnyCard() ? this : getParentTargetingCard(); } - /** - *

- * getParentTargetingCard. - *

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

- * 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(); - } + return targetChosen.isTargetingAnySpell() ? this : getParentTargetingSA(); } - /** - *

- * getParentTargetingSA. - *

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

- * 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(); - } + return targetChosen.isTargetingAnyPlayer() ? this : getParentTargetingPlayer(); } /** @@ -1592,15 +1481,11 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable { public SpellAbility getParentTargetingPlayer() { SpellAbility parent = this.getParent(); while (parent != null) { - - Target tgt = parent.getTarget(); - if (tgt != null && tgt.getTargetPlayers() != null && !tgt.getTargetPlayers().isEmpty()) { - break; - } + if (parent.targetChosen.isTargetingAnyPlayer()) + return parent; parent = parent.getParent(); - } - return parent; + return null; } /** @@ -1614,21 +1499,16 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable { final List targets = new ArrayList(); SpellAbility child = this.getParent(); while (child != null) { - if (child.getTarget() != null) { - targets.addAll(child.getTarget().getTargets()); + if (child.getTargetRestrictions() != null) { + Iterables.addAll(targets, child.getTargets().getTargets()); } child = child.getParent(); } return targets; } - @Override - public boolean canBeTargetedBy(SpellAbility sa) { - return sa.canBeTargetedBy(this); - } - public boolean canTargetSpellAbility(final SpellAbility topSA) { - final Target tgt = this.getTarget(); + final TargetRestrictions tgt = this.getTargetRestrictions(); final String saType = tgt.getTargetSpellAbilityType(); if (null == saType) { @@ -1653,7 +1533,7 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable { if (splitTargetRestrictions != null) { // TODO What about spells with SubAbilities with Targets? - final Target matchTgt = topSA.getTarget(); + final TargetChoices matchTgt = topSA.getTargets(); if (matchTgt == null) { return false; @@ -1661,7 +1541,7 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable { boolean result = false; - for (final Object o : matchTgt.getTargets()) { + for (final ITargetable o : matchTgt.getTargets()) { if (matchesValid(o, splitTargetRestrictions.split(","))) { result = true; break; @@ -1674,9 +1554,8 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable { } if (tgt.isSingleTarget()) { - final ArrayList choices = topSA.getAllTargetChoices(); int totalTargets = 0; - for(TargetChoices tc : choices) { + for(TargetChoices tc : topSA.getAllTargetChoices()) { totalTargets += tc.getNumTargeted(); if (totalTargets > 1) { // As soon as we get more than one, bail out @@ -1692,7 +1571,7 @@ public abstract class SpellAbility implements ISpellAbility, ITargetable { return topSA.getSourceCard().isValid(tgt.getValidTgts(), this.getActivatingPlayer(), this.getSourceCard()); } - private boolean matchesValid(final Object o, final String[] valids) { + private boolean matchesValid(final ITargetable o, final String[] valids) { final Card srcCard = this.getSourceCard(); final Player activatingPlayer = this.getActivatingPlayer(); if (o instanceof Card) { diff --git a/src/main/java/forge/card/spellability/SpellAbilityCondition.java b/src/main/java/forge/card/spellability/SpellAbilityCondition.java index 431681391a5..254bbffba7e 100644 --- a/src/main/java/forge/card/spellability/SpellAbilityCondition.java +++ b/src/main/java/forge/card/spellability/SpellAbilityCondition.java @@ -188,7 +188,7 @@ public class SpellAbilityCondition extends SpellAbilityVariables { if( this.altCostPaid && !sa.isOptionalCostPaid(OptionalCost.AltCost)) return false; if (this.isAllTargetsLegal()) { - for (Card c : sa.getTarget().getTargetCards()) { + for (Card c : sa.getTargets().getTargetCards()) { if (!CardFactoryUtil.isTargetStillValid(sa, c)) { return false; } diff --git a/src/main/java/forge/card/spellability/SpellAbilityStackInstance.java b/src/main/java/forge/card/spellability/SpellAbilityStackInstance.java index bf05d878a40..6957f2a4faa 100644 --- a/src/main/java/forge/card/spellability/SpellAbilityStackInstance.java +++ b/src/main/java/forge/card/spellability/SpellAbilityStackInstance.java @@ -108,10 +108,10 @@ public class SpellAbilityStackInstance { // Targeting info -- 29/06/11 Moved to after taking care of SubAbilities // because otherwise AF_DealDamage SubAbilities that use Defined$ // Targeted breaks (since it's parents target is reset) - final Target target = sa.getTarget(); + final TargetRestrictions target = sa.getTargetRestrictions(); if (target != null) { - this.tc = target.getTargetChoices(); - this.ability.getTarget().resetTargets(); + this.tc = ability.getTargets(); + this.ability.resetTargets(); } final Card source = this.ability.getSourceCard(); @@ -134,10 +134,8 @@ public class SpellAbilityStackInstance { * @return a {@link forge.card.spellability.SpellAbility} object. */ public final SpellAbility getSpellAbility() { - if (this.ability.getTarget() != null) { - this.ability.getTarget().resetTargets(); - this.ability.getTarget().setTargetChoices(this.tc); - } + this.ability.resetTargets(); + this.ability.setTargets(tc); this.ability.setActivatingPlayer(activator); // Saved sub-SA needs to be reset on the way out @@ -252,10 +250,10 @@ public class SpellAbilityStackInstance { return this.tc; } - public void updateTarget(Target target) { + public void updateTarget(TargetChoices target) { if (target != null) { - this.tc = target.getTargetChoices(); - this.ability.setTarget(target); + this.tc = target; + this.ability.setTargets(tc); this.stackDescription = this.ability.getStackDescription(); } } @@ -271,7 +269,7 @@ public class SpellAbilityStackInstance { } while (compare != null && sub != null) { - TargetChoices choices = compare.getTarget() != null ? compare.getTarget().getTargetChoices() : null; + TargetChoices choices = compare.getTargetRestrictions() != null ? compare.getTargets() : null; if (choices != null && !choices.equals(sub.getTargetChoices())) { return false; diff --git a/src/main/java/forge/card/spellability/TargetChoices.java b/src/main/java/forge/card/spellability/TargetChoices.java index 2a1e92b91b3..41dce15f6d0 100644 --- a/src/main/java/forge/card/spellability/TargetChoices.java +++ b/src/main/java/forge/card/spellability/TargetChoices.java @@ -20,6 +20,8 @@ package forge.card.spellability; import java.util.ArrayList; import java.util.List; +import com.google.common.collect.Iterables; + import forge.Card; import forge.ITargetable; import forge.game.player.Player; @@ -38,7 +40,7 @@ public class TargetChoices { // Card or Player are legal targets. private final List targetCards = new ArrayList(); private final List targetPlayers = new ArrayList(); - private final List targetSAs = new ArrayList(); + private final List targetSpells = new ArrayList(); /** *

@@ -60,7 +62,7 @@ public class TargetChoices { * a {@link java.lang.Object} object. * @return a boolean. */ - public final boolean addTarget(final ITargetable o) { + public final boolean add(final ITargetable o) { if (o instanceof Player) { return this.addTarget((Player) o); } else if (o instanceof Card) { @@ -81,7 +83,7 @@ public class TargetChoices { * a {@link forge.Card} object. * @return a boolean. */ - public final boolean addTarget(final Card c) { + private final boolean addTarget(final Card c) { if (!this.targetCards.contains(c)) { this.targetCards.add(c); this.numTargeted++; @@ -99,7 +101,7 @@ public class TargetChoices { * a {@link forge.game.player.Player} object. * @return a boolean. */ - public final boolean addTarget(final Player p) { + private final boolean addTarget(final Player p) { if (!this.targetPlayers.contains(p)) { this.targetPlayers.add(p); this.numTargeted++; @@ -117,26 +119,15 @@ public class TargetChoices { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - public final boolean addTarget(final SpellAbility sa) { - if (!this.targetSAs.contains(sa)) { - this.targetSAs.add(sa); + private final boolean addTarget(final SpellAbility sa) { + if (!this.targetSpells.contains(sa)) { + this.targetSpells.add(sa); this.numTargeted++; return true; } return false; } - /** - *

- * clear. - *

- */ - public final void clear() { - this.targetPlayers.clear(); - this.targetCards.clear(); - this.targetSAs.clear(); - } - /** *

* removeTarget. @@ -146,48 +137,11 @@ public class TargetChoices { * a {@link forge.Card} object. * @return a boolean. */ - public final boolean removeTarget(final Card card) { - // Do I decrement numTargeted for fizzling targets? - if (!this.targetCards.contains(card)) { - this.targetCards.remove(card); - //this.numTargeted--; - return true; - } - return false; - } - - /** - *

- * removeTarget. - *

- * - * @param pl - * a {@link forge.game.player.Player} object. - * @return a boolean. - */ - public final boolean removeTarget(final Player pl) { - // Do I decrement numTargeted for fizzling targets? - if (!this.targetPlayers.contains(pl)) { - this.targetPlayers.remove(pl); - //this.numTargeted--; - return true; - } - return false; - } - - /** - *

- * removeTarget. - *

- * - * @param sa - * a {@link forge.card.spellability.SpellAbility} object. - * @return a boolean. - */ - public final boolean removeTarget(final SpellAbility sa) { - // Do I decrement numTargeted for fizzling targets? - if (!this.targetSAs.contains(sa)) { - this.targetSAs.remove(sa); + public final boolean remove(final ITargetable target) { + // remove returns true if element was found in given list + if (this.targetCards.remove(target) || this.targetPlayers.remove(target) || this.targetSpells.remove(target)) { + + // Do I decrement numTargeted for fizzling targets? //this.numTargeted--; return true; } @@ -201,7 +155,7 @@ public class TargetChoices { * * @return a {@link java.util.ArrayList} object. */ - public final List getTargetCards() { + public final Iterable getTargetCards() { return this.targetCards; } @@ -212,7 +166,7 @@ public class TargetChoices { * * @return a {@link java.util.ArrayList} object. */ - public final List getTargetPlayers() { + public final Iterable getTargetPlayers() { return this.targetPlayers; } @@ -223,8 +177,8 @@ public class TargetChoices { * * @return a {@link java.util.ArrayList} object. */ - public final List getTargetSAs() { - return this.targetSAs; + public final Iterable getTargetSpells() { + return this.targetSpells; } /** @@ -238,18 +192,12 @@ public class TargetChoices { final ArrayList tgts = new ArrayList(); tgts.addAll(this.targetPlayers); tgts.addAll(this.targetCards); - tgts.addAll(this.targetSAs); + tgts.addAll(this.targetSpells); return tgts; } - /** - *

- * getTargetedString. - *

- * - * @return a {@link java.lang.String} object. - */ + public final String getTargetedString() { final List tgts = this.getTargets(); final StringBuilder sb = new StringBuilder(); @@ -271,4 +219,40 @@ public class TargetChoices { return sb.toString(); } + + public final boolean isTargetingAnyCard() { + return !targetCards.isEmpty(); + } + + public final boolean isTargetingAnyPlayer() { + return !targetPlayers.isEmpty(); + } + + + public final boolean isTargetingAnySpell() { + return !targetSpells.isEmpty(); + } + + public final boolean isTargeting(ITargetable e) { + return targetCards.contains(e) || targetSpells.contains(e) || targetPlayers.contains(e); + } + + public final Card getFirstTargetedCard() { + return Iterables.getFirst(targetCards, null); + } + + public final Player getFirstTargetedPlayer() { + return Iterables.getFirst(targetPlayers, null); + } + + public final SpellAbility getFirstTargetedSpell() { + return Iterables.getFirst(targetSpells, null); + } + + /* (non-Javadoc) + * @see forge.card.spellability.ITargetsChosen#isEmpty() + */ + public final boolean isEmpty() { + return targetCards.isEmpty() && targetSpells.isEmpty() && targetPlayers.isEmpty(); + } } diff --git a/src/main/java/forge/card/spellability/Target.java b/src/main/java/forge/card/spellability/TargetRestrictions.java similarity index 79% rename from src/main/java/forge/card/spellability/Target.java rename to src/main/java/forge/card/spellability/TargetRestrictions.java index a58241e305a..42f6ad9e423 100644 --- a/src/main/java/forge/card/spellability/Target.java +++ b/src/main/java/forge/card/spellability/TargetRestrictions.java @@ -41,7 +41,7 @@ import forge.game.zone.ZoneType; * @author Forge * @version $Id$ */ -public class Target { +public class TargetRestrictions { // Target has two things happening: // Targeting restrictions (Creature, Min/Maxm etc) which are true for this @@ -70,15 +70,11 @@ public class Target { private boolean randomTarget = false; private String definedController = null; private String relatedProperty = null; - private Object definedTarget = null; // How many can be targeted? private String minTargets; private String maxTargets; - // What Choices are actually made for targeting - private TargetChoices choice = null; - // For "Divided" cards. Is this better in TargetChoices? private boolean dividedAsYouChoose = false; private HashMap dividedMap = new HashMap(); @@ -93,9 +89,9 @@ public class Target { *

* * @param target - * a {@link forge.card.spellability.Target} object. + * a {@link forge.card.spellability.TargetRestrictions} object. */ - public Target(final Target target) { + public TargetRestrictions(final TargetRestrictions target) { this.tgtValid = true; this.uiPrompt = target.getVTSelection(); this.validTgts = target.getValidTgts(); @@ -115,11 +111,9 @@ public class Target { this.relatedProperty = target.getRelatedProperty(); this.singleTarget = target.isSingleTarget(); this.randomTarget = target.isRandomTarget(); - this.definedTarget = target.getDefinedTarget(); - this.choice = target.getTargetChoices(); } - public Target() { + public TargetRestrictions() { this(null, ArrayUtils.EMPTY_STRING_ARRAY, "1", "1"); } @@ -139,36 +133,13 @@ public class Target { * @param max * a {@link java.lang.String} object. */ - public Target(final String prompt, final String[] valid, final String min, final String max) { + public TargetRestrictions(final String prompt, final String[] valid, final String min, final String max) { this.tgtValid = true; this.uiPrompt = prompt; this.validTgts = valid; this.minTargets = min; this.maxTargets = max; } - - /** - *

- * getTargetChoices. - *

- * - * @return a {@link forge.card.spellability.TargetChoices} object. - */ - public final TargetChoices getTargetChoices() { - return this.choice; - } - - /** - *

- * setTargetChoices. - *

- * - * @param tc - * a {@link forge.card.spellability.TargetChoices} object. - */ - public final void setTargetChoices(final TargetChoices tc) { - this.choice = tc; - } /** *

@@ -286,7 +257,8 @@ public class Target { * @return a boolean. */ public final boolean isMaxTargetsChosen(final Card c, final SpellAbility sa) { - return (this.choice != null) && (this.getMaxTargets(c, sa) == this.choice.getNumTargeted()); + TargetChoices choice = sa.getTargets(); + return this.getMaxTargets(c, sa) == choice.getNumTargeted(); } /** @@ -304,7 +276,8 @@ public class Target { if (this.getMinTargets(c, sa) == 0) { return true; } - return (this.choice != null) && (this.getMinTargets(c, sa) <= this.choice.getNumTargeted()); + TargetChoices choice = sa.getTargets(); + return this.getMinTargets(c, sa) <= choice.getNumTargeted(); } /** @@ -386,143 +359,6 @@ public class Target { return this.saValidTargeting; } - // Leaving old structure behind for compatibility. - /** - *

- * addTarget. - *

- * - * @param o - * a {@link java.lang.Object} object. - * @return a boolean. - */ - public final boolean addTarget(final Object o) { - if (this.choice == null) { - this.choice = new TargetChoices(); - } - - if (o instanceof Card) { - return this.choice.addTarget((Card) o); - } - - if (o instanceof Player) { - return this.choice.addTarget((Player) o); - } - - if (o instanceof SpellAbility) { - return this.choice.addTarget((SpellAbility) o); - } - - return false; - } - - /** - *

- * getTargetCards. - *

- * - * @return a {@link java.util.ArrayList} object. - */ - public final List getTargetCards() { - if (this.choice == null) { - return new ArrayList(); - } - - return this.choice.getTargetCards(); - } - - /** - *

- * getTargetPlayers. - *

- * - * @return a {@link java.util.ArrayList} object. - */ - public final List getTargetPlayers() { - if (this.choice == null) { - return new ArrayList(); - } - - return this.choice.getTargetPlayers(); - } - - /** - *

- * getTargetSAs. - *

- * - * @return a {@link java.util.ArrayList} object. - */ - public final List getTargetSAs() { - if (this.choice == null) { - return new ArrayList(); - } - - return this.choice.getTargetSAs(); - } - - /** - *

- * getTargets. - *

- * - * @return a {@link java.util.ArrayList} object. - */ - public final List getTargets() { - if (this.choice == null) { - return new ArrayList(); - } - - return this.choice.getTargets(); - } - - /** - *

- * getNumTargeted. - *

- * - * @return a int. - */ - public final int getNumTargeted() { - if (this.choice == null) { - return 0; - } - return this.choice.getNumTargeted(); - } - - /** - *

- * resetTargets. - *

- */ - public final void resetTargets() { - this.choice = null; - } - - /** - *

- * getTargetedString. - *

- * - * @return a {@link java.lang.String} object. - */ - public final String getTargetedString() { - final List tgts = this.getTargets(); - final StringBuilder sb = new StringBuilder(""); - for (final Object o : tgts) { - if (o instanceof Player) { - final Player p = (Player) o; - sb.append(p.getName()); - } - if (o instanceof Card) { - final Card c = (Card) o; - sb.append(c); - } - sb.append(" "); - } - - return sb.toString(); - } /** *

@@ -634,7 +470,7 @@ public class Target { if (isTargeted && !c.canBeTargetedBy(sa)) { continue; } - if (this.getTargetCards().contains(c)) { + if (sa.getTargets().isTargeting(c)) { continue; } return true; @@ -670,9 +506,9 @@ public class Target { * Check Valid Candidates and Targeting * @return a List. */ - public final List getAllCandidates(final SpellAbility sa, final boolean isTargeted) { + public final List getAllCandidates(final SpellAbility sa, final boolean isTargeted) { final Game game = sa.getActivatingPlayer().getGame(); - List candidates = new ArrayList(); + List candidates = new ArrayList(); for (Player player : game.getPlayers()) { if (sa.canTarget(player)) { candidates.add(player); @@ -684,7 +520,7 @@ public class Target { for (final Card c : game.getStackZone().getCards()) { boolean isValidTarget = c.isValid(this.validTgts, srcCard.getController(), srcCard); boolean canTarget = (!isTargeted || c.canBeTargetedBy(sa)); - boolean isAlreadyTargeted = this.getTargetCards().contains(c); + boolean isAlreadyTargeted = sa.getTargets().isTargeting(c); if (isValidTarget && canTarget && !isAlreadyTargeted) { candidates.add(c); } @@ -693,7 +529,7 @@ public class Target { for (final Card c : game.getCardsIn(this.tgtZone)) { boolean isValidTarget = c.isValid(this.validTgts, srcCard.getController(), srcCard); boolean canTarget = (!isTargeted || c.canBeTargetedBy(sa)); - boolean isAlreadyTargeted = this.getTargetCards().contains(c); + boolean isAlreadyTargeted = sa.getTargets().isTargeting(c); if (isValidTarget && canTarget && !isAlreadyTargeted) { candidates.add(c); } @@ -760,12 +596,12 @@ public class Target { * copy. *

* - * @return a {@link forge.card.spellability.Target} object. + * @return a {@link forge.card.spellability.TargetRestrictions} object. */ - public Target copy() { - Target clone = null; + public TargetRestrictions copy() { + TargetRestrictions clone = null; try { - clone = (Target) this.clone(); + clone = (TargetRestrictions) this.clone(); } catch (final CloneNotSupportedException e) { System.err.println(e); } @@ -860,20 +696,6 @@ public class Target { this.relatedProperty = related; } - /** - * @return the definedTarget - */ - public Object getDefinedTarget() { - return definedTarget; - } - - /** - * @param defined the definedTarget to set - */ - public void setDefinedTarget(Object defined) { - this.definedTarget = defined; - } - /** * @return the singleTarget */ diff --git a/src/main/java/forge/card/spellability/TargetSelection.java b/src/main/java/forge/card/spellability/TargetSelection.java index 485968fecfc..11bfd8d396e 100644 --- a/src/main/java/forge/card/spellability/TargetSelection.java +++ b/src/main/java/forge/card/spellability/TargetSelection.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.List; import com.google.common.base.Predicate; +import com.google.common.collect.Lists; import forge.Card; import forge.CardLists; @@ -51,8 +52,8 @@ public class TargetSelection { this.ability = sa; } - private final Target getTgt() { - return this.ability.getTarget(); + private final TargetRestrictions getTgt() { + return this.ability.getTargetRestrictions(); } private boolean bTargetingDone = false; @@ -65,14 +66,14 @@ public class TargetSelection { */ public final boolean chooseTargets() { - Target tgt = getTgt(); + TargetRestrictions tgt = getTgt(); final boolean canTarget = tgt != null && tgt.doesTarget(); if( !canTarget ) throw new RuntimeException("TargetSelection.chooseTargets called for ability that does not target - " + ability); final int minTargets = tgt.getMinTargets(ability.getSourceCard(), ability); final int maxTargets = tgt.getMaxTargets(ability.getSourceCard(), ability); - final int numTargeted = tgt.getNumTargeted(); + final int numTargeted = ability.getTargets().getNumTargeted(); boolean hasEnoughTargets = minTargets == 0 || numTargeted >= minTargets; boolean hasAllTargets = numTargeted == maxTargets && maxTargets > 0; @@ -96,13 +97,10 @@ public class TargetSelection { final boolean choiceResult; final boolean random = tgt.isRandomTarget(); - final Object defined = tgt.getDefinedTarget(); if (random) { - List candidates = tgt.getAllCandidates(this.ability, true); - Object choice = Aggregates.random(candidates); - return tgt.addTarget(choice); - } else if (defined != null) { - return tgt.addTarget(defined); + List candidates = tgt.getAllCandidates(this.ability, true); + ITargetable choice = Aggregates.random(candidates); + return ability.getTargets().add(choice); } else if (zone.size() == 1 && zone.get(0) == ZoneType.Stack) { // If Zone is Stack, the choices are handled slightly differently. // Handle everything inside function due to interaction with StackInstance @@ -137,7 +135,7 @@ public class TargetSelection { * @return */ private final List getValidCardsToTarget() { - final Target tgt = this.getTgt(); + final TargetRestrictions tgt = this.getTgt(); final Game game = ability.getActivatingPlayer().getGame(); final List zone = tgt.getZone(); @@ -163,7 +161,7 @@ public class TargetSelection { } // Remove cards already targeted - final List targeted = tgt.getTargetCards(); + final List targeted = Lists.newArrayList(ability.getTargets().getTargetCards()); for (final Card c : targeted) { if (choices.contains(c)) { choices.remove(c); @@ -323,7 +321,7 @@ public class TargetSelection { } if (chosen instanceof Card ) - this.getTgt().addTarget(chosen); + ability.getTargets().add((Card)chosen); return true; } @@ -336,7 +334,7 @@ public class TargetSelection { * a boolean. */ private final boolean chooseCardFromStack(final boolean mandatory) { - final Target tgt = this.getTgt(); + final TargetRestrictions tgt = this.getTgt(); final String message = tgt.getVTSelection(); // Find what's targetable, then allow human to choose final List selectOptions = new ArrayList(); @@ -346,7 +344,7 @@ public class TargetSelection { SpellAbility abilityOnStack = si.getSpellAbility(); if (ability.equals(abilityOnStack)) { // By peeking at stack item, target is set to its SI state. So set it back before adding targets - tgt.resetTargets(); + ability.resetTargets(); } else if (ability.canTargetSpellAbility(abilityOnStack)) { selectOptions.add(abilityOnStack); @@ -372,7 +370,7 @@ public class TargetSelection { return false; } if (madeChoice instanceof SpellAbility) { - tgt.addTarget(madeChoice); + ability.getTargets().add((SpellAbility)madeChoice); } else // 'FINISH TARGETING' chosen bTargetingDone = true; } diff --git a/src/main/java/forge/card/staticability/StaticAbilityCostChange.java b/src/main/java/forge/card/staticability/StaticAbilityCostChange.java index 90b1e7d31f3..2ae8936e46a 100644 --- a/src/main/java/forge/card/staticability/StaticAbilityCostChange.java +++ b/src/main/java/forge/card/staticability/StaticAbilityCostChange.java @@ -27,7 +27,7 @@ import forge.card.mana.ManaCostShard; import forge.card.spellability.AbilityActivated; import forge.card.spellability.Spell; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.game.zone.ZoneType; @@ -91,17 +91,14 @@ public class StaticAbilityCostChange { return; } if (params.containsKey("ValidTarget")) { - Target tgt = sa.getTarget(); + TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt == null) { return; } boolean targetValid = false; - for (Object target : tgt.getTargets()) { - if (target instanceof Card) { - Card targetCard = (Card) target; - if (targetCard.isValid(params.get("ValidTarget").split(","), hostCard.getController(), hostCard)) { - targetValid = true; - } + for (Card target : sa.getTargets().getTargetCards()) { + if (target.isValid(params.get("ValidTarget").split(","), hostCard.getController(), hostCard)) { + targetValid = true; } } if (!targetValid) { @@ -109,17 +106,15 @@ public class StaticAbilityCostChange { } } if (params.containsKey("ValidSpellTarget")) { - Target tgt = sa.getTarget(); + TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt == null) { return; } boolean targetValid = false; - for (Object target : tgt.getTargets()) { - if (target instanceof SpellAbility) { - Card targetCard = ((SpellAbility) target).getSourceCard(); - if (targetCard.isValid(params.get("ValidSpellTarget").split(","), hostCard.getController(), hostCard)) { - targetValid = true; - } + for (SpellAbility target : sa.getTargets().getTargetSpells()) { + Card targetCard = target.getSourceCard(); + if (targetCard.isValid(params.get("ValidSpellTarget").split(","), hostCard.getController(), hostCard)) { + targetValid = true; } } if (!targetValid) { @@ -223,17 +218,14 @@ public class StaticAbilityCostChange { } } if (params.containsKey("ValidTarget")) { - Target tgt = sa.getTarget(); + TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt == null) { return; } boolean targetValid = false; - for (Object target : tgt.getTargets()) { - if (target instanceof Card) { - Card targetCard = (Card) target; - if (targetCard.isValid(params.get("ValidTarget").split(","), hostCard.getController(), hostCard)) { - targetValid = true; - } + for (Card target : sa.getTargets().getTargetCards()) { + if (target.isValid(params.get("ValidTarget").split(","), hostCard.getController(), hostCard)) { + targetValid = true; } } if (!targetValid) { diff --git a/src/main/java/forge/card/trigger/TriggerHandler.java b/src/main/java/forge/card/trigger/TriggerHandler.java index ed682b1a07d..0634931f4ea 100644 --- a/src/main/java/forge/card/trigger/TriggerHandler.java +++ b/src/main/java/forge/card/trigger/TriggerHandler.java @@ -31,7 +31,7 @@ import forge.card.ability.effects.CharmEffect; import forge.card.mana.ManaCost; import forge.card.spellability.Ability; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.Game; import forge.game.GlobalRuleChange; import forge.game.ai.ComputerUtil; @@ -394,7 +394,7 @@ public class TriggerHandler { SpellAbility ability = sa; while (ability != null) { - final Target tgt = ability.getTarget(); + final TargetRestrictions tgt = ability.getTargetRestrictions(); if (tgt != null) { tgt.setMandatory(true); diff --git a/src/main/java/forge/card/trigger/TriggerSpellAbilityCast.java b/src/main/java/forge/card/trigger/TriggerSpellAbilityCast.java index 2468087b198..8d437d8cbf1 100644 --- a/src/main/java/forge/card/trigger/TriggerSpellAbilityCast.java +++ b/src/main/java/forge/card/trigger/TriggerSpellAbilityCast.java @@ -112,16 +112,16 @@ public class TriggerSpellAbilityCast extends Trigger { if (si != null) { sa = si.getSpellAbility(); } - if (sa.getTarget() == null) { + if (sa.getTargetRestrictions() == null) { if (sa.getTargetCard() == null) { - if (sa.getTargetPlayer() == null) { + Player targetPl = sa.getTargets().getFirstTargetedPlayer(); + if (targetPl == null) + return false; + + if (!matchesValid(targetPl, this.mapParams.get("TargetsValid").split(","), this.getHostCard())) { return false; - } else { - if (!matchesValid(sa.getTargetPlayer(), - this.mapParams.get("TargetsValid").split(","), this.getHostCard())) { - return false; - } } + } else { if (!matchesValid(sa.getTargetCard(), this.mapParams.get("TargetsValid").split(","), this.getHostCard())) { @@ -129,9 +129,9 @@ public class TriggerSpellAbilityCast extends Trigger { } } } else { - if (sa.getTarget().doesTarget()) { + if (sa.getTargetRestrictions().doesTarget()) { boolean validTgtFound = false; - for (final Card tgt : sa.getTarget().getTargetCards()) { + for (final Card tgt : sa.getTargets().getTargetCards()) { if (tgt.isValid(this.mapParams.get("TargetsValid").split(","), this.getHostCard() .getController(), this.getHostCard())) { validTgtFound = true; @@ -139,7 +139,7 @@ public class TriggerSpellAbilityCast extends Trigger { } } - for (final Player p : sa.getTarget().getTargetPlayers()) { + for (final Player p : sa.getTargets().getTargetPlayers()) { if (matchesValid(p, this.mapParams.get("TargetsValid").split(","), this.getHostCard())) { validTgtFound = true; break; @@ -168,7 +168,7 @@ public class TriggerSpellAbilityCast extends Trigger { } } if (this.mapParams.containsKey("IsSingleTarget")) { - if (spellAbility.getTarget().getTargets().size() != 1) { + if (spellAbility.getTargets().getNumTargeted() != 1) { return false; } } diff --git a/src/main/java/forge/card/trigger/WrappedAbility.java b/src/main/java/forge/card/trigger/WrappedAbility.java index 7b6a7001a7e..a9d56c0627b 100644 --- a/src/main/java/forge/card/trigger/WrappedAbility.java +++ b/src/main/java/forge/card/trigger/WrappedAbility.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Map; import forge.Card; +import forge.ITargetable; import forge.card.ability.ApiType; import forge.card.cost.Cost; import forge.card.mana.ManaCost; @@ -13,7 +14,7 @@ import forge.card.spellability.AbilitySub; import forge.card.spellability.ISpellAbility; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbilityRestriction; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.card.spellability.TargetChoices; import forge.game.Game; import forge.game.ai.ComputerUtil; @@ -175,9 +176,9 @@ public class WrappedAbility extends Ability implements ISpellAbility { @Override public String getStackDescription() { final StringBuilder sb = new StringBuilder(regtrig.toString()); - if (this.getTarget() != null) { + if (this.getTargetRestrictions() != null) { sb.append(" (Targeting "); - for (final Object o : this.getTarget().getTargets()) { + for (final ITargetable o : this.getTargets().getTargets()) { sb.append(o.toString()); sb.append(", "); } @@ -198,8 +199,8 @@ public class WrappedAbility extends Ability implements ISpellAbility { } @Override - public Target getTarget() { - return sa.getTarget(); + public TargetRestrictions getTargetRestrictions() { + return sa.getTargetRestrictions(); } @Override @@ -208,8 +209,8 @@ public class WrappedAbility extends Ability implements ISpellAbility { } @Override - public Player getTargetPlayer() { - return sa.getTargetPlayer(); + public TargetChoices getTargets() { + return sa.getTargets(); } @Override @@ -299,8 +300,8 @@ public class WrappedAbility extends Ability implements ISpellAbility { } @Override - public void setTarget(final Target tgt) { - sa.setTarget(tgt); + public void setTargetRestrictions(final TargetRestrictions tgt) { + sa.setTargetRestrictions(tgt); } @Override @@ -394,26 +395,25 @@ public class WrappedAbility extends Ability implements ISpellAbility { // needs to be expanded when a more difficult cards comes up } else { // Store/replace target choices more properly to get this SA cleared. - Target tgt = sa.getTarget(); TargetChoices tc = null; - boolean storeChoices = tgt != null && tgt.getTargetChoices() != null; + boolean storeChoices = sa.getTargetRestrictions() != null; if (storeChoices) { - tc = tgt.getTargetChoices(); - tgt.resetTargets(); + tc = sa.getTargets(); + sa.resetTargets(); } // There is no way this doTrigger here will have the same target as stored above // So it's possible it's making a different decision here than will actually happen if (!sa.doTrigger(this.isMandatory(), decider)) { if (storeChoices) { - tgt.resetTargets(); - tgt.setTargetChoices(tc); + sa.resetTargets(); + sa.setTargets(tc); } return false; } if (storeChoices) { - tgt.resetTargets(); - tgt.setTargetChoices(tc); + sa.resetTargets(); + sa.setTargets(tc); } } } diff --git a/src/main/java/forge/game/Game.java b/src/main/java/forge/game/Game.java index 9520ae270cd..0dac2ef6be1 100644 --- a/src/main/java/forge/game/Game.java +++ b/src/main/java/forge/game/Game.java @@ -417,7 +417,6 @@ public class Game { return c; } } - return card; } diff --git a/src/main/java/forge/game/GameAction.java b/src/main/java/forge/game/GameAction.java index f08b9f321f0..236c9ea7683 100644 --- a/src/main/java/forge/game/GameAction.java +++ b/src/main/java/forge/game/GameAction.java @@ -52,7 +52,7 @@ import forge.card.replacement.ReplacementResult; import forge.card.spellability.Ability; import forge.card.spellability.AbilityActivated; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.card.staticability.StaticAbility; import forge.card.trigger.Trigger; import forge.card.trigger.TriggerType; @@ -937,9 +937,9 @@ public class GameAction { final GameEntity entity = c.getEnchanting(); final SpellAbility sa = c.getSpells().get(0); - Target tgt = null; + TargetRestrictions tgt = null; if (sa != null) { - tgt = sa.getTarget(); + tgt = sa.getTargetRestrictions(); } if (entity instanceof Card) { diff --git a/src/main/java/forge/game/ai/ComputerUtil.java b/src/main/java/forge/game/ai/ComputerUtil.java index 7d5a47195ab..a260b619000 100644 --- a/src/main/java/forge/game/ai/ComputerUtil.java +++ b/src/main/java/forge/game/ai/ComputerUtil.java @@ -50,7 +50,7 @@ import forge.card.spellability.AbilityManaPart; import forge.card.spellability.AbilityStatic; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbilityStackInstance; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.card.staticability.StaticAbility; import forge.error.BugReporter; import forge.game.Game; @@ -173,7 +173,7 @@ public class ComputerUtil { int restrict = 0; final Card source = sa.getSourceCard(); - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); // Play higher costing spells first? @@ -824,7 +824,7 @@ public class ComputerUtil { } } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { if (CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), controller, sa.getSourceCard()).contains(card)) { return true; @@ -872,7 +872,7 @@ public class ComputerUtil { if (AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa).contains(card)) { prevented += AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("Amount"), sa); } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt != null) { if (CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), controller, sa.getSourceCard()).contains(card)) { prevented += AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("Amount"), sa); @@ -1236,7 +1236,7 @@ public class ComputerUtil { if (dmg <= damage) { continue; } - final Target tgt = sa.getTarget(); + final TargetRestrictions tgt = sa.getTargetRestrictions(); if (tgt == null) { continue; } @@ -1263,16 +1263,16 @@ public class ComputerUtil { * @return a {@link java.util.ArrayList} object. * @since 1.0.15 */ - public static ArrayList predictThreatenedObjects(final Player aiPlayer, final SpellAbility sa) { + public static List predictThreatenedObjects(final Player aiPlayer, final SpellAbility sa) { final Game game = aiPlayer.getGame(); - final ArrayList objects = new ArrayList(); + final List objects = new ArrayList(); if (game.getStack().isEmpty()) { return objects; } // check stack for something that will kill this final SpellAbility topStack = game.getStack().peekAbility(); - objects.addAll(ComputerUtil.predictThreatenedObjects(aiPlayer, sa, topStack)); + Iterables.addAll(objects, ComputerUtil.predictThreatenedObjects(aiPlayer, sa, topStack)); return objects; } @@ -1289,9 +1289,9 @@ public class ComputerUtil { * @return a {@link java.util.ArrayList} object. * @since 1.0.15 */ - public static List predictThreatenedObjects(final Player aiPlayer, final SpellAbility saviour, + private static Iterable predictThreatenedObjects(final Player aiPlayer, final SpellAbility saviour, final SpellAbility topStack) { - List objects = new ArrayList(); + Iterable objects = new ArrayList(); final List threatened = new ArrayList(); ApiType saviourApi = saviour.getApi(); @@ -1304,20 +1304,17 @@ public class ComputerUtil { // Can only Predict things from AFs if (threatApi != null) { - final Target tgt = topStack.getTarget(); + final TargetRestrictions tgt = topStack.getTargetRestrictions(); if (tgt == null) { if (topStack.hasParam("Defined")) { objects = AbilityUtils.getDefinedObjects(source, topStack.getParam("Defined"), topStack); } else if (topStack.hasParam("ValidCards")) { List battleField = aiPlayer.getCardsIn(ZoneType.Battlefield); - List cards = CardLists.getValidCards(battleField, topStack.getParam("ValidCards").split(","), source.getController(), source); - for (Card card : cards) { - objects.add(card); - } + objects = CardLists.getValidCards(battleField, topStack.getParam("ValidCards").split(","), source.getController(), source); } } else { - objects = tgt.getTargets(); + objects = topStack.getTargets().getTargets(); } // Determine if Defined Objects are "threatened" will be destroyed @@ -1440,7 +1437,7 @@ public class ComputerUtil { } } - threatened.addAll(ComputerUtil.predictThreatenedObjects(aiPlayer, saviour, topStack.getSubAbility())); + Iterables.addAll(threatened, ComputerUtil.predictThreatenedObjects(aiPlayer, saviour, topStack.getSubAbility())); return threatened; } diff --git a/src/main/java/forge/game/player/HumanPlay.java b/src/main/java/forge/game/player/HumanPlay.java index 93e3044cf1d..20897ac1441 100644 --- a/src/main/java/forge/game/player/HumanPlay.java +++ b/src/main/java/forge/game/player/HumanPlay.java @@ -45,7 +45,7 @@ import forge.card.mana.ManaCostBeingPaid; import forge.card.spellability.Ability; import forge.card.spellability.HumanPlaySpellAbility; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.GameActionUtil; import forge.game.Game; import forge.game.zone.ZoneType; @@ -109,7 +109,7 @@ public class HumanPlay { boolean newAbility = sa.getPayCosts() != null; SpellAbility ability = sa; while ((ability != null) && !newAbility) { - final Target tgt = ability.getTarget(); + final TargetRestrictions tgt = ability.getTargetRestrictions(); newAbility |= tgt != null; ability = ability.getSubAbility(); diff --git a/src/main/java/forge/game/player/Player.java b/src/main/java/forge/game/player/Player.java index e5c6e992765..bddc5754928 100644 --- a/src/main/java/forge/game/player/Player.java +++ b/src/main/java/forge/game/player/Player.java @@ -49,7 +49,6 @@ import forge.card.mana.ManaPool; import forge.card.replacement.ReplacementResult; import forge.card.spellability.Ability; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.card.staticability.StaticAbility; import forge.card.trigger.TriggerType; import forge.game.GameActionUtil; @@ -1288,7 +1287,7 @@ public class Player extends GameEntity implements Comparable { // It's oracle-worded as a replacement effect ("If a player would draw a card ... discards a card instead") (rule 419.1a) // Yet, gatherer's rulings read: The effect is cumulative. If there are two of these on the battlefield, each of them will modify each draw // That means player isn't supposed to choose one replacement effect out of two (generated by Chains Of Mephistopheles), but both happen. - // So it's not a common replacement effect and has to handled by special code. + // So it's not a common replacement effect and has to be handled by special code. // This is why the code is placed after any other replacement effects could affect the draw event. List chainsList = null; @@ -1302,20 +1301,19 @@ public class Player extends GameEntity implements Comparable { if (chainsList != null && (numDrawnThisDrawStep > 0 || !game.getPhaseHandler().is(PhaseType.DRAW))) { for(Card c : chainsList) { // I have to target this player - don't know how to do it. - Target target = new Target(); - target.addTarget(this); + if (getCardsIn(ZoneType.Hand).isEmpty()) { SpellAbility saMill = AbilityFactory.getAbility(c.getSVar("MillOne"), c); saMill.setActivatingPlayer(c.getController()); - saMill.setTarget(target); + saMill.getTargets().add(this); AbilityUtils.resolve(saMill); - + return drawn; // Draw is cancelled } else { SpellAbility saDiscard = AbilityFactory.getAbility(c.getSVar("DiscardOne"), c); saDiscard.setActivatingPlayer(c.getController()); - saDiscard.setTarget(target); + saDiscard.getTargets().add(this); AbilityUtils.resolve(saDiscard); } } diff --git a/src/main/java/forge/game/player/PlayerController.java b/src/main/java/forge/game/player/PlayerController.java index 1a5284c48f7..56fa4c7a62f 100644 --- a/src/main/java/forge/game/player/PlayerController.java +++ b/src/main/java/forge/game/player/PlayerController.java @@ -13,7 +13,7 @@ import forge.card.cost.Cost; import forge.card.mana.Mana; import forge.card.replacement.ReplacementEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetChoices; import forge.deck.Deck; import forge.game.Game; import forge.game.GameType; @@ -101,7 +101,7 @@ public abstract class PlayerController { public abstract Integer announceRequirements(SpellAbility ability, String announce, boolean allowZero); public abstract List choosePermanentsToSacrifice(SpellAbility sa, int min, int max, List validTargets, String message); public abstract List choosePermanentsToDestroy(SpellAbility sa, int min, int max, List validTargets, String message); - public abstract Target chooseTargets(SpellAbility ability); + public abstract TargetChoices chooseTargets(SpellAbility ability); public Card chooseSingleCardForEffect(List sourceList, SpellAbility sa, String title) { return chooseSingleCardForEffect(sourceList, sa, title, false); } public abstract Card chooseSingleCardForEffect(List sourceList, SpellAbility sa, String title, boolean isOptional); diff --git a/src/main/java/forge/game/player/PlayerControllerAi.java b/src/main/java/forge/game/player/PlayerControllerAi.java index fca4fbbbc4b..494fd5678af 100644 --- a/src/main/java/forge/game/player/PlayerControllerAi.java +++ b/src/main/java/forge/game/player/PlayerControllerAi.java @@ -23,7 +23,7 @@ import forge.card.spellability.Ability; import forge.card.spellability.AbilityStatic; import forge.card.spellability.Spell; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetChoices; import forge.deck.Deck; import forge.game.Game; import forge.game.GameType; @@ -255,7 +255,7 @@ public class PlayerControllerAi extends PlayerController { * @see forge.game.player.PlayerController#chooseTargets(forge.card.spellability.SpellAbility, forge.card.spellability.SpellAbilityStackInstance) */ @Override - public Target chooseTargets(SpellAbility ability) { + public TargetChoices chooseTargets(SpellAbility ability) { // AI currently can't do this. But when it can it will need to be based on Ability API return null; } diff --git a/src/main/java/forge/game/player/PlayerControllerHuman.java b/src/main/java/forge/game/player/PlayerControllerHuman.java index d407c25a55d..8c5a1bd43e4 100644 --- a/src/main/java/forge/game/player/PlayerControllerHuman.java +++ b/src/main/java/forge/game/player/PlayerControllerHuman.java @@ -21,8 +21,8 @@ import forge.card.cost.Cost; import forge.card.mana.Mana; import forge.card.replacement.ReplacementEffect; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; import forge.card.spellability.TargetSelection; +import forge.card.spellability.TargetChoices; import forge.deck.CardPool; import forge.deck.Deck; import forge.deck.DeckSection; @@ -440,15 +440,15 @@ public class PlayerControllerHuman extends PlayerController { * @see forge.game.player.PlayerController#chooseTargets(forge.card.spellability.SpellAbility, forge.card.spellability.SpellAbilityStackInstance) */ @Override - public Target chooseTargets(SpellAbility ability) { - if (ability.getTarget() == null) { + public TargetChoices chooseTargets(SpellAbility ability) { + if (ability.getTargetRestrictions() == null) { return null; } - Target oldTarget = new Target(ability.getTarget()); + TargetChoices oldTarget = ability.getTargets(); TargetSelection select = new TargetSelection(ability); - ability.getTarget().resetTargets(); + ability.resetTargets(); if (select.chooseTargets()) { - return ability.getTarget(); + return ability.getTargets(); } else { // Return old target, since we had to reset them above return oldTarget; diff --git a/src/main/java/forge/game/zone/MagicStack.java b/src/main/java/forge/game/zone/MagicStack.java index e8845b6cb11..87c026c706e 100644 --- a/src/main/java/forge/game/zone/MagicStack.java +++ b/src/main/java/forge/game/zone/MagicStack.java @@ -51,7 +51,7 @@ import forge.card.spellability.OptionalCost; import forge.card.spellability.Spell; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbilityStackInstance; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.card.spellability.TargetChoices; import forge.card.trigger.Trigger; import forge.card.trigger.TriggerType; @@ -670,9 +670,9 @@ public class MagicStack /* extends MyObservable */ implements Iterable tgts = tgt.getTargets(); - final TargetChoices choices = tgt.getTargetChoices(); - for (final Object o : tgts) { + final TargetChoices choices = sa.getTargets(); + for (final ITargetable o : sa.getTargets().getTargets()) { boolean invalidTarget = false; - if (o instanceof Player) { - final Player p = (Player) o; - invalidTarget = !(p.canBeTargetedBy(sa)); - // TODO Remove target? - if (invalidTarget) { - choices.removeTarget(p); - } - } - else if (o instanceof Card) { + if (o instanceof Card) { final Card card = (Card) o; Card current = game.getCardState(card); - invalidTarget = current.getTimestamp() != card.getTimestamp(); - invalidTarget |= !(CardFactoryUtil.isTargetStillValid(sa, card)); + } else { + invalidTarget = !o.canBeTargetedBy(sa); + } + // Remove targets + if (invalidTarget) { + choices.remove(o); + } - if (invalidTarget) { - choices.removeTarget(card); - } - // Remove targets - } - else if (o instanceof SpellAbility) { - final SpellAbility tgtSA = (SpellAbility) o; - invalidTarget = !(sa.canTargetSpellAbility(tgtSA)); - // TODO Remove target? - if (invalidTarget) { - choices.removeTarget(tgtSA); - } - } fizzle &= invalidTarget; } } diff --git a/src/main/java/forge/gui/input/InputSelectTargets.java b/src/main/java/forge/gui/input/InputSelectTargets.java index 2be155b7d7c..e70b33813c9 100644 --- a/src/main/java/forge/gui/input/InputSelectTargets.java +++ b/src/main/java/forge/gui/input/InputSelectTargets.java @@ -9,7 +9,7 @@ import forge.Card; import forge.GameEntity; import forge.card.ability.ApiType; import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; +import forge.card.spellability.TargetRestrictions; import forge.game.player.Player; import forge.gui.GuiChoose; import forge.view.ButtonUtil; @@ -22,7 +22,7 @@ public final class InputSelectTargets extends InputSyncronizedBase { private final List choices; // some cards can be targeted several times (eg: distribute damage as you choose) private final Map targetDepth = new HashMap(); - private final Target tgt; + private final TargetRestrictions tgt; private final SpellAbility sa; private boolean bCancel = false; private boolean bOk = false; @@ -44,7 +44,7 @@ public final class InputSelectTargets extends InputSyncronizedBase { */ public InputSelectTargets(List choices, SpellAbility sa, boolean mandatory) { this.choices = choices; - this.tgt = sa.getTarget(); + this.tgt = sa.getTargetRestrictions(); this.sa = sa; this.mandatory = mandatory; } @@ -64,7 +64,7 @@ public final class InputSelectTargets extends InputSyncronizedBase { sb.append(tgt.getVTSelection()); int maxTargets = tgt.getMaxTargets(sa.getSourceCard(), sa); - int targeted = tgt.getNumTargeted(); + int targeted = sa.getTargets().getNumTargeted(); if(maxTargets > 1) sb.append("\n(").append(maxTargets - targeted).append(" more can be targeted)"); @@ -125,7 +125,7 @@ public final class InputSelectTargets extends InputSyncronizedBase { final int stillToDivide = tgt.getStillToDivide(); int allocatedPortion = 0; // allow allocation only if the max targets isn't reached and there are more candidates - if ((tgt.getNumTargeted() + 1 < tgt.getMaxTargets(sa.getSourceCard(), sa)) + if ((sa.getTargets().getNumTargeted() + 1 < tgt.getMaxTargets(sa.getSourceCard(), sa)) && (tgt.getNumCandidates(sa, true) - 1 > 0) && stillToDivide > 1) { final Integer[] choices = new Integer[stillToDivide]; for (int i = 1; i <= stillToDivide; i++) { @@ -171,7 +171,7 @@ public final class InputSelectTargets extends InputSyncronizedBase { final int stillToDivide = tgt.getStillToDivide(); int allocatedPortion = 0; // allow allocation only if the max targets isn't reached and there are more candidates - if ((tgt.getNumTargeted() + 1 < tgt.getMaxTargets(sa.getSourceCard(), sa)) && (tgt.getNumCandidates(sa, true) - 1 > 0) && stillToDivide > 1) { + if ((sa.getTargets().getNumTargeted() + 1 < tgt.getMaxTargets(sa.getSourceCard(), sa)) && (tgt.getNumCandidates(sa, true) - 1 > 0) && stillToDivide > 1) { final Integer[] choices = new Integer[stillToDivide]; for (int i = 1; i <= stillToDivide; i++) { choices[i - 1] = i; @@ -200,7 +200,7 @@ public final class InputSelectTargets extends InputSyncronizedBase { } private void addTarget(GameEntity ge) { - tgt.addTarget(ge); + sa.getTargets().add(ge); if(ge instanceof Card) { ((Card) ge).setUsedToPay(true); }