SpellAbility holds separate TargetRestricions and TargetChoices in separate members.

Some APIs might become broken, please report
This commit is contained in:
Maxmtg
2013-06-19 14:51:21 +00:00
parent 3c3ab8138b
commit ade7bed52f
172 changed files with 1391 additions and 1936 deletions

3
.gitattributes vendored
View File

@@ -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/AbilityFactory.java svneol=native#text/plain
src/main/java/forge/card/ability/AbilityUtils.java -text src/main/java/forge/card/ability/AbilityUtils.java -text
src/main/java/forge/card/ability/ApiType.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/SpellAbilityAi.java -text
src/main/java/forge/card/ability/SpellAbilityEffect.java -text src/main/java/forge/card/ability/SpellAbilityEffect.java -text
src/main/java/forge/card/ability/SpellApiBased.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/SpellAbilityStackInstance.java svneol=native#text/plain
src/main/java/forge/card/spellability/SpellAbilityVariables.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/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/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/TargetSelection.java svneol=native#text/plain
src/main/java/forge/card/spellability/package-info.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 src/main/java/forge/card/staticability/StaticAbility.java svneol=native#text/plain

View File

@@ -58,7 +58,7 @@ import forge.card.spellability.AbilityTriggered;
import forge.card.spellability.OptionalCost; import forge.card.spellability.OptionalCost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellPermanent; import forge.card.spellability.SpellPermanent;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.card.staticability.StaticAbility; import forge.card.staticability.StaticAbility;
import forge.card.trigger.Trigger; import forge.card.trigger.Trigger;
import forge.card.trigger.TriggerType; import forge.card.trigger.TriggerType;
@@ -5355,7 +5355,7 @@ public class Card extends GameEntity implements Comparable<Card> {
for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) { for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) {
final SpellAbility saTargeting = sa.getSATargetingPlayer(); final SpellAbility saTargeting = sa.getSATargetingPlayer();
if (saTargeting != null) { if (saTargeting != null) {
for (final Player p : saTargeting.getTarget().getTargetPlayers()) { for (final Player p : saTargeting.getTargets().getTargetPlayers()) {
if (!this.getController().equals(p)) { if (!this.getController().equals(p)) {
return false; return false;
} }
@@ -5403,7 +5403,7 @@ public class Card extends GameEntity implements Comparable<Card> {
for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) { for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) {
final SpellAbility saTargeting = sa.getSATargetingPlayer(); final SpellAbility saTargeting = sa.getSATargetingPlayer();
if (saTargeting != null) { if (saTargeting != null) {
for (final Player p : saTargeting.getTarget().getTargetPlayers()) { for (final Player p : saTargeting.getTargets().getTargetPlayers()) {
if (!this.getOwner().equals(p)) { if (!this.getOwner().equals(p)) {
return false; return false;
} }
@@ -5504,7 +5504,7 @@ public class Card extends GameEntity implements Comparable<Card> {
for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) { for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) {
final SpellAbility saTargeting = sa.getSATargetingCard(); final SpellAbility saTargeting = sa.getSATargetingCard();
if (saTargeting != null) { 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())) { if (!this.getEnchantedBy().contains(c) && !this.equals(c.getEnchanting())) {
return false; return false;
} }
@@ -5518,7 +5518,7 @@ public class Card extends GameEntity implements Comparable<Card> {
for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) { for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) {
final SpellAbility saTargeting = sa.getSATargetingCard(); final SpellAbility saTargeting = sa.getSATargetingCard();
if (saTargeting != null) { if (saTargeting != null) {
for (final Card c : saTargeting.getTarget().getTargetCards()) { for (final Card c : saTargeting.getTargets().getTargetCards()) {
if (this.getEnchantedBy().contains(c)) { if (this.getEnchantedBy().contains(c)) {
return false; return false;
} }
@@ -5549,7 +5549,7 @@ public class Card extends GameEntity implements Comparable<Card> {
for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) { for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) {
final SpellAbility saTargeting = sa.getSATargetingCard(); final SpellAbility saTargeting = sa.getSATargetingCard();
if (saTargeting != null) { if (saTargeting != null) {
for (final Card c : saTargeting.getTarget().getTargetCards()) { for (final Card c : saTargeting.getTargets().getTargetCards()) {
if (!this.canBeEnchantedBy(c)) { if (!this.canBeEnchantedBy(c)) {
return false; return false;
} }
@@ -5575,7 +5575,7 @@ public class Card extends GameEntity implements Comparable<Card> {
for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) { for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) {
final SpellAbility saTargeting = sa.getSATargetingCard(); final SpellAbility saTargeting = sa.getSATargetingCard();
if (saTargeting != null) { if (saTargeting != null) {
for (final Card c : saTargeting.getTarget().getTargetCards()) { for (final Card c : saTargeting.getTargets().getTargetCards()) {
if (!this.equippedBy.contains(c)) { if (!this.equippedBy.contains(c)) {
return false; return false;
} }
@@ -5686,7 +5686,7 @@ public class Card extends GameEntity implements Comparable<Card> {
for (final SpellAbility sa : this.getCharacteristics().getSpellAbility()) { for (final SpellAbility sa : this.getCharacteristics().getSpellAbility()) {
final SpellAbility saTargeting = sa.getSATargetingCard(); final SpellAbility saTargeting = sa.getSATargetingCard();
if (saTargeting != null) { if (saTargeting != null) {
for (final Card c : saTargeting.getTarget().getTargetCards()) { for (final Card c : saTargeting.getTargets().getTargetCards()) {
if (c.equals(source)) { if (c.equals(source)) {
return true; return true;
} }
@@ -8050,9 +8050,9 @@ public class Card extends GameEntity implements Comparable<Card> {
*/ */
public final boolean canBeEnchantedBy(final Card aura) { public final boolean canBeEnchantedBy(final Card aura) {
final SpellAbility sa = aura.getFirstSpellAbility(); final SpellAbility sa = aura.getFirstSpellAbility();
Target tgt = null; TargetRestrictions tgt = null;
if (sa != null) { if (sa != null) {
tgt = sa.getTarget(); tgt = sa.getTargetRestrictions();
} }
if (this.hasProtectionFrom(aura) if (this.hasProtectionFrom(aura)

View File

@@ -76,7 +76,7 @@ public class GameLogFormatter extends IGameEventVisitor.Base<GameLogEntry> {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(who).append(action).append(what); sb.append(who).append(action).append(what);
if (event.sa.getTarget() != null) { if (event.sa.getTargetRestrictions() != null) {
sb.append(" targeting "); sb.append(" targeting ");
for (TargetChoices ch : event.sa.getAllTargetChoices()) { for (TargetChoices ch : event.sa.getAllTargetChoices()) {
if (null != ch) { if (null != ch) {

View File

@@ -11,7 +11,7 @@ import forge.card.cardfactory.CardFactory;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.AbilityActivated; import forge.card.spellability.AbilityActivated;
import forge.card.spellability.AbilityManaPart; import forge.card.spellability.AbilityManaPart;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player; import forge.game.player.Player;
public class AbilityApiBased extends AbilityActivated { public class AbilityApiBased extends AbilityActivated {
@@ -20,7 +20,7 @@ public class AbilityApiBased extends AbilityActivated {
private static final long serialVersionUID = -4183793555528531978L; private static final long serialVersionUID = -4183793555528531978L;
public AbilityApiBased(ApiType api0, Card sourceCard, Cost abCost, Target tgt, Map<String, String> params0) { public AbilityApiBased(ApiType api0, Card sourceCard, Cost abCost, TargetRestrictions tgt, Map<String, String> params0) {
super(sourceCard, abCost, tgt); super(sourceCard, abCost, tgt);
params = params0; params = params0;
api = api0; api = api0;
@@ -48,7 +48,7 @@ public class AbilityApiBased extends AbilityActivated {
*/ */
@Override @Override
public AbilityActivated getCopy() { 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); AbilityActivated res = new AbilityApiBased(api, getSourceCard(), getPayCosts(), tgt, params);
CardFactory.copySpellAbility(this, res); CardFactory.copySpellAbility(this, res);
return res; return res;

View File

@@ -28,7 +28,7 @@ import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityCondition; import forge.card.spellability.SpellAbilityCondition;
import forge.card.spellability.SpellAbilityRestriction; import forge.card.spellability.SpellAbilityRestriction;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.util.FileSection; import forge.util.FileSection;
@@ -55,7 +55,7 @@ public final class AbilityFactory {
return prefix; return prefix;
} }
public SpellAbility buildSpellAbility(ApiType api, Card hostCard, Cost abCost, Target abTgt, Map<String, String> mapParams ) { public SpellAbility buildSpellAbility(ApiType api, Card hostCard, Cost abCost, TargetRestrictions abTgt, Map<String, String> mapParams ) {
switch(this) { switch(this) {
case Ability: return new AbilityApiBased(api, hostCard, abCost, abTgt, mapParams); case Ability: return new AbilityApiBased(api, hostCard, abCost, abTgt, mapParams);
case Spell: return new SpellApiBased(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<String, String> mapParams, Cost abCost, Card hostCard) { public static final SpellAbility getAbility(AbilityRecordType type, ApiType api, Map<String, String> 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) { 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 // 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; return spellAbility;
} }
private static final Target readTarget(Map<String, String> mapParams) { private static final TargetRestrictions readTarget(Map<String, String> mapParams) {
final String min = mapParams.containsKey("TargetMin") ? mapParams.get("TargetMin") : "1"; final String min = mapParams.containsKey("TargetMin") ? mapParams.get("TargetMin") : "1";
final String max = mapParams.containsKey("TargetMax") ? mapParams.get("TargetMax") : "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"); final String prompt = mapParams.containsKey("TgtPrompt") ? mapParams.get("TgtPrompt") : "Select target " + mapParams.get("ValidTgts");
sb.append(prompt); 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 if (mapParams.containsKey("TgtZone")) { // if Targeting
// something // something
@@ -338,11 +338,11 @@ public final class AbilityFactory {
origin = ZoneType.listValueOf(params.get("Origin")); 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 // Don't set the zone if it targets a player
if ((tgt != null) && !tgt.canTgtPlayer()) { if ((tgt != null) && !tgt.canTgtPlayer()) {
sa.getTarget().setZone(origin); sa.getTargetRestrictions().setZone(origin);
} }
} }

View File

@@ -9,6 +9,8 @@ import forge.card.MagicColor;
import forge.card.mana.ManaCostShard; import forge.card.mana.ManaCostShard;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.google.common.collect.Iterables;
import forge.Card; import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.CardUtil; import forge.CardUtil;
@@ -124,13 +126,13 @@ public class AbilityUtils {
else if (defined.equals("Targeted")) { else if (defined.equals("Targeted")) {
final SpellAbility saTargeting = sa.getSATargetingCard(); final SpellAbility saTargeting = sa.getSATargetingCard();
if (saTargeting != null) { if (saTargeting != null) {
cards.addAll(saTargeting.getTarget().getTargetCards()); Iterables.addAll(cards, saTargeting.getTargets().getTargetCards());
} }
} else if (defined.equals("ParentTarget")) { } else if (defined.equals("ParentTarget")) {
final SpellAbility parent = sa.getParentTargetingCard(); final SpellAbility parent = sa.getParentTargetingCard();
if (parent != null) { if (parent != null) {
cards.addAll(parent.getTarget().getTargetCards()); Iterables.addAll(cards, parent.getTargets().getTargetCards());
} }
} else if (defined.startsWith("Triggered") && (sa != null)) { } else if (defined.startsWith("Triggered") && (sa != null)) {
@@ -445,17 +447,17 @@ public class AbilityUtils {
final ArrayList<Player> players = new ArrayList<Player>(); final ArrayList<Player> players = new ArrayList<Player>();
final SpellAbility saTargeting = ability.getSATargetingPlayer(); final SpellAbility saTargeting = ability.getSATargetingPlayer();
if (null != saTargeting) { if (null != saTargeting) {
players.addAll(saTargeting.getTarget().getTargetPlayers()); Iterables.addAll(players, saTargeting.getTargets().getTargetPlayers());
} }
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier; return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
} }
if (calcX[0].startsWith("TargetedObjects")) { if (calcX[0].startsWith("TargetedObjects")) {
final ArrayList<Object> objects = new ArrayList<Object>(); final List<ITargetable> objects = new ArrayList<ITargetable>();
// Make list of all targeted objects starting with the root SpellAbility // Make list of all targeted objects starting with the root SpellAbility
SpellAbility loopSA = ability.getRootAbility(); SpellAbility loopSA = ability.getRootAbility();
while (loopSA != null) { while (loopSA != null) {
if (loopSA.getTarget() != null) { if (loopSA.getTargetRestrictions() != null) {
objects.addAll(loopSA.getTarget().getTargets()); Iterables.addAll(objects, loopSA.getTargets().getTargets());
} }
loopSA = loopSA.getSubAbility(); loopSA = loopSA.getSubAbility();
} }
@@ -702,7 +704,7 @@ public class AbilityUtils {
if (defined.equals("Targeted")) { if (defined.equals("Targeted")) {
final SpellAbility saTargeting = sa.getSATargetingPlayer(); final SpellAbility saTargeting = sa.getSATargetingPlayer();
if (saTargeting != null) { if (saTargeting != null) {
players.addAll(saTargeting.getTarget().getTargetPlayers()); Iterables.addAll(players, saTargeting.getTargets().getTargetPlayers());
} }
} else if (defined.equals("TargetedController")) { } else if (defined.equals("TargetedController")) {
final List<Card> list = getDefinedCards(card, "Targeted", sa); final List<Card> list = getDefinedCards(card, "Targeted", sa);
@@ -732,7 +734,7 @@ public class AbilityUtils {
} else if (defined.equals("TargetedAndYou")) { } else if (defined.equals("TargetedAndYou")) {
final SpellAbility saTargeting = sa.getSATargetingPlayer(); final SpellAbility saTargeting = sa.getSATargetingPlayer();
if (saTargeting != null) { if (saTargeting != null) {
players.addAll(saTargeting.getTarget().getTargetPlayers()); Iterables.addAll(players, saTargeting.getTargets().getTargetPlayers());
players.add(sa.getActivatingPlayer()); players.add(sa.getActivatingPlayer());
} }
} else if (defined.equals("Remembered")) { } else if (defined.equals("Remembered")) {
@@ -959,7 +961,7 @@ public class AbilityUtils {
} else if (defined.equals("Targeted")) { } else if (defined.equals("Targeted")) {
final SpellAbility saTargeting = sa.getSATargetingSA(); final SpellAbility saTargeting = sa.getSATargetingSA();
if (saTargeting != null) { if (saTargeting != null) {
sas.addAll(saTargeting.getTarget().getTargetSAs()); Iterables.addAll(sas, saTargeting.getTargets().getTargetSpells());
} }
} else if (defined.startsWith("Triggered")) { } else if (defined.startsWith("Triggered")) {
final SpellAbility root = sa.getRootAbility(); final SpellAbility root = sa.getRootAbility();
@@ -1103,7 +1105,7 @@ public class AbilityUtils {
boolean paid = false; boolean paid = false;
for (Player payer : payers) { 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); ability.setActivatingPlayer(payer);
if (payer.isComputer()) { if (payer.isComputer()) {
if (ComputerUtilCost.willPayUnlessCost(sa, payer, cost, paid, payers) && ComputerUtilCost.canPayCost(ability, payer)) { 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) { public static void handleRemembering(final SpellAbility sa) {
Card host = sa.getSourceCard(); Card host = sa.getSourceCard();
if (sa.hasParam("RememberTargets") && sa.getTarget() != null) { if (sa.hasParam("RememberTargets") && sa.getTargetRestrictions() != null) {
if (sa.hasParam("ForgetOtherTargets")) { if (sa.hasParam("ForgetOtherTargets")) {
host.clearRemembered(); host.clearRemembered();
} }
for (final Object o : sa.getTarget().getTargets()) { for (final ITargetable o : sa.getTargets().getTargets()) {
host.addRemembered(o); host.addRemembered(o);
} }
} }

View File

@@ -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<Card> getTargetCards(SpellAbility sa) { return getCards(false, "Defined", sa); }
protected List<Card> getTargetCards(SpellAbility sa, String definedParam) { return getCards(false, definedParam, sa); }
protected List<Card> getDefinedCardsOrTargeted(SpellAbility sa, String definedParam) { return getCards(true, definedParam, sa); }
private List<Card> 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<Player> getTargetPlayers(SpellAbility sa) { return getPlayers(false, "Defined", sa); }
protected List<Player> getTargetPlayers(SpellAbility sa, String definedParam) { return getPlayers(false, definedParam, sa); }
protected List<Player> getDefinedPlayersOrTargeted(SpellAbility sa ) { return getPlayers(true, "Defined", sa); }
protected List<Player> getDefinedPlayersOrTargeted(SpellAbility sa, String definedParam) { return getPlayers(true, definedParam, sa); }
private List<Player> 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<SpellAbility> getTargetSpells(SpellAbility sa) { return getSpells(false, "Defined", sa); }
protected List<SpellAbility> getTargetSpells(SpellAbility sa, String definedParam) { return getSpells(false, definedParam, sa); }
protected List<SpellAbility> getDefinedSpellsOrTargeted(SpellAbility sa, String definedParam) { return getSpells(true, definedParam, sa); }
private List<SpellAbility> 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<ITargetable> getTargets(SpellAbility sa) { return getTargetables(false, "Defined", sa); }
protected List<ITargetable> getTargets(SpellAbility sa, String definedParam) { return getTargetables(false, definedParam, sa); }
protected List<ITargetable> getDefinedOrTargeteded(SpellAbility sa, String definedParam) { return getTargetables(true, definedParam, sa); }
private List<ITargetable> 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);
}
}

View File

@@ -12,7 +12,7 @@ import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode; 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) { public final boolean canPlayAIWithSubs(final Player aiPlayer, final SpellAbility sa) {
if (!canPlayAI(aiPlayer, sa)) { if (!canPlayAI(aiPlayer, sa)) {

View File

@@ -1,20 +1,15 @@
package forge.card.ability; package forge.card.ability;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import forge.Card;
import forge.ITargetable;
import forge.card.cardfactory.CardFactoryUtil; import forge.card.cardfactory.CardFactoryUtil;
import forge.card.spellability.AbilitySub; import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.game.player.Player;
/** /**
* <p> * <p>
@@ -25,7 +20,7 @@ import forge.game.player.Player;
* @version $Id: AbilityFactoryAlterLife.java 17656 2012-10-22 19:32:56Z Max mtg $ * @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); public abstract void resolve(final SpellAbility sa);
@@ -123,49 +118,4 @@ import forge.game.player.Player;
} }
} }
} }
protected List<Card> getTargetCards(SpellAbility sa) {
final Target tgt = sa.getTarget();
return tgt != null ? tgt.getTargetCards() : AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa);
}
protected List<Player> getTargetPlayers(SpellAbility sa) {
return getTargetPlayers(sa, false, true);
}
protected List<Player> getTargetPlayersEmptyAsDefault(SpellAbility sa) {
return getTargetPlayers(sa, true, true);
}
protected List<Player> 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<Player> emptyPlayerList = Collections.unmodifiableList(new ArrayList<Player>());
private List<Player> 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<SpellAbility> getTargetSpellAbilities(SpellAbility sa) {
final Target tgt = sa.getTarget();
return tgt != null ? tgt.getTargetSAs() : AbilityUtils.getDefinedSpellAbilities(sa.getSourceCard(), sa.getParam("Defined"), sa);
}
protected List<ITargetable> getTargetObjects(SpellAbility sa) {
final Target tgt = sa.getTarget();
return tgt != null ? tgt.getTargets() : AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam("Defined"), sa);
}
} }

View File

@@ -10,16 +10,16 @@ import forge.card.ability.effects.ManaReflectedEffect;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.AbilityManaPart; import forge.card.spellability.AbilityManaPart;
import forge.card.spellability.Spell; import forge.card.spellability.Spell;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
public class SpellApiBased extends Spell { public class SpellApiBased extends Spell {
private static final long serialVersionUID = -6741797239508483250L; private static final long serialVersionUID = -6741797239508483250L;
private final SpellAbilityEffect effect; private final SpellAbilityEffect effect;
private final SpellAbilityAi ai; private final SpellAbilityAi ai;
public SpellApiBased(ApiType api0, Card sourceCard, Cost abCost, Target tgt, Map<String, String> params0) { public SpellApiBased(ApiType api0, Card sourceCard, Cost abCost, TargetRestrictions tgt, Map<String, String> params0) {
super(sourceCard, abCost); super(sourceCard, abCost);
this.setTarget(tgt); this.setTargetRestrictions(tgt);
params = params0; params = params0;
api = api0; api = api0;

View File

@@ -22,7 +22,6 @@ import java.util.List;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.game.player.Player; import forge.game.player.Player;
/** /**
@@ -39,21 +38,20 @@ public class AddTurnAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
final Player opp = ai.getWeakestOpponent(); final Player opp = ai.getWeakestOpponent();
final Target tgt = sa.getTarget();
if (sa.getTarget() != null) { if (sa.usesTargeting()) {
tgt.resetTargets(); sa.resetTargets();
if (sa.canTarget(ai)) { if (sa.canTarget(ai)) {
sa.getTarget().addTarget(ai); sa.getTargets().add(ai);
} else if (mandatory) { } else if (mandatory) {
for (final Player ally : ai.getAllies()) { for (final Player ally : ai.getAllies()) {
if (sa.canTarget(ally)) { if (sa.canTarget(ally)) {
sa.getTarget().addTarget(ally); sa.getTargets().add(ally);
break; break;
} }
} }
if (!sa.getTarget().isMinTargetsChosen(sa.getSourceCard(), sa) && sa.canTarget(opp)) { if (!sa.getTargetRestrictions().isMinTargetsChosen(sa.getSourceCard(), sa) && sa.canTarget(opp)) {
sa.getTarget().addTarget(opp); sa.getTargets().add(opp);
} else { } else {
return false; return false;
} }

View File

@@ -9,7 +9,7 @@ import forge.CardPredicates;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
@@ -31,7 +31,7 @@ public class AnimateAi extends SpellAbilityAi {
*/ */
@Override @Override
protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) { protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Game game = aiPlayer.getGame(); final Game game = aiPlayer.getGame();
@@ -112,7 +112,7 @@ public class AnimateAi extends SpellAbilityAi {
return false; return false;
} }
} else { } else {
tgt.resetTargets(); sa.resetTargets();
if (!animateTgtAI(sa)) { if (!animateTgtAI(sa)) {
return false; return false;
} }
@@ -125,8 +125,8 @@ public class AnimateAi extends SpellAbilityAi {
@Override @Override
public boolean chkAIDrawback(SpellAbility sa, Player aiPlayer) { public boolean chkAIDrawback(SpellAbility sa, Player aiPlayer) {
if (sa.getTarget() != null) { if (sa.usesTargeting()) {
sa.getTarget().resetTargets(); sa.resetTargets();
if (!animateTgtAI(sa)) { if (!animateTgtAI(sa)) {
return false; return false;
} }
@@ -151,7 +151,7 @@ public class AnimateAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player aiPlayer, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player aiPlayer, SpellAbility sa, boolean mandatory) {
if (sa.getTarget() != null && !animateTgtAI(sa) && !mandatory) { if (sa.usesTargeting() && !animateTgtAI(sa) && !mandatory) {
return false; return false;
} }

View File

@@ -21,7 +21,7 @@ import forge.card.ability.SpellAbilityAi;
import forge.card.cardfactory.CardFactoryUtil; import forge.card.cardfactory.CardFactoryUtil;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.card.staticability.StaticAbility; import forge.card.staticability.StaticAbility;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
@@ -60,9 +60,9 @@ public class AttachAi extends SpellAbilityAi {
final boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn()); final boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());
// Attach spells always have a target // Attach spells always have a target
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
if (!attachPreference(sa, tgt, false)) { if (!attachPreference(sa, tgt, false)) {
return false; return false;
} }
@@ -455,7 +455,7 @@ public class AttachAi extends SpellAbilityAi {
final Card attachSource) { final Card attachSource) {
// AI For choosing a Card to Gain Control of. // 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, // If can target all Permanents, and Life isn't in eminent danger,
// grab Planeswalker first, then Creature // grab Planeswalker first, then Creature
// if Life < 5 grab Creature first, then Planeswalker. Lands, // if Life < 5 grab Creature first, then Planeswalker. Lands,
@@ -613,7 +613,7 @@ public class AttachAi extends SpellAbilityAi {
final Card card = sa.getSourceCard(); final Card card = sa.getSourceCard();
// Check if there are any valid targets // Check if there are any valid targets
List<ITargetable> targets = new ArrayList<ITargetable>(); List<ITargetable> targets = new ArrayList<ITargetable>();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt == null) { if (tgt == null) {
targets = AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam("Defined"), sa); targets = AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam("Defined"), sa);
} else { } else {
@@ -678,8 +678,8 @@ public class AttachAi extends SpellAbilityAi {
* the mandatory * the mandatory
* @return true, if successful * @return true, if successful
*/ */
private static boolean attachPreference(final SpellAbility sa, final Target tgt, final boolean mandatory) { private static boolean attachPreference(final SpellAbility sa, final TargetRestrictions tgt, final boolean mandatory) {
Object o; ITargetable o;
if (tgt.canTgtPlayer()) { if (tgt.canTgtPlayer()) {
o = attachToPlayerAIPreferences(sa.getActivatingPlayer(), sa, mandatory); o = attachToPlayerAIPreferences(sa.getActivatingPlayer(), sa, mandatory);
} else { } else {
@@ -690,7 +690,7 @@ public class AttachAi extends SpellAbilityAi {
return false; return false;
} }
tgt.addTarget(o); sa.getTargets().add(o);
return true; return true;
} }
@@ -866,7 +866,7 @@ public class AttachAi extends SpellAbilityAi {
* @return the card * @return the card
*/ */
private static Card attachToCardAIPreferences(final Player aiPlayer, final SpellAbility sa, final boolean mandatory) { 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(); final Card attachSource = sa.getSourceCard();
// TODO AttachSource is currently set for the Source of the Spell, but // TODO AttachSource is currently set for the Source of the Spell, but
// at some point can support attaching a different card // at some point can support attaching a different card

View File

@@ -7,7 +7,7 @@ import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
@@ -19,7 +19,7 @@ public class BecomesBlockedAi extends SpellAbilityAi {
@Override @Override
protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) { protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) {
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Game game = aiPlayer.getGame(); final Game game = aiPlayer.getGame();
if (!game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS) if (!game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)
@@ -33,7 +33,7 @@ public class BecomesBlockedAi extends SpellAbilityAi {
list = CardLists.getTargetableCards(list, sa); list = CardLists.getTargetableCards(list, sa);
list = CardLists.getNotKeyword(list, "Trample"); list = CardLists.getNotKeyword(list, "Trample");
while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) {
Card choice = null; Card choice = null;
if (list.isEmpty()) { if (list.isEmpty()) {
@@ -47,7 +47,7 @@ public class BecomesBlockedAi extends SpellAbilityAi {
} }
list.remove(choice); list.remove(choice);
tgt.addTarget(choice); sa.getTargets().add(choice);
} }
return true; return true;
} }

View File

@@ -8,6 +8,7 @@ import java.util.Random;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import forge.Card; import forge.Card;
import forge.CardCharacteristicName; import forge.CardCharacteristicName;
@@ -16,6 +17,7 @@ import forge.CardPredicates;
import forge.CardPredicates.Presets; import forge.CardPredicates.Presets;
import forge.Constant; import forge.Constant;
import forge.GameEntity; import forge.GameEntity;
import forge.ITargetable;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.ApiType; import forge.card.ability.ApiType;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
@@ -25,7 +27,7 @@ import forge.card.cost.CostDiscard;
import forge.card.cost.CostPart; import forge.card.cost.CostPart;
import forge.card.spellability.AbilitySub; import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.card.trigger.TriggerType; import forge.card.trigger.TriggerType;
import forge.game.Game; import forge.game.Game;
import forge.game.GlobalRuleChange; import forge.game.GlobalRuleChange;
@@ -228,17 +230,16 @@ public class ChangeZoneAi extends SpellAbilityAi {
// prevent run-away activations - first time will always return true // prevent run-away activations - first time will always return true
boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn()); boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());
List<Player> pDefined = new ArrayList<Player>(); Iterable<Player> pDefined = Lists.newArrayList(source.getController());
pDefined.add(source.getController()); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Target tgt = sa.getTarget();
if ((tgt != null) && tgt.canTgtPlayer()) { if ((tgt != null) && tgt.canTgtPlayer()) {
boolean isCurse = sa.isCurse(); boolean isCurse = sa.isCurse();
if (isCurse && sa.canTarget(opponent)) { if (isCurse && sa.canTarget(opponent)) {
tgt.addTarget(opponent); sa.getTargets().add(opponent);
} else if (!isCurse && sa.canTarget(ai)) { } else if (!isCurse && sa.canTarget(ai)) {
tgt.addTarget(ai); sa.getTargets().add(ai);
} }
pDefined = tgt.getTargetPlayers(); pDefined = sa.getTargets().getTargetPlayers();
} else { } else {
if (sa.hasParam("DefinedPlayer")) { if (sa.hasParam("DefinedPlayer")) {
pDefined = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("DefinedPlayer"), sa); 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) { private static boolean hiddenOriginPlayDrawbackAI(final Player aiPlayer, final SpellAbility sa) {
// if putting cards from hand to library and parent is drawing cards // if putting cards from hand to library and parent is drawing cards
// make sure this will actually do something: // make sure this will actually do something:
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Player opp = aiPlayer.getOpponent(); final Player opp = aiPlayer.getOpponent();
if ((tgt != null) && tgt.canTgtPlayer()) { if ((tgt != null) && tgt.canTgtPlayer()) {
boolean isCurse = sa.isCurse(); boolean isCurse = sa.isCurse();
if (isCurse && sa.canTarget(opp)) { if (isCurse && sa.canTarget(opp)) {
tgt.addTarget(opp); sa.getTargets().add(opp);
} else if (!isCurse && sa.canTarget(aiPlayer)) { } else if (!isCurse && sa.canTarget(aiPlayer)) {
tgt.addTarget(aiPlayer); sa.getTargets().add(aiPlayer);
} else { } else {
return false; return false;
} }
@@ -372,32 +373,32 @@ public class ChangeZoneAi extends SpellAbilityAi {
source.setSVar("PayX", Integer.toString(xPay)); source.setSVar("PayX", Integer.toString(xPay));
} }
List<Player> pDefined; Iterable<Player> pDefined;
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if ((tgt != null) && tgt.canTgtPlayer()) { if ((tgt != null) && tgt.canTgtPlayer()) {
final Player opp = ai.getOpponent(); final Player opp = ai.getOpponent();
if (sa.isCurse()) { if (sa.isCurse()) {
if (sa.canTarget(opp)) { if (sa.canTarget(opp)) {
tgt.addTarget(opp); sa.getTargets().add(opp);
} else if (mandatory && sa.canTarget(ai)) { } else if (mandatory && sa.canTarget(ai)) {
tgt.addTarget(ai); sa.getTargets().add(ai);
} }
} else { } else {
if (sa.canTarget(ai)) { if (sa.canTarget(ai)) {
tgt.addTarget(ai); sa.getTargets().add(ai);
} else if (mandatory && sa.canTarget(opp)) { } 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; return false;
} }
if (mandatory) { if (mandatory) {
return pDefined.size() > 0; return true;
} }
} else { } else {
if (mandatory) { if (mandatory) {
@@ -571,7 +572,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
// prevent run-away activations - first time will always return true // prevent run-away activations - first time will always return true
boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getRestrictions().getNumberTurnActivations()); boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getRestrictions().getNumberTurnActivations());
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
if (!isPreferredTarget(ai, sa, false)) { if (!isPreferredTarget(ai, sa, false)) {
return false; return false;
@@ -609,7 +610,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
return false; return false;
} }
final ArrayList<Object> objects = ComputerUtil.predictThreatenedObjects(ai, sa); final List<ITargetable> objects = ComputerUtil.predictThreatenedObjects(ai, sa);
boolean contains = false; boolean contains = false;
for (final Card c : retrieval) { for (final Card c : retrieval) {
if (objects.contains(c)) { if (objects.contains(c)) {
@@ -664,7 +665,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
* @return a boolean. * @return a boolean.
*/ */
private static boolean knownOriginPlayDrawbackAI(final Player aiPlayer, final SpellAbility sa) { private static boolean knownOriginPlayDrawbackAI(final Player aiPlayer, final SpellAbility sa) {
if (sa.getTarget() == null) { if (sa.getTargetRestrictions() == null) {
return true; return true;
} }
@@ -688,7 +689,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final ZoneType origin = ZoneType.listValueOf(sa.getParam("Origin")).get(0); final ZoneType origin = ZoneType.listValueOf(sa.getParam("Origin")).get(0);
final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination")); final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination"));
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final AbilitySub abSub = sa.getSubAbility(); final AbilitySub abSub = sa.getSubAbility();
ApiType subApi = null; ApiType subApi = null;
@@ -700,7 +701,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
} }
} }
tgt.resetTargets(); sa.resetTargets();
List<Card> list = CardLists.getValidCards(ai.getGame().getCardsIn(origin), tgt.getValidTgts(), ai, source); List<Card> list = CardLists.getValidCards(ai.getGame().getCardsIn(origin), tgt.getValidTgts(), ai, source);
list = CardLists.getTargetableCards(list, sa); list = CardLists.getTargetableCards(list, sa);
if (sa.hasParam("AITgts")) { if (sa.hasParam("AITgts")) {
@@ -730,7 +731,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
// check stack for something on the stack that will kill // check stack for something on the stack that will kill
// anything i control // anything i control
if (!ai.getGame().getStack().isEmpty()) { if (!ai.getGame().getStack().isEmpty()) {
final ArrayList<Object> objects = ComputerUtil.predictThreatenedObjects(ai, sa); final List<ITargetable> objects = ComputerUtil.predictThreatenedObjects(ai, sa);
final List<Card> threatenedTargets = new ArrayList<Card>(); final List<Card> threatenedTargets = new ArrayList<Card>();
@@ -742,7 +743,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
if (!threatenedTargets.isEmpty()) { if (!threatenedTargets.isEmpty()) {
// Choose "best" of the remaining to save // Choose "best" of the remaining to save
tgt.addTarget(ComputerUtilCard.getBestAI(threatenedTargets)); sa.getTargets().add(ComputerUtilCard.getBestAI(threatenedTargets));
return true; return true;
} }
} }
@@ -753,7 +754,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
for (final Card c : combatants) { for (final Card c : combatants) {
if (c.getShield() == 0 && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c) && c.getOwner() == ai && !c.isToken()) { if (c.getShield() == 0 && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c) && c.getOwner() == ai && !c.isToken()) {
tgt.addTarget(c); sa.getTargets().add(c);
return true; return true;
} }
} }
@@ -789,7 +790,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
}); });
if (!aiPermanents.isEmpty()) { if (!aiPermanents.isEmpty()) {
// Choose "best" of the remaining to save // Choose "best" of the remaining to save
tgt.addTarget(ComputerUtilCard.getBestAI(aiPermanents)); sa.getTargets().add(ComputerUtilCard.getBestAI(aiPermanents));
return true; return true;
} }
}*/ }*/
@@ -860,7 +861,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
} }
// target loop // target loop
while (tgt.getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) { while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) {
// AI Targeting // AI Targeting
Card choice = null; Card choice = null;
@@ -909,9 +910,9 @@ public class ChangeZoneAi extends SpellAbilityAi {
} }
} }
if (choice == null) { // can't find anything left 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) { if (!mandatory) {
tgt.resetTargets(); sa.resetTargets();
} }
return false; return false;
} else { } else {
@@ -923,7 +924,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
} }
list.remove(choice); list.remove(choice);
tgt.addTarget(choice); sa.getTargets().add(choice);
} }
return true; return true;
@@ -951,7 +952,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final ZoneType origin = ZoneType.listValueOf(sa.getParam("Origin")).get(0); final ZoneType origin = ZoneType.listValueOf(sa.getParam("Origin")).get(0);
final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination")); final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination"));
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
List<Card> list = CardLists.getValidCards(ai.getGame().getCardsIn(origin), tgt.getValidTgts(), ai, source); List<Card> 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); list.remove(c);
} }
@@ -978,7 +979,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
} }
// target loop // target loop
while (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { while (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) {
// AI Targeting // AI Targeting
Card choice = null; Card choice = null;
@@ -1020,8 +1021,8 @@ public class ChangeZoneAi extends SpellAbilityAi {
} }
} }
if (choice == null) { // can't find anything left 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))) {
tgt.resetTargets(); sa.resetTargets();
return false; return false;
} else { } else {
if (!ComputerUtil.shouldCastLessThanMax(ai, source)) { if (!ComputerUtil.shouldCastLessThanMax(ai, source)) {
@@ -1032,7 +1033,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
} }
list.remove(choice); list.remove(choice);
tgt.addTarget(choice); sa.getTargets().add(choice);
} }
return true; return true;
@@ -1054,7 +1055,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
private static boolean knownOriginTriggerAI(final Player ai, final SpellAbility sa, private static boolean knownOriginTriggerAI(final Player ai, final SpellAbility sa,
final boolean mandatory) { final boolean mandatory) {
if (sa.getTarget() == null) { if (sa.getTargetRestrictions() == null) {
// Just in case of Defined cases // Just in case of Defined cases
if (!mandatory && sa.hasParam("AttachedTo")) { if (!mandatory && sa.hasParam("AttachedTo")) {
final List<Card> list = AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("AttachedTo"), sa); final List<Card> 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. * a {@link forge.game.player.Player} object.
*/ */
public static void hiddenOriginResolveAI(final Player ai, final SpellAbility sa, Player player) { 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 Card card = sa.getSourceCard();
final boolean defined = sa.hasParam("Defined"); final boolean defined = sa.hasParam("Defined");
final Player activator = sa.getActivatingPlayer(); final Player activator = sa.getActivatingPlayer();
final Game game = ai.getGame(); final Game game = ai.getGame();
if (tgt != null) { if (tgt != null) {
if (!tgt.getTargetPlayers().isEmpty()) { if (sa.getTargets().isTargetingAnyPlayer()) {
player = sa.hasParam("DefinedPlayer") ? player : tgt.getTargetPlayers().get(0); player = sa.hasParam("DefinedPlayer") ? player : sa.getTargets().getFirstTargetedPlayer();
if (!player.canBeTargetedBy(sa)) { if (!player.canBeTargetedBy(sa)) {
return; return;
} }
@@ -1342,7 +1343,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
// Auras without Candidates stay in their current location // Auras without Candidates stay in their current location
if (c.isAura()) { if (c.isAura()) {
final SpellAbility saAura = AttachEffect.getAttachSpellAbility(c); final SpellAbility saAura = AttachEffect.getAttachSpellAbility(c);
if (!saAura.getTarget().hasCandidates(saAura, false)) { if (!saAura.getTargetRestrictions().hasCandidates(saAura, false)) {
continue; continue;
} }
} }

View File

@@ -9,7 +9,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
@@ -57,7 +57,7 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
final List<Card> humanType = AbilityUtils.filterListByType(opp.getCardsIn(origin), sa.getParam("ChangeType"), sa); final List<Card> humanType = AbilityUtils.filterListByType(opp.getCardsIn(origin), sa.getParam("ChangeType"), sa);
List<Card> computerType = ai.getCardsIn(origin); List<Card> computerType = ai.getCardsIn(origin);
computerType = AbilityUtils.filterListByType(computerType, sa.getParam("ChangeType"), sa); 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 // TODO improve restrictions on when the AI would want to use this
// spBounceAll has some AI we can compare to. // spBounceAll has some AI we can compare to.
@@ -67,8 +67,8 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
|| !opp.canBeTargetedBy(sa)) { || !opp.canBeTargetedBy(sa)) {
return false; return false;
} }
tgt.resetTargets(); sa.resetTargets();
tgt.addTarget(opp); sa.getTargets().add(opp);
} }
} else if (origin.equals(ZoneType.Battlefield)) { } else if (origin.equals(ZoneType.Battlefield)) {
// this statement is assuming the AI is trying to use this spell // this statement is assuming the AI is trying to use this spell
@@ -82,8 +82,8 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
|| !opp.canBeTargetedBy(sa)) { || !opp.canBeTargetedBy(sa)) {
return false; return false;
} }
tgt.resetTargets(); sa.resetTargets();
tgt.addTarget(opp); sa.getTargets().add(opp);
computerType.clear(); computerType.clear();
} }
if ((CardLists.getNotType(humanType, "Creature").size() == 0) && (CardLists.getNotType(computerType, "Creature").size() == 0)) { 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)) { || !opp.canBeTargetedBy(sa)) {
return false; return false;
} }
tgt.resetTargets(); sa.resetTargets();
tgt.addTarget(opp); sa.getTargets().add(opp);
} }
} else if (origin.equals(ZoneType.Exile)) { } 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 // TODO improve restrictions on when the AI would want to use this
// spBounceAll has some AI we can compare to. // spBounceAll has some AI we can compare to.
if (origin.equals(ZoneType.Hand) || origin.equals(ZoneType.Library)) { if (origin.equals(ZoneType.Hand) || origin.equals(ZoneType.Library)) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
if (opp.getCardsIn(ZoneType.Hand).isEmpty() if (opp.getCardsIn(ZoneType.Hand).isEmpty()
|| !opp.canBeTargetedBy(sa)) { || !opp.canBeTargetedBy(sa)) {
return false; return false;
} }
tgt.resetTargets(); sa.resetTargets();
tgt.addTarget(opp); sa.getTargets().add(opp);
} }
} else if (origin.equals(ZoneType.Battlefield)) { } else if (origin.equals(ZoneType.Battlefield)) {
// this statement is assuming the AI is trying to use this spell offensively // this statement is assuming the AI is trying to use this spell offensively
@@ -215,14 +215,14 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
return false; return false;
} }
} else if (origin.equals(ZoneType.Graveyard)) { } else if (origin.equals(ZoneType.Graveyard)) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
if (opp.getCardsIn(ZoneType.Graveyard).isEmpty() if (opp.getCardsIn(ZoneType.Graveyard).isEmpty()
|| !opp.canBeTargetedBy(sa)) { || !opp.canBeTargetedBy(sa)) {
return false; return false;
} }
tgt.resetTargets(); sa.resetTargets();
tgt.addTarget(opp); sa.getTargets().add(opp);
} }
} else if (origin.equals(ZoneType.Exile)) { } else if (origin.equals(ZoneType.Exile)) {

View File

@@ -9,7 +9,7 @@ import forge.CardLists;
import forge.CardPredicates.Presets; import forge.CardPredicates.Presets;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCombat; import forge.game.ai.ComputerUtilCombat;
@@ -27,11 +27,11 @@ public class ChooseCardAi extends SpellAbilityAi {
final Card host = sa.getSourceCard(); final Card host = sa.getSourceCard();
final Game game = ai.getGame(); final Game game = ai.getGame();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
if (sa.canTarget(ai.getOpponent())) { if (sa.canTarget(ai.getOpponent())) {
tgt.addTarget(ai.getOpponent()); sa.getTargets().add(ai.getOpponent());
} else { } else {
return false; return false;
} }

View File

@@ -3,7 +3,7 @@ package forge.card.ability.ai;
import forge.Card; import forge.Card;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilMana; import forge.game.ai.ComputerUtilMana;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
@@ -40,13 +40,13 @@ public class ChooseCardNameAi extends SpellAbilityAi {
source.setSVar("PayX", Integer.toString(tokenSize)); source.setSVar("PayX", Integer.toString(tokenSize));
} }
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
if (tgt.canOnlyTgtOpponent()) { if (tgt.canOnlyTgtOpponent()) {
tgt.addTarget(ai.getOpponent()); sa.getTargets().add(ai.getOpponent());
} else { } else {
tgt.addTarget(ai); sa.getTargets().add(ai);
} }
} }
return true; return true;

View File

@@ -1,6 +1,5 @@
package forge.card.ability.ai; package forge.card.ability.ai;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
@@ -13,7 +12,7 @@ import forge.card.ability.ApiType;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtilCombat; import forge.game.ai.ComputerUtilCombat;
import forge.game.ai.ComputerUtilCost; 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) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
if (sa.canTarget(ai.getOpponent())) { if (sa.canTarget(ai.getOpponent())) {
tgt.addTarget(ai.getOpponent()); sa.getTargets().add(ai.getOpponent());
} else { } else {
return false; return false;
} }
@@ -79,18 +78,12 @@ public class ChooseSourceAi extends SpellAbilityAi {
} }
final Card threatSource = topStack.getSourceCard(); final Card threatSource = topStack.getSourceCard();
List<? extends ITargetable> objects = new ArrayList<ITargetable>(); List<? extends ITargetable> objects = getTargets(sa);
final Target threatTgt = topStack.getTarget();
if (threatTgt == null) { if (!topStack.usesTargeting() && topStack.hasParam("ValidPlayers") && !topStack.hasParam("Defined")) {
if (topStack.hasParam("Defined")) { objects = AbilityUtils.getDefinedPlayers(threatSource, topStack.getParam("ValidPlayers"), topStack);
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 (!objects.contains(ai) || topStack.hasParam("NoPrevention")) { if (!objects.contains(ai) || topStack.hasParam("NoPrevention")) {
return false; return false;
} }

View File

@@ -3,7 +3,6 @@ package forge.card.ability.ai;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.game.player.Player; import forge.game.player.Player;
public class ChooseTypeAi extends SpellAbilityAi { public class ChooseTypeAi extends SpellAbilityAi {
@@ -18,11 +17,9 @@ public class ChooseTypeAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
final Target tgt = sa.getTarget(); if (sa.usesTargeting()) {
sa.resetTargets();
if (sa.getTarget() != null) { sa.getTargets().add(ai);
tgt.resetTargets();
sa.getTarget().addTarget(ai);
} else { } else {
for (final Player p : AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa)) { for (final Player p : AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa)) {
if (p.isOpponentOf(ai) && !mandatory) { if (p.isOpponentOf(ai) && !mandatory) {

View File

@@ -3,7 +3,7 @@ package forge.card.ability.ai;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player; import forge.game.player.Player;
public class ClashAi extends SpellAbilityAi { public class ClashAi extends SpellAbilityAi {
@@ -21,14 +21,14 @@ public class ClashAi extends SpellAbilityAi {
*/ */
@Override @Override
protected boolean canPlayAI(Player ai, SpellAbility sa) { protected boolean canPlayAI(Player ai, SpellAbility sa) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Player opp = ai.getOpponent(); final Player opp = ai.getOpponent();
if (tgt != null) { if (tgt != null) {
if (!opp.canBeTargetedBy(sa)) { if (!opp.canBeTargetedBy(sa)) {
return false; return false;
} }
tgt.resetTargets(); sa.resetTargets();
tgt.addTarget(opp); sa.getTargets().add(opp);
} }
return true; return true;
} }

View File

@@ -6,7 +6,7 @@ import forge.Card;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
@@ -16,7 +16,7 @@ public class CloneAi extends SpellAbilityAi {
@Override @Override
protected boolean canPlayAI(Player ai, SpellAbility sa) { protected boolean canPlayAI(Player ai, SpellAbility sa) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Game game = source.getGame(); final Game game = source.getGame();
@@ -85,7 +85,7 @@ public class CloneAi extends SpellAbilityAi {
return false; return false;
} }
} else { } else {
tgt.resetTargets(); sa.resetTargets();
useAbility &= cloneTgtAI(sa); useAbility &= cloneTgtAI(sa);
} }
@@ -97,7 +97,7 @@ public class CloneAi extends SpellAbilityAi {
// AI should only activate this during Human's turn // AI should only activate this during Human's turn
boolean chance = true; boolean chance = true;
if (sa.getTarget() != null) { if (sa.usesTargeting()) {
chance = cloneTgtAI(sa); chance = cloneTgtAI(sa);
} }
@@ -110,7 +110,7 @@ public class CloneAi extends SpellAbilityAi {
boolean chance = true; boolean chance = true;
if (sa.getTarget() != null) { if (sa.usesTargeting()) {
chance = cloneTgtAI(sa); chance = cloneTgtAI(sa);
} }

View File

@@ -10,7 +10,7 @@ import forge.CardLists;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -25,8 +25,8 @@ public class ControlExchangeAi extends SpellAbilityAi {
protected boolean canPlayAI(Player ai, final SpellAbility sa) { protected boolean canPlayAI(Player ai, final SpellAbility sa) {
Card object1 = null; Card object1 = null;
Card object2 = null; Card object2 = null;
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
tgt.resetTargets(); sa.resetTargets();
List<Card> list = List<Card> list =
CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, sa.getSourceCard()); CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, sa.getSourceCard());
@@ -46,13 +46,13 @@ public class ControlExchangeAi extends SpellAbilityAi {
List<Card> list2 = ai.getCardsIn(ZoneType.Battlefield); List<Card> list2 = ai.getCardsIn(ZoneType.Battlefield);
list2 = CardLists.getValidCards(list2, tgt.getValidTgts(), ai, sa.getSourceCard()); list2 = CardLists.getValidCards(list2, tgt.getValidTgts(), ai, sa.getSourceCard());
object2 = ComputerUtilCard.getWorstAI(list2); object2 = ComputerUtilCard.getWorstAI(list2);
tgt.addTarget(object2); sa.getTargets().add(object2);
} }
if (object1 == null || object2 == null) { if (object1 == null || object2 == null) {
return false; return false;
} }
if (ComputerUtilCard.evaluateCreature(object1) > ComputerUtilCard.evaluateCreature(object2) + 40) { 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 MyRandom.getRandom().nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());
} }
return false; return false;

View File

@@ -28,7 +28,7 @@ import forge.CardLists;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.phase.CombatUtil; import forge.game.phase.CombatUtil;
@@ -70,7 +70,7 @@ public class ControlGainAi extends SpellAbilityAi {
final List<String> lose = sa.hasParam("LoseControl") ? Arrays.asList(sa.getParam("LoseControl").split(",")) : null; final List<String> 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(); Player opp = ai.getOpponent();
// if Defined, then don't worry about targeting // if Defined, then don't worry about targeting
@@ -84,12 +84,12 @@ public class ControlGainAi extends SpellAbilityAi {
} }
return true; return true;
} else { } else {
tgt.resetTargets(); sa.resetTargets();
if (tgt.canOnlyTgtOpponent()) { if (tgt.canOnlyTgtOpponent()) {
if (!opp.canBeTargetedBy(sa)) { if (!opp.canBeTargetedBy(sa)) {
return false; return false;
} }
tgt.addTarget(opp); sa.getTargets().add(opp);
} }
} }
@@ -116,7 +116,7 @@ public class ControlGainAi extends SpellAbilityAi {
return false; return false;
} }
while (tgt.getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) { while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) {
Card t = null; Card t = null;
for (final Card c : list) { for (final Card c : list) {
if (c.isCreature()) { if (c.isCreature()) {
@@ -134,8 +134,8 @@ public class ControlGainAi extends SpellAbilityAi {
} }
if (list.isEmpty()) { 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)) {
tgt.resetTargets(); sa.resetTargets();
return false; return false;
} else { } else {
// TODO is this good enough? for up to amounts? // TODO is this good enough? for up to amounts?
@@ -155,7 +155,7 @@ public class ControlGainAi extends SpellAbilityAi {
t = ComputerUtilCard.getMostExpensivePermanentAI(list, sa, true); t = ComputerUtilCard.getMostExpensivePermanentAI(list, sa, true);
} }
tgt.addTarget(t); sa.getTargets().add(t);
list.remove(t); list.remove(t);
hasCreature = false; hasCreature = false;
@@ -170,7 +170,7 @@ public class ControlGainAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
if (sa.getTarget() == null) { if (sa.getTargetRestrictions() == null) {
if (mandatory) { if (mandatory) {
return true; return true;
} }
@@ -184,7 +184,7 @@ public class ControlGainAi extends SpellAbilityAi {
@Override @Override
public boolean chkAIDrawback(SpellAbility sa, final Player ai) { public boolean chkAIDrawback(SpellAbility sa, final Player ai) {
final Game game = ai.getGame(); final Game game = ai.getGame();
if ((sa.getTarget() == null) || !sa.getTarget().doesTarget()) { if ((sa.getTargetRestrictions() == null) || !sa.getTargetRestrictions().doesTarget()) {
if (sa.hasParam("AllValid")) { if (sa.hasParam("AllValid")) {
List<Card> tgtCards = CardLists.filterControlledBy(game.getCardsIn(ZoneType.Battlefield), ai.getOpponent()); List<Card> tgtCards = CardLists.filterControlledBy(game.getCardsIn(ZoneType.Battlefield), ai.getOpponent());
tgtCards = AbilityUtils.filterListByType(tgtCards, sa.getParam("AllValid"), sa); tgtCards = AbilityUtils.filterListByType(tgtCards, sa.getParam("AllValid"), sa);

View File

@@ -11,7 +11,7 @@ import forge.CardLists;
import forge.CardPredicates.Presets; import forge.CardPredicates.Presets;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
@@ -53,7 +53,7 @@ public class CopyPermanentAi extends SpellAbilityAi {
// //// // ////
// Targeting // Targeting
final Target abTgt = sa.getTarget(); final TargetRestrictions abTgt = sa.getTargetRestrictions();
if (abTgt != null) { if (abTgt != null) {
List<Card> list = aiPlayer.getGame().getCardsIn(ZoneType.Battlefield); List<Card> list = aiPlayer.getGame().getCardsIn(ZoneType.Battlefield);
@@ -66,13 +66,13 @@ public class CopyPermanentAi extends SpellAbilityAi {
return !vars.containsKey("RemAIDeck"); return !vars.containsKey("RemAIDeck");
} }
}); });
abTgt.resetTargets(); sa.resetTargets();
// target loop // target loop
while (abTgt.getNumTargeted() < abTgt.getMaxTargets(sa.getSourceCard(), sa)) { while (sa.getTargets().getNumTargeted() < abTgt.getMaxTargets(sa.getSourceCard(), sa)) {
if (list.isEmpty()) { if (list.isEmpty()) {
if ((abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) if ((sa.getTargets().getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa))
|| (abTgt.getNumTargeted() == 0)) { || (sa.getTargets().getNumTargeted() == 0)) {
abTgt.resetTargets(); sa.resetTargets();
return false; return false;
} else { } else {
// TODO is this good enough? for up to amounts? // 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 (choice == null) { // can't find anything left
if ((abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) if ((sa.getTargets().getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa))
|| (abTgt.getNumTargeted() == 0)) { || (sa.getTargets().getNumTargeted() == 0)) {
abTgt.resetTargets(); sa.resetTargets();
return false; return false;
} else { } else {
// TODO is this good enough? for up to amounts? // TODO is this good enough? for up to amounts?
@@ -104,7 +104,7 @@ public class CopyPermanentAi extends SpellAbilityAi {
} }
} }
list.remove(choice); list.remove(choice);
abTgt.addTarget(choice); sa.getTargets().add(choice);
} }
} else { } else {
// if no targeting, it should always be ok // if no targeting, it should always be ok

View File

@@ -6,7 +6,7 @@ import forge.card.ability.SpellAbilityAi;
import forge.card.cardfactory.CardFactoryUtil; import forge.card.cardfactory.CardFactoryUtil;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.ai.ComputerUtilMana; 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) { if (tgt != null) {
final SpellAbility topSA = game.getStack().peekAbility(); final SpellAbility topSA = game.getStack().peekAbility();
@@ -48,9 +48,9 @@ public class CounterAi extends SpellAbilityAi {
return false; return false;
} }
tgt.resetTargets(); sa.resetTargets();
if (sa.canTargetSpellAbility(topSA)) { if (sa.canTargetSpellAbility(topSA)) {
tgt.addTarget(topSA); sa.getTargets().add(topSA);
} else { } else {
return false; return false;
} }
@@ -108,7 +108,7 @@ public class CounterAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
final Game game = ai.getGame(); final Game game = ai.getGame();
if (game.getStack().isEmpty()) { if (game.getStack().isEmpty()) {
@@ -119,9 +119,9 @@ public class CounterAi extends SpellAbilityAi {
return false; return false;
} }
tgt.resetTargets(); sa.resetTargets();
if (sa.canTargetSpellAbility(topSA)) { if (sa.canTargetSpellAbility(topSA)) {
tgt.addTarget(topSA); sa.getTargets().add(topSA);
} else { } else {
return false; return false;
} }

View File

@@ -9,7 +9,7 @@ import forge.CounterType;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -48,7 +48,7 @@ public class CountersMoveAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
final Card host = sa.getSourceCard(); final Card host = sa.getSourceCard();
final Target abTgt = sa.getTarget(); final TargetRestrictions abTgt = sa.getTargetRestrictions();
final String type = sa.getParam("CounterType"); final String type = sa.getParam("CounterType");
final String amountStr = sa.getParam("CounterNum"); final String amountStr = sa.getParam("CounterNum");
int amount = 0; int amount = 0;
@@ -124,7 +124,7 @@ public class CountersMoveAi extends SpellAbilityAi {
// TODO - I think choice can be null here. Is that ok for // TODO - I think choice can be null here. Is that ok for
// addTarget()? // addTarget()?
abTgt.addTarget(choice); sa.getTargets().add(choice);
} }
return chance; return chance;

View File

@@ -13,7 +13,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
@@ -32,7 +32,7 @@ public class CountersPutAi extends SpellAbilityAi {
// what the expected targets could be // what the expected targets could be
final Random r = MyRandom.getRandom(); final Random r = MyRandom.getRandom();
final Cost abCost = sa.getPayCosts(); final Cost abCost = sa.getPayCosts();
final Target abTgt = sa.getTarget(); final TargetRestrictions abTgt = sa.getTargetRestrictions();
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
List<Card> list; List<Card> list;
Card choice = null; Card choice = null;
@@ -89,7 +89,7 @@ public class CountersPutAi extends SpellAbilityAi {
// Targeting // Targeting
if (abTgt != null) { if (abTgt != null) {
abTgt.resetTargets(); sa.resetTargets();
// target loop // target loop
list = CardLists.filter(player.getCardsIn(ZoneType.Battlefield), new Predicate<Card>() { list = CardLists.filter(player.getCardsIn(ZoneType.Battlefield), new Predicate<Card>() {
@@ -104,11 +104,11 @@ public class CountersPutAi extends SpellAbilityAi {
if (list.size() < abTgt.getMinTargets(source, sa)) { if (list.size() < abTgt.getMinTargets(source, sa)) {
return false; return false;
} }
while (abTgt.getNumTargeted() < abTgt.getMaxTargets(sa.getSourceCard(), sa)) { while (sa.getTargets().getNumTargeted() < abTgt.getMaxTargets(sa.getSourceCard(), sa)) {
if (list.isEmpty()) { if (list.isEmpty()) {
if ((abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) if ((sa.getTargets().getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa))
|| (abTgt.getNumTargeted() == 0)) { || (sa.getTargets().getNumTargeted() == 0)) {
abTgt.resetTargets(); sa.resetTargets();
return false; return false;
} else { } else {
// TODO is this good enough? for up to amounts? // 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 (choice == null) { // can't find anything left
if ((abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) if ((sa.getTargets().getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa))
|| (abTgt.getNumTargeted() == 0)) { || (sa.getTargets().getNumTargeted() == 0)) {
abTgt.resetTargets(); sa.resetTargets();
return false; return false;
} else { } else {
// TODO is this good enough? for up to amounts? // TODO is this good enough? for up to amounts?
@@ -134,7 +134,7 @@ public class CountersPutAi extends SpellAbilityAi {
} }
list.remove(choice); list.remove(choice);
abTgt.addTarget(choice); sa.getTargets().add(choice);
if (divided) { if (divided) {
abTgt.addDividedAllocation(choice, amount); abTgt.addDividedAllocation(choice, amount);
@@ -175,7 +175,7 @@ public class CountersPutAi extends SpellAbilityAi {
@Override @Override
public boolean chkAIDrawback(final SpellAbility sa, Player ai) { public boolean chkAIDrawback(final SpellAbility sa, Player ai) {
boolean chance = true; boolean chance = true;
final Target abTgt = sa.getTarget(); final TargetRestrictions abTgt = sa.getTargetRestrictions();
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
Card choice = null; Card choice = null;
final String type = sa.getParam("CounterType"); final String type = sa.getParam("CounterType");
@@ -193,9 +193,9 @@ public class CountersPutAi extends SpellAbilityAi {
return false; return false;
} }
abTgt.resetTargets(); sa.resetTargets();
// target loop // 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<Card>() { list = CardLists.filter(list, new Predicate<Card>() {
@Override @Override
public boolean apply(final Card c) { public boolean apply(final Card c) {
@@ -203,9 +203,9 @@ public class CountersPutAi extends SpellAbilityAi {
} }
}); });
if (list.size() == 0) { if (list.size() == 0) {
if ((abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) if ((sa.getTargets().getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa))
|| (abTgt.getNumTargeted() == 0)) { || (sa.getTargets().getNumTargeted() == 0)) {
abTgt.resetTargets(); sa.resetTargets();
return false; return false;
} else { } else {
break; break;
@@ -219,9 +219,9 @@ public class CountersPutAi extends SpellAbilityAi {
} }
if (choice == null) { // can't find anything left if (choice == null) { // can't find anything left
if ((abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) if ((sa.getTargets().getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa))
|| (abTgt.getNumTargeted() == 0)) { || (sa.getTargets().getNumTargeted() == 0)) {
abTgt.resetTargets(); sa.resetTargets();
return false; return false;
} else { } else {
// TODO is this good enough? for up to amounts? // TODO is this good enough? for up to amounts?
@@ -229,7 +229,7 @@ public class CountersPutAi extends SpellAbilityAi {
} }
} }
list.remove(choice); list.remove(choice);
abTgt.addTarget(choice); sa.getTargets().add(choice);
if (divided) { if (divided) {
abTgt.addDividedAllocation(choice, amount); abTgt.addDividedAllocation(choice, amount);
break; break;
@@ -242,7 +242,7 @@ public class CountersPutAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
final Target abTgt = sa.getTarget(); final TargetRestrictions abTgt = sa.getTargetRestrictions();
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
// boolean chance = true; // boolean chance = true;
boolean preferred = 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 // TODO - I think choice can be null here. Is that ok for
// addTarget()? // addTarget()?
abTgt.addTarget(choice); sa.getTargets().add(choice);
} }
return true; return true;

View File

@@ -12,7 +12,7 @@ import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.AbilitySub; import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.ai.ComputerUtilMana; import forge.game.ai.ComputerUtilMana;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
@@ -36,7 +36,7 @@ public class CountersPutAllAi extends SpellAbilityAi {
final String amountStr = sa.getParam("CounterNum"); final String amountStr = sa.getParam("CounterNum");
final String valid = sa.getParam("ValidCards"); final String valid = sa.getParam("ValidCards");
final boolean curse = sa.isCurse(); 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); hList = CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid, source.getController(), source);
cList = CardLists.getValidCards(ai.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) { if (tgt != null) {
Player pl = curse ? ai.getOpponent() : ai; Player pl = curse ? ai.getOpponent() : ai;
tgt.addTarget(pl); sa.getTargets().add(pl);
hList = CardLists.filterControlledBy(hList, pl); hList = CardLists.filterControlledBy(hList, pl);
cList = CardLists.filterControlledBy(cList, pl); cList = CardLists.filterControlledBy(cList, pl);

View File

@@ -5,7 +5,7 @@ import forge.CounterType;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
@@ -19,7 +19,7 @@ public class CountersRemoveAi extends SpellAbilityAi {
// based on what // based on what
// the expected targets could be // the expected targets could be
final Cost abCost = sa.getPayCosts(); final Cost abCost = sa.getPayCosts();
Target abTgt = sa.getTarget(); TargetRestrictions abTgt = sa.getTargetRestrictions();
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
// List<Card> list; // List<Card> list;
// Card choice = null; // Card choice = null;

View File

@@ -12,7 +12,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCombat; import forge.game.ai.ComputerUtilCombat;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
@@ -51,10 +51,10 @@ public class DamageAllAi extends SpellAbilityAi {
final List<Card> humanList = this.getKillableCreatures(sa, opp, dmg); final List<Card> humanList = this.getKillableCreatures(sa, opp, dmg);
List<Card> computerList = this.getKillableCreatures(sa, ai, dmg); List<Card> computerList = this.getKillableCreatures(sa, ai, dmg);
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null && sa.canTarget(opp)) { if (tgt != null && sa.canTarget(opp)) {
tgt.resetTargets(); sa.resetTargets();
sa.getTarget().addTarget(opp); sa.getTargets().add(opp);
computerList = new ArrayList<Card>(); computerList = new ArrayList<Card>();
} }
@@ -124,11 +124,11 @@ public class DamageAllAi extends SpellAbilityAi {
Player enemy = ai.getOpponent(); Player enemy = ai.getOpponent();
final List<Card> humanList = this.getKillableCreatures(sa, enemy, dmg); final List<Card> humanList = this.getKillableCreatures(sa, enemy, dmg);
List<Card> computerList = this.getKillableCreatures(sa, ai, dmg); List<Card> computerList = this.getKillableCreatures(sa, ai, dmg);
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null && sa.canTarget(enemy)) { if (tgt != null && sa.canTarget(enemy)) {
tgt.resetTargets(); sa.resetTargets();
sa.getTarget().addTarget(enemy); sa.getTargets().add(enemy);
computerList.clear(); computerList.clear();
} }
// Don't get yourself killed // Don't get yourself killed
@@ -208,11 +208,11 @@ public class DamageAllAi extends SpellAbilityAi {
Player enemy = ai.getOpponent(); Player enemy = ai.getOpponent();
final List<Card> humanList = this.getKillableCreatures(sa, enemy, dmg); final List<Card> humanList = this.getKillableCreatures(sa, enemy, dmg);
List<Card> computerList = this.getKillableCreatures(sa, ai, dmg); List<Card> computerList = this.getKillableCreatures(sa, ai, dmg);
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null && sa.canTarget(enemy)) { if (tgt != null && sa.canTarget(enemy)) {
tgt.resetTargets(); sa.resetTargets();
sa.getTarget().addTarget(enemy); sa.getTargets().add(enemy);
computerList.clear(); computerList.clear();
} }

View File

@@ -4,6 +4,7 @@ import java.util.List;
import java.util.Random; import java.util.Random;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
import forge.Card; import forge.Card;
import forge.CardLists; import forge.CardLists;
@@ -13,7 +14,7 @@ import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.AbilitySub; import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCard; 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 (damage.equals("X") && source.getSVar(damage).equals("Count$xPaid")) {
// If I can kill my target by paying less mana, do it // If I can kill my target by paying less mana, do it
final Target tgt = sa.getTarget(); if (sa.usesTargeting() && !sa.getTargets().isTargetingAnyPlayer() && !sa.hasParam("DividedAsYouChoose")) {
if (tgt != null && tgt.getTargetPlayers().isEmpty() && !sa.hasParam("DividedAsYouChoose")) {
int actualPay = 0; int actualPay = 0;
final boolean noPrevention = sa.hasParam("NoPrevention"); 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); final int adjDamage = ComputerUtilCombat.getEnoughDamageToKill(c, dmg, source, false, noPrevention);
if ((adjDamage > actualPay) && (adjDamage <= dmg)) { if ((adjDamage > actualPay) && (adjDamage <= dmg)) {
actualPay = adjDamage; actualPay = adjDamage;
@@ -135,20 +135,20 @@ public class DamageDealAi extends DamageAiBase {
* a boolean. * a boolean.
* @return a {@link forge.Card} object. * @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) { final Player pl, final boolean mandatory) {
// wait until stack is empty (prevents duplicate kills) // wait until stack is empty (prevents duplicate kills)
if (!saMe.isTrigger() && !ai.getGame().getStack().isEmpty()) { if (!sa.isTrigger() && !ai.getGame().getStack().isEmpty()) {
return null; return null;
} }
final Target tgt = saMe.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Card source = saMe.getSourceCard(); final Card source = sa.getSourceCard();
List<Card> hPlay = CardLists.getValidCards(pl.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, source); List<Card> hPlay = CardLists.getValidCards(pl.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, source);
final List<ITargetable> objects = tgt.getTargets(); final List<ITargetable> objects = Lists.newArrayList(sa.getTargets().getTargets());
if (saMe.hasParam("TargetUnique")) { if (sa.hasParam("TargetUnique")) {
objects.addAll(saMe.getUniqueTargets()); objects.addAll(sa.getUniqueTargets());
} }
for (final Object o : objects) { for (final Object o : objects) {
if (o instanceof Card) { 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<Card> killables = CardLists.filter(hPlay, new Predicate<Card>() { final List<Card> killables = CardLists.filter(hPlay, new Predicate<Card>() {
@Override @Override
@@ -204,7 +204,7 @@ public class DamageDealAi extends DamageAiBase {
* @return a boolean. * @return a boolean.
*/ */
private boolean damageTargetAI(final Player ai, final SpellAbility saMe, final int dmg) { 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) { if (tgt == null) {
return this.damageChooseNontargeted(ai, saMe, dmg); return this.damageChooseNontargeted(ai, saMe, dmg);
@@ -222,38 +222,38 @@ public class DamageDealAi extends DamageAiBase {
* damageChoosingTargets. * damageChoosingTargets.
* </p> * </p>
* *
* @param saMe * @param sa
* a {@link forge.card.spellability.SpellAbility} object. * a {@link forge.card.spellability.SpellAbility} object.
* @param tgt * @param tgt
* a {@link forge.card.spellability.Target} object. * a {@link forge.card.spellability.TargetRestrictions} object.
* @param dmg * @param dmg
* a int. * a int.
* @param mandatory * @param mandatory
* a boolean. * a boolean.
* @return 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 boolean isTrigger, final boolean mandatory) {
final Card source = saMe.getSourceCard(); final Card source = sa.getSourceCard();
final boolean noPrevention = saMe.hasParam("NoPrevention"); final boolean noPrevention = sa.hasParam("NoPrevention");
final Game game = source.getGame(); final Game game = source.getGame();
final PhaseHandler phase = game.getPhaseHandler(); final PhaseHandler phase = game.getPhaseHandler();
final boolean divided = saMe.hasParam("DividedAsYouChoose"); final boolean divided = sa.hasParam("DividedAsYouChoose");
// target loop // target loop
tgt.resetTargets(); sa.resetTargets();
Player enemy = ai.getOpponent(); Player enemy = ai.getOpponent();
if (tgt.getMaxTargets(source, saMe) <= 0) { if (tgt.getMaxTargets(source, sa) <= 0) {
return false; return false;
} }
while (tgt.getNumTargeted() < tgt.getMaxTargets(source, saMe)) { while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) {
if (tgt.canTgtCreatureAndPlayer()) { if (tgt.canTgtCreatureAndPlayer()) {
if (this.shouldTgtP(ai, saMe, dmg, noPrevention)) { if (this.shouldTgtP(ai, sa, dmg, noPrevention)) {
tgt.addTarget(enemy); sa.getTargets().add(enemy);
if (divided) { if (divided) {
tgt.addDividedAllocation(enemy, dmg); tgt.addDividedAllocation(enemy, dmg);
break; break;
@@ -261,9 +261,9 @@ public class DamageDealAi extends DamageAiBase {
continue; 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) { if (c != null) {
tgt.addTarget(c); sa.getTargets().add(c);
if (divided) { if (divided) {
final int assignedDamage = ComputerUtilCombat.getEnoughDamageToKill(c, dmg, source, false, noPrevention); final int assignedDamage = ComputerUtilCombat.getEnoughDamageToKill(c, dmg, source, false, noPrevention);
if (assignedDamage <= dmg) { if (assignedDamage <= dmg) {
@@ -284,21 +284,21 @@ public class DamageDealAi extends DamageAiBase {
// TODO: add check here if card is about to die from something // TODO: add check here if card is about to die from something
// on the stack // on the stack
// or from taking combat damage // or from taking combat damage
final boolean freePing = isTrigger || saMe.getPayCosts() == null || tgt.getNumTargeted() > 0 final boolean freePing = isTrigger || sa.getPayCosts() == null || sa.getTargets().getNumTargeted() > 0
|| (phase.is(PhaseType.END_OF_TURN) && saMe.isAbility() && phase.getNextTurn().equals(ai)) || (phase.is(PhaseType.END_OF_TURN) && sa.isAbility() && phase.getNextTurn().equals(ai))
|| (phase.is(PhaseType.MAIN2) && saMe.getRestrictions().getPlaneswalker()); || (phase.is(PhaseType.MAIN2) && sa.getRestrictions().getPlaneswalker());
if (freePing && saMe.canTarget(enemy)) { if (freePing && sa.canTarget(enemy)) {
tgt.addTarget(enemy); sa.getTargets().add(enemy);
if (divided) { if (divided) {
tgt.addDividedAllocation(enemy, dmg); tgt.addDividedAllocation(enemy, dmg);
break; break;
} }
} }
} else if (tgt.canTgtCreature()) { } 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) { if (c != null) {
tgt.addTarget(c); sa.getTargets().add(c);
if (divided) { if (divided) {
final int assignedDamage = ComputerUtilCombat.getEnoughDamageToKill(c, dmg, source, false, noPrevention); final int assignedDamage = ComputerUtilCombat.getEnoughDamageToKill(c, dmg, source, false, noPrevention);
if (assignedDamage <= dmg) { if (assignedDamage <= dmg) {
@@ -315,12 +315,12 @@ public class DamageDealAi extends DamageAiBase {
// TODO: Improve Damage, we shouldn't just target the player just // TODO: Improve Damage, we shouldn't just target the player just
// because we can // because we can
else if (saMe.canTarget(enemy)) { else if (sa.canTarget(enemy)) {
if ((phase.is(PhaseType.END_OF_TURN) && phase.getNextTurn().equals(ai)) if ((phase.is(PhaseType.END_OF_TURN) && phase.getNextTurn().equals(ai))
|| (SpellAbilityAi.isSorcerySpeed(saMe) && phase.is(PhaseType.MAIN2)) || (SpellAbilityAi.isSorcerySpeed(sa) && phase.is(PhaseType.MAIN2))
|| saMe.getPayCosts() == null || isTrigger || sa.getPayCosts() == null || isTrigger
|| this.shouldTgtP(ai, saMe, dmg, noPrevention)) { || this.shouldTgtP(ai, sa, dmg, noPrevention)) {
tgt.addTarget(enemy); sa.getTargets().add(enemy);
if (divided) { if (divided) {
tgt.addDividedAllocation(enemy, dmg); tgt.addDividedAllocation(enemy, dmg);
break; break;
@@ -329,13 +329,13 @@ public class DamageDealAi extends DamageAiBase {
} }
} }
// fell through all the choices, no targets left? // 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) { if (!mandatory) {
tgt.resetTargets(); sa.resetTargets();
return false; return false;
} else { } else {
// If the trigger is mandatory, gotta choose my own stuff now // 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 { } else {
// TODO is this good enough? for up to amounts? // TODO is this good enough? for up to amounts?
@@ -406,28 +406,28 @@ public class DamageDealAi extends DamageAiBase {
* damageChooseRequiredTargets. * damageChooseRequiredTargets.
* </p> * </p>
* *
* @param saMe * @param sa
* a {@link forge.card.spellability.SpellAbility} object. * a {@link forge.card.spellability.SpellAbility} object.
* @param tgt * @param tgt
* a {@link forge.card.spellability.Target} object. * a {@link forge.card.spellability.TargetRestrictions} object.
* @param dmg * @param dmg
* a int. * a int.
* @param mandatory * @param mandatory
* a boolean. * a boolean.
* @return 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) { final boolean mandatory) {
// this is for Triggered targets that are mandatory // this is for Triggered targets that are mandatory
final boolean noPrevention = saMe.hasParam("NoPrevention"); final boolean noPrevention = sa.hasParam("NoPrevention");
final boolean divided = saMe.hasParam("DividedAsYouChoose"); 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 // TODO: Consider targeting the planeswalker
if (tgt.canTgtCreature()) { 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) { if (c != null) {
tgt.addTarget(c); sa.getTargets().add(c);
if (divided) { if (divided) {
tgt.addDividedAllocation(c, dmg); tgt.addDividedAllocation(c, dmg);
break; break;
@@ -436,8 +436,8 @@ public class DamageDealAi extends DamageAiBase {
} }
} }
if (saMe.canTarget(ai)) { if (sa.canTarget(ai)) {
if (tgt.addTarget(ai)) { if (sa.getTargets().add(ai)) {
if (divided) { if (divided) {
tgt.addDividedAllocation(ai, dmg); tgt.addDividedAllocation(ai, dmg);
break; break;
@@ -466,7 +466,7 @@ public class DamageDealAi extends DamageAiBase {
source.setSVar("PayX", Integer.toString(dmg)); source.setSVar("PayX", Integer.toString(dmg));
} }
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt == null) { if (tgt == null) {
// If it's not mandatory check a few things // If it's not mandatory check a few things
if (!mandatory && !this.damageChooseNontargeted(ai, sa, dmg)) { 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 // If I can kill my target by paying less mana, do it
int actualPay = 0; int actualPay = 0;
final boolean noPrevention = sa.hasParam("NoPrevention"); final boolean noPrevention = sa.hasParam("NoPrevention");
final List<Card> cards = tgt.getTargetCards();
//target is a player //target is a player
if (cards.isEmpty()) { if (!sa.getTargets().isTargetingAnyCard()) {
actualPay = dmg; actualPay = dmg;
} }
for (final Card c : cards) { for (final Card c : sa.getTargets().getTargetCards()) {
final int adjDamage = ComputerUtilCombat.getEnoughDamageToKill(c, dmg, source, false, noPrevention); final int adjDamage = ComputerUtilCombat.getEnoughDamageToKill(c, dmg, source, false, noPrevention);
if (adjDamage > actualPay) { if (adjDamage > actualPay) {
actualPay = adjDamage; actualPay = adjDamage;

View File

@@ -3,7 +3,7 @@ package forge.card.ability.ai;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player; import forge.game.player.Player;
public class DamageEachAi extends DamageAiBase { public class DamageEachAi extends DamageAiBase {
@@ -13,11 +13,11 @@ public class DamageEachAi extends DamageAiBase {
*/ */
@Override @Override
protected boolean canPlayAI(Player ai, SpellAbility sa) { protected boolean canPlayAI(Player ai, SpellAbility sa) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null && sa.canTarget(ai.getOpponent())) { if (tgt != null && sa.canTarget(ai.getOpponent())) {
tgt.resetTargets(); sa.resetTargets();
sa.getTarget().addTarget(ai.getOpponent()); sa.getTargets().add(ai.getOpponent());
} }
final String damage = sa.getParam("NumDmg"); final String damage = sa.getParam("NumDmg");

View File

@@ -11,7 +11,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
@@ -49,7 +49,7 @@ public class DamagePreventAi extends SpellAbilityAi {
return false; return false;
} }
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt == null) { if (tgt == null) {
// As far as I can tell these Defined Cards will only have one of // As far as I can tell these Defined Cards will only have one of
// them // them
@@ -57,7 +57,7 @@ public class DamagePreventAi extends SpellAbilityAi {
// react to threats on the stack // react to threats on the stack
if (!game.getStack().isEmpty()) { if (!game.getStack().isEmpty()) {
final ArrayList<Object> threatenedObjects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa); final List<ITargetable> threatenedObjects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa);
for (final Object o : objects) { for (final Object o : objects) {
if (threatenedObjects.contains(o)) { if (threatenedObjects.contains(o)) {
chance = true; chance = true;
@@ -91,14 +91,14 @@ public class DamagePreventAi extends SpellAbilityAi {
// react to threats on the stack // react to threats on the stack
else if (!game.getStack().isEmpty()) { else if (!game.getStack().isEmpty()) {
tgt.resetTargets(); sa.resetTargets();
// check stack for something on the stack will kill anything i // check stack for something on the stack will kill anything i
// control // control
final ArrayList<Object> objects = new ArrayList<Object>(); final ArrayList<Object> objects = new ArrayList<Object>();
// AbilityFactory.predictThreatenedObjects(af); // AbilityFactory.predictThreatenedObjects(af);
if (objects.contains(ai)) { if (objects.contains(ai)) {
tgt.addTarget(ai); sa.getTargets().add(ai);
} }
final List<Card> threatenedTargets = new ArrayList<Card>(); final List<Card> threatenedTargets = new ArrayList<Card>();
@@ -114,7 +114,7 @@ public class DamagePreventAi extends SpellAbilityAi {
if (!threatenedTargets.isEmpty()) { if (!threatenedTargets.isEmpty()) {
// Choose "best" of the remaining to save // Choose "best" of the remaining to save
tgt.addTarget(ComputerUtilCard.getBestCreatureAI(threatenedTargets)); sa.getTargets().add(ComputerUtilCard.getBestCreatureAI(threatenedTargets));
chance = true; chance = true;
} }
@@ -123,7 +123,7 @@ public class DamagePreventAi extends SpellAbilityAi {
if (sa.canTarget(ai) && ComputerUtilCombat.wouldLoseLife(ai, game.getCombat()) if (sa.canTarget(ai) && ComputerUtilCombat.wouldLoseLife(ai, game.getCombat())
&& (ComputerUtilCombat.lifeInDanger(ai, game.getCombat()) || sa.isAbility()) && (ComputerUtilCombat.lifeInDanger(ai, game.getCombat()) || sa.isAbility())
&& game.getPhaseHandler().isPlayerTurn(ai.getOpponent())) { && game.getPhaseHandler().isPlayerTurn(ai.getOpponent())) {
tgt.addTarget(ai); sa.getTargets().add(ai);
chance = true; chance = true;
} else { } else {
// filter AIs battlefield by what I can target // filter AIs battlefield by what I can target
@@ -139,7 +139,7 @@ public class DamagePreventAi extends SpellAbilityAi {
for (final Card c : combatants) { for (final Card c : combatants) {
if (ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) { if (ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) {
tgt.addTarget(c); sa.getTargets().add(c);
chance = true; chance = true;
break; break;
} }
@@ -153,7 +153,7 @@ public class DamagePreventAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
boolean chance = false; boolean chance = false;
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt == null) { if (tgt == null) {
// If there's no target on the trigger, just say yes. // If there's no target on the trigger, just say yes.
chance = true; chance = true;
@@ -179,8 +179,8 @@ public class DamagePreventAi extends SpellAbilityAi {
*/ */
private boolean preventDamageMandatoryTarget(final Player ai, final SpellAbility sa, private boolean preventDamageMandatoryTarget(final Player ai, final SpellAbility sa,
final boolean mandatory) { final boolean mandatory) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
tgt.resetTargets(); sa.resetTargets();
// filter AIs battlefield by what I can target // filter AIs battlefield by what I can target
final Game game = ai.getGame(); final Game game = ai.getGame();
List<Card> targetables = game.getCardsIn(ZoneType.Battlefield); List<Card> targetables = game.getCardsIn(ZoneType.Battlefield);
@@ -201,7 +201,7 @@ public class DamagePreventAi extends SpellAbilityAi {
if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) { if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
for (final Card c : combatants) { for (final Card c : combatants) {
if (ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) { if (ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) {
tgt.addTarget(c); sa.getTargets().add(c);
return true; return true;
} }
} }
@@ -210,11 +210,11 @@ public class DamagePreventAi extends SpellAbilityAi {
// TODO see if something on the stack is about to kill something I // TODO see if something on the stack is about to kill something I
// can target // can target
tgt.addTarget(combatants.get(0)); sa.getTargets().add(combatants.get(0));
return true; return true;
} }
tgt.addTarget(ComputerUtilCard.getCheapestPermanentAI(targetables, sa, true)); sa.getTargets().add(ComputerUtilCard.getCheapestPermanentAI(targetables, sa, true));
return true; return true;
} }

View File

@@ -13,7 +13,7 @@ import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityRestriction; import forge.card.spellability.SpellAbilityRestriction;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
@@ -30,7 +30,7 @@ public class DebuffAi extends SpellAbilityAi {
protected boolean canPlayAI(final Player ai, final SpellAbility sa) { protected boolean canPlayAI(final Player ai, final SpellAbility sa) {
// if there is no target and host card isn't in play, don't activate // if there is no target and host card isn't in play, don't activate
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
if ((sa.getTarget() == null) && !source.isInPlay()) { if ((sa.getTargetRestrictions() == null) && !source.isInPlay()) {
return false; return false;
} }
@@ -70,7 +70,7 @@ public class DebuffAi extends SpellAbilityAi {
return false; return false;
} }
if ((sa.getTarget() == null) || !sa.getTarget().doesTarget()) { if ((sa.getTargetRestrictions() == null) || !sa.getTargetRestrictions().doesTarget()) {
List<Card> cards = AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa); List<Card> cards = AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa);
if (!cards.isEmpty()) { if (!cards.isEmpty()) {
@@ -97,7 +97,7 @@ public class DebuffAi extends SpellAbilityAi {
@Override @Override
public boolean chkAIDrawback(SpellAbility sa, Player ai) { 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 // TODO - copied from AF_Pump.pumpDrawbackAI() - what should be
// here? // here?
} else { } else {
@@ -128,8 +128,8 @@ public class DebuffAi extends SpellAbilityAi {
return false; return false;
} }
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
tgt.resetTargets(); sa.resetTargets();
List<Card> list = getCurseCreatures(ai, sa, kws); List<Card> list = getCurseCreatures(ai, sa, kws);
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard()); 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); 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; Card t = null;
// boolean goodt = false; // boolean goodt = false;
if (list.isEmpty()) { 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) { if (mandatory) {
return debuffMandatoryTarget(ai, sa, mandatory); return debuffMandatoryTarget(ai, sa, mandatory);
} }
tgt.resetTargets(); sa.resetTargets();
return false; return false;
} else { } else {
// TODO is this good enough? for up to amounts? // TODO is this good enough? for up to amounts?
@@ -163,7 +163,7 @@ public class DebuffAi extends SpellAbilityAi {
} }
t = ComputerUtilCard.getBestCreatureAI(list); t = ComputerUtilCard.getBestCreatureAI(list);
tgt.addTarget(t); sa.getTargets().add(t);
list.remove(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) { private boolean debuffMandatoryTarget(final Player ai, final SpellAbility sa, final boolean mandatory) {
List<Card> list = ai.getGame().getCardsIn(ZoneType.Battlefield); List<Card> 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()); list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard());
if (list.size() < tgt.getMinTargets(sa.getSourceCard(), sa)) { if (list.size() < tgt.getMinTargets(sa.getSourceCard(), sa)) {
tgt.resetTargets(); sa.resetTargets();
return false; return false;
} }
// Remove anything that's already been targeted // Remove anything that's already been targeted
for (final Card c : tgt.getTargetCards()) { for (final Card c : sa.getTargets().getTargetCards()) {
list.remove(c); list.remove(c);
} }
@@ -233,7 +233,7 @@ public class DebuffAi extends SpellAbilityAi {
final List<Card> forced = CardLists.filterControlledBy(list, ai); final List<Card> forced = CardLists.filterControlledBy(list, ai);
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) {
if (pref.isEmpty()) { if (pref.isEmpty()) {
break; break;
} }
@@ -247,10 +247,10 @@ public class DebuffAi extends SpellAbilityAi {
pref.remove(c); 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()) { if (forced.isEmpty()) {
break; break;
} }
@@ -266,11 +266,11 @@ public class DebuffAi extends SpellAbilityAi {
forced.remove(c); forced.remove(c);
tgt.addTarget(c); sa.getTargets().add(c);
} }
if (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { if (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) {
tgt.resetTargets(); sa.resetTargets();
return false; return false;
} }
@@ -281,7 +281,7 @@ public class DebuffAi extends SpellAbilityAi {
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
final List<String> kws = sa.hasParam("Keywords") ? Arrays.asList(sa.getParam("Keywords").split(" & ")) : new ArrayList<String>(); final List<String> kws = sa.hasParam("Keywords") ? Arrays.asList(sa.getParam("Keywords").split(" & ")) : new ArrayList<String>();
if (sa.getTarget() == null) { if (sa.getTargetRestrictions() == null) {
if (mandatory) { if (mandatory) {
return true; return true;
} }

View File

@@ -15,7 +15,7 @@ import forge.card.cost.Cost;
import forge.card.cost.CostPart; import forge.card.cost.CostPart;
import forge.card.cost.CostSacrifice; import forge.card.cost.CostSacrifice;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
@@ -41,7 +41,7 @@ public class DestroyAi extends SpellAbilityAi {
// based on what the expected targets could be // based on what the expected targets could be
final Random r = MyRandom.getRandom(); final Random r = MyRandom.getRandom();
final Cost abCost = sa.getPayCosts(); final Cost abCost = sa.getPayCosts();
final Target abTgt = sa.getTarget(); final TargetRestrictions abTgt = sa.getTargetRestrictions();
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final boolean noRegen = sa.hasParam("NoRegen"); final boolean noRegen = sa.hasParam("NoRegen");
List<Card> list; List<Card> list;
@@ -65,7 +65,7 @@ public class DestroyAi extends SpellAbilityAi {
// Targeting // Targeting
if (abTgt != null) { if (abTgt != null) {
abTgt.resetTargets(); sa.resetTargets();
list = CardLists.getTargetableCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), sa); list = CardLists.getTargetableCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), sa);
list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source); list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source);
if (sa.hasParam("AITgts")) { if (sa.hasParam("AITgts")) {
@@ -113,11 +113,11 @@ public class DestroyAi extends SpellAbilityAi {
return false; return false;
} }
// target loop // target loop
while (abTgt.getNumTargeted() < abTgt.getMaxTargets(sa.getSourceCard(), sa)) { while (sa.getTargets().getNumTargeted() < abTgt.getMaxTargets(sa.getSourceCard(), sa)) {
if (list.size() == 0) { if (list.size() == 0) {
if ((abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) if ((sa.getTargets().getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa))
|| (abTgt.getNumTargeted() == 0)) { || (sa.getTargets().getNumTargeted() == 0)) {
abTgt.resetTargets(); sa.resetTargets();
return false; return false;
} else { } else {
// TODO is this good enough? for up to amounts? // 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 (choice == null) { // can't find anything left
if ((abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa)) if ((sa.getTargets().getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa))
|| (abTgt.getNumTargeted() == 0)) { || (sa.getTargets().getNumTargeted() == 0)) {
abTgt.resetTargets(); sa.resetTargets();
return false; return false;
} else { } else {
// TODO is this good enough? for up to amounts? // TODO is this good enough? for up to amounts?
@@ -146,7 +146,7 @@ public class DestroyAi extends SpellAbilityAi {
} }
} }
list.remove(choice); list.remove(choice);
abTgt.addTarget(choice); sa.getTargets().add(choice);
} }
} else { } else {
if (sa.hasParam("Defined")) { if (sa.hasParam("Defined")) {
@@ -164,7 +164,7 @@ public class DestroyAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { 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 Card source = sa.getSourceCard();
final boolean noRegen = sa.hasParam("NoRegen"); final boolean noRegen = sa.hasParam("NoRegen");
final Player opp = ai.getOpponent(); final Player opp = ai.getOpponent();
@@ -178,7 +178,7 @@ public class DestroyAi extends SpellAbilityAi {
return false; return false;
} }
tgt.resetTargets(); sa.resetTargets();
List<Card> preferred = CardLists.getNotKeyword(list, "Indestructible"); List<Card> preferred = CardLists.getNotKeyword(list, "Indestructible");
preferred = CardLists.filterControlledBy(preferred, opp); preferred = CardLists.filterControlledBy(preferred, opp);
@@ -200,12 +200,12 @@ public class DestroyAi extends SpellAbilityAi {
list.remove(c); 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 (preferred.size() == 0) {
if ((tgt.getNumTargeted() == 0) if ((sa.getTargets().getNumTargeted() == 0)
|| (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa))) { || (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa))) {
if (!mandatory) { if (!mandatory) {
tgt.resetTargets(); sa.resetTargets();
return false; return false;
} else { } else {
break; break;
@@ -222,12 +222,12 @@ public class DestroyAi extends SpellAbilityAi {
} else { } else {
c = ComputerUtilCard.getMostExpensivePermanentAI(preferred, sa, false); c = ComputerUtilCard.getMostExpensivePermanentAI(preferred, sa, false);
} }
tgt.addTarget(c); sa.getTargets().add(c);
preferred.remove(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) { if (list.size() == 0) {
break; break;
} else { } else {
@@ -237,12 +237,12 @@ public class DestroyAi extends SpellAbilityAi {
} else { } else {
c = ComputerUtilCard.getCheapestPermanentAI(list, sa, false); c = ComputerUtilCard.getCheapestPermanentAI(list, sa, false);
} }
tgt.addTarget(c); sa.getTargets().add(c);
list.remove(c); list.remove(c);
} }
} }
if (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { if (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) {
return false; return false;
} }
} else { } else {

View File

@@ -10,7 +10,6 @@ import forge.CardLists;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.ai.ComputerUtilMana; import forge.game.ai.ComputerUtilMana;
@@ -33,7 +32,6 @@ public class DestroyAllAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Target tgt = sa.getTarget();
String valid = ""; String valid = "";
if (mandatory) { if (mandatory) {
return true; return true;
@@ -41,13 +39,12 @@ public class DestroyAllAi extends SpellAbilityAi {
if (sa.hasParam("ValidCards")) { if (sa.hasParam("ValidCards")) {
valid = sa.getParam("ValidCards"); valid = sa.getParam("ValidCards");
} }
List<Card> humanlist = List<Card> humanlist = CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source);
CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source); List<Card> computerlist = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source);
List<Card> computerlist =
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source); if (sa.usesTargeting()) {
if (sa.getTarget() != null) { sa.resetTargets();
tgt.resetTargets(); sa.getTargets().add(ai.getOpponent());
sa.getTarget().addTarget(ai.getOpponent());
computerlist.clear(); computerlist.clear();
} }
@@ -98,15 +95,11 @@ public class DestroyAllAi extends SpellAbilityAi {
valid = valid.replace("X", Integer.toString(xPay)); valid = valid.replace("X", Integer.toString(xPay));
} }
final Target tgt = sa.getTarget(); List<Card> humanlist = CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source);
List<Card> computerlist = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source);
List<Card> humanlist = if (sa.usesTargeting()) {
CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source); sa.resetTargets();
List<Card> computerlist = sa.getTargets().add(ai.getOpponent());
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source);
if (sa.getTarget() != null) {
tgt.resetTargets();
sa.getTarget().addTarget(ai.getOpponent());
computerlist.clear(); computerlist.clear();
} }

View File

@@ -6,7 +6,6 @@ import forge.Card;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
@@ -24,15 +23,14 @@ public class DigAi extends SpellAbilityAi {
Player opp = ai.getOpponent(); Player opp = ai.getOpponent();
final Card host = sa.getSourceCard(); final Card host = sa.getSourceCard();
final Target tgt = sa.getTarget();
Player libraryOwner = ai; Player libraryOwner = ai;
if (sa.getTarget() != null) { if (sa.usesTargeting()) {
tgt.resetTargets(); sa.resetTargets();
if (!opp.canBeTargetedBy(sa)) { if (!opp.canBeTargetedBy(sa)) {
return false; return false;
} else { } else {
sa.getTarget().addTarget(opp); sa.getTargets().add(opp);
} }
libraryOwner = opp; libraryOwner = opp;
} }
@@ -68,11 +66,9 @@ public class DigAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
final Target tgt = sa.getTarget(); if (sa.usesTargeting()) {
sa.resetTargets();
if (sa.getTarget() != null) { sa.getTargets().add(ai);
tgt.resetTargets();
sa.getTarget().addTarget(ai);
} }
return true; return true;

View File

@@ -7,7 +7,6 @@ import forge.CardLists;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.AbilitySub; import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.game.ai.ComputerUtilMana; import forge.game.ai.ComputerUtilMana;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -26,16 +25,15 @@ public class DigUntilAi extends SpellAbilityAi {
final Random r = MyRandom.getRandom(); final Random r = MyRandom.getRandom();
final boolean randomReturn = r.nextFloat() <= Math.pow(chance, sa.getActivationsThisTurn() + 1); final boolean randomReturn = r.nextFloat() <= Math.pow(chance, sa.getActivationsThisTurn() + 1);
final Target tgt = sa.getTarget();
Player libraryOwner = ai; Player libraryOwner = ai;
Player opp = ai.getOpponent(); Player opp = ai.getOpponent();
if (sa.getTarget() != null) { if (sa.usesTargeting()) {
tgt.resetTargets(); sa.resetTargets();
if (!opp.canBeTargetedBy(sa)) { if (!opp.canBeTargetedBy(sa)) {
return false; return false;
} else { } else {
sa.getTarget().addTarget(opp); sa.getTargets().add(opp);
} }
libraryOwner = opp; libraryOwner = opp;
} else { } else {
@@ -70,14 +68,12 @@ public class DigUntilAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
final Target tgt = sa.getTarget(); if (sa.usesTargeting()) {
sa.resetTargets();
if (sa.getTarget() != null) {
tgt.resetTargets();
if (sa.isCurse()) { if (sa.isCurse()) {
sa.getTarget().addTarget(ai.getOpponent()); sa.getTargets().add(ai.getOpponent());
} else { } else {
sa.getTarget().addTarget(ai); sa.getTargets().add(ai);
} }
} }

View File

@@ -8,7 +8,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.ai.ComputerUtilMana; import forge.game.ai.ComputerUtilMana;
@@ -22,7 +22,7 @@ public class DiscardAi extends SpellAbilityAi {
@Override @Override
protected boolean canPlayAI(Player ai, SpellAbility sa) { protected boolean canPlayAI(Player ai, SpellAbility sa) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Cost abCost = sa.getPayCosts(); final Cost abCost = sa.getPayCosts();
@@ -113,14 +113,14 @@ public class DiscardAi extends SpellAbilityAi {
} // discardCanPlayAI() } // discardCanPlayAI()
private boolean discardTargetAI(final Player ai, final SpellAbility sa) { private boolean discardTargetAI(final Player ai, final SpellAbility sa) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
Player opp = ai.getOpponent(); Player opp = ai.getOpponent();
if (opp.getCardsIn(ZoneType.Hand).isEmpty()) { if (opp.getCardsIn(ZoneType.Hand).isEmpty()) {
return false; return false;
} }
if (tgt != null) { if (tgt != null) {
if (sa.canTarget(opp)) { if (sa.canTarget(opp)) {
tgt.addTarget(opp); sa.getTargets().add(opp);
return true; return true;
} }
} }
@@ -131,14 +131,14 @@ public class DiscardAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
Player opp = ai.getOpponent(); Player opp = ai.getOpponent();
if (!discardTargetAI(ai, sa)) { if (!discardTargetAI(ai, sa)) {
if (mandatory && sa.canTarget(opp)) { if (mandatory && sa.canTarget(opp)) {
tgt.addTarget(opp); sa.getTargets().add(opp);
} else if (mandatory && sa.canTarget(ai)) { } else if (mandatory && sa.canTarget(ai)) {
tgt.addTarget(ai); sa.getTargets().add(ai);
} else { } else {
return false; return false;
} }
@@ -159,7 +159,7 @@ public class DiscardAi extends SpellAbilityAi {
public boolean chkAIDrawback(SpellAbility sa, Player ai) { public boolean chkAIDrawback(SpellAbility sa, Player ai) {
// Drawback AI improvements // Drawback AI improvements
// if parent draws cards, make sure cards in hand + cards drawn > 0 // 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) { if (tgt != null) {
return discardTargetAI(ai, sa); return discardTargetAI(ai, sa);
} }

View File

@@ -7,7 +7,7 @@ import forge.Card;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player; import forge.game.player.Player;
import forge.util.MyRandom; import forge.util.MyRandom;
@@ -17,7 +17,7 @@ public class DrainManaAi extends SpellAbilityAi {
protected boolean canPlayAI(Player ai, SpellAbility sa) { protected boolean canPlayAI(Player ai, SpellAbility sa) {
// AI cannot use this properly until he can use SAs during Humans turn // 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 Card source = sa.getSourceCard();
final Player opp = ai.getOpponent(); final Player opp = ai.getOpponent();
final Random r = MyRandom.getRandom(); final Random r = MyRandom.getRandom();
@@ -33,8 +33,8 @@ public class DrainManaAi extends SpellAbilityAi {
return false; return false;
} }
} else { } else {
tgt.resetTargets(); sa.resetTargets();
tgt.addTarget(opp); sa.getTargets().add(opp);
} }
return randomReturn; return randomReturn;
@@ -44,7 +44,7 @@ public class DrainManaAi extends SpellAbilityAi {
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
final Player opp = ai.getOpponent(); final Player opp = ai.getOpponent();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
if (null == tgt) { if (null == tgt) {
@@ -60,8 +60,8 @@ public class DrainManaAi extends SpellAbilityAi {
return true; return true;
} else { } else {
tgt.resetTargets(); sa.resetTargets();
tgt.addTarget(opp); sa.getTargets().add(opp);
} }
return true; return true;
@@ -70,7 +70,7 @@ public class DrainManaAi extends SpellAbilityAi {
@Override @Override
public boolean chkAIDrawback(SpellAbility sa, Player ai) { public boolean chkAIDrawback(SpellAbility sa, Player ai) {
// AI cannot use this properly until he can use SAs during Humans turn // 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 Card source = sa.getSourceCard();
boolean randomReturn = true; boolean randomReturn = true;
@@ -82,8 +82,8 @@ public class DrainManaAi extends SpellAbilityAi {
return false; return false;
} }
} else { } else {
tgt.resetTargets(); sa.resetTargets();
tgt.addTarget(ai.getOpponent()); sa.getTargets().add(ai.getOpponent());
} }
return randomReturn; return randomReturn;

View File

@@ -18,7 +18,6 @@
*/ */
package forge.card.ability.ai; package forge.card.ability.ai;
import java.util.List;
import java.util.Random; import java.util.Random;
import forge.Card; import forge.Card;
@@ -30,7 +29,7 @@ import forge.card.cost.CostPart;
import forge.card.cost.PaymentDecision; import forge.card.cost.PaymentDecision;
import forge.card.spellability.AbilitySub; import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
@@ -53,7 +52,7 @@ public class DrawAi extends SpellAbilityAi {
*/ */
@Override @Override
protected boolean canPlayAI(Player ai, SpellAbility sa) { protected boolean canPlayAI(Player ai, SpellAbility sa) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Cost abCost = sa.getPayCosts(); final Cost abCost = sa.getPayCosts();
final Game game = ai.getGame(); final Game game = ai.getGame();
@@ -95,8 +94,8 @@ public class DrawAi extends SpellAbilityAi {
} }
if (tgt != null) { if (tgt != null) {
final List<Player> players = tgt.getTargetPlayers(); final Player player = sa.getTargets().getFirstTargetedPlayer();
if ((players.size() > 0) && players.get(0).isOpponentOf(ai)) { if (player != null && player.isOpponentOf(ai)) {
return true; return true;
} }
} }
@@ -139,7 +138,7 @@ public class DrawAi extends SpellAbilityAi {
} }
private boolean targetAI(final Player ai, final SpellAbility sa, final boolean mandatory) { 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 Card source = sa.getSourceCard();
final boolean drawback = (sa instanceof AbilitySub); final boolean drawback = (sa instanceof AbilitySub);
final Game game = ai.getGame(); final Game game = ai.getGame();
@@ -180,7 +179,7 @@ public class DrawAi extends SpellAbilityAi {
if (tgt != null) { if (tgt != null) {
// ability is targeted // ability is targeted
tgt.resetTargets(); sa.resetTargets();
final boolean canTgtHuman = sa.canTarget(opp); final boolean canTgtHuman = sa.canTarget(opp);
final boolean canTgtComp = sa.canTarget(ai); final boolean canTgtComp = sa.canTarget(ai);
@@ -192,7 +191,7 @@ public class DrawAi extends SpellAbilityAi {
if (canTgtHuman && !opp.cantLose() && numCards >= humanLibrarySize) { if (canTgtHuman && !opp.cantLose() && numCards >= humanLibrarySize) {
// Deck the Human? DO IT! // Deck the Human? DO IT!
tgt.addTarget(opp); sa.getTargets().add(opp);
return true; return true;
} }
@@ -228,9 +227,9 @@ public class DrawAi extends SpellAbilityAi {
} }
if ((!tgtHuman || !canTgtHuman) && canTgtComp) { if ((!tgtHuman || !canTgtHuman) && canTgtComp) {
tgt.addTarget(ai); sa.getTargets().add(ai);
} else if (mandatory && canTgtHuman) { } else if (mandatory && canTgtHuman) {
tgt.addTarget(opp); sa.getTargets().add(opp);
} else { } else {
return false; return false;
} }

View File

@@ -9,7 +9,7 @@ import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCombat; import forge.game.ai.ComputerUtilCombat;
@@ -58,9 +58,9 @@ public class EffectAi extends SpellAbilityAi {
if (!ComputerUtilCombat.lifeInDanger(ai, game.getCombat())) { if (!ComputerUtilCombat.lifeInDanger(ai, game.getCombat())) {
return false; return false;
} }
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
List<Card> list = game.getCombat().getAttackers(); List<Card> list = game.getCombat().getAttackers();
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard()); list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard());
list = CardLists.getTargetableCards(list, sa); list = CardLists.getTargetableCards(list, sa);
@@ -68,7 +68,7 @@ public class EffectAi extends SpellAbilityAi {
if (target == null) { if (target == null) {
return false; return false;
} }
tgt.addTarget(target); sa.getTargets().add(target);
} }
randomReturn = true; randomReturn = true;
} else if (logic.equals("Always")) { } 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()) { if (tgt != null && tgt.canTgtPlayer()) {
tgt.resetTargets(); sa.resetTargets();
if (tgt.canOnlyTgtOpponent() || logic.equals("BeginningOfOppTurn")) { if (tgt.canOnlyTgtOpponent() || logic.equals("BeginningOfOppTurn")) {
tgt.addTarget(ai.getOpponent()); sa.getTargets().add(ai.getOpponent());
} else { } else {
tgt.addTarget(ai); sa.getTargets().add(ai);
} }
} }
@@ -125,15 +125,14 @@ public class EffectAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player aiPlayer, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player aiPlayer, SpellAbility sa, boolean mandatory) {
final Target tgt = sa.getTarget();
final Player opp = aiPlayer.getOpponent(); final Player opp = aiPlayer.getOpponent();
if (sa.getTarget() != null) { if (sa.usesTargeting()) {
tgt.resetTargets(); sa.resetTargets();
if (mandatory && sa.canTarget(opp)) { if (mandatory && sa.canTarget(opp)) {
sa.getTarget().addTarget(opp); sa.getTargets().add(opp);
} else if (mandatory && sa.canTarget(aiPlayer)) { } else if (mandatory && sa.canTarget(aiPlayer)) {
sa.getTarget().addTarget(aiPlayer); sa.getTargets().add(aiPlayer);
} }
} }

View File

@@ -7,7 +7,6 @@ import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCombat; import forge.game.ai.ComputerUtilCombat;
import forge.game.player.Player; import forge.game.player.Player;
@@ -20,8 +19,7 @@ public class FightAi extends SpellAbilityAi {
*/ */
@Override @Override
protected boolean canPlayAI(Player ai, SpellAbility sa) { protected boolean canPlayAI(Player ai, SpellAbility sa) {
Target tgt = sa.getTarget(); sa.resetTargets();
tgt.resetTargets();
List<Card> aiCreatures = ai.getCreaturesInPlay(); List<Card> aiCreatures = ai.getCreaturesInPlay();
aiCreatures = CardLists.getTargetableCards(aiCreatures, sa); aiCreatures = CardLists.getTargetableCards(aiCreatures, sa);
@@ -42,12 +40,12 @@ public class FightAi extends SpellAbilityAi {
if (ComputerUtilCombat.getDamageToKill(humanCreature) <= aiCreature.getNetAttack() if (ComputerUtilCombat.getDamageToKill(humanCreature) <= aiCreature.getNetAttack()
&& humanCreature.getNetAttack() < ComputerUtilCombat.getDamageToKill(aiCreature)) { && humanCreature.getNetAttack() < ComputerUtilCombat.getDamageToKill(aiCreature)) {
// todo: check min/max targets; see if we picked the best matchup // todo: check min/max targets; see if we picked the best matchup
tgt.addTarget(humanCreature); sa.getTargets().add(humanCreature);
tgt.addTarget(aiCreature); sa.getTargets().add(aiCreature);
return true; return true;
} else if (humanCreature.getSVar("Targeting").equals("Dies")) { } else if (humanCreature.getSVar("Targeting").equals("Dies")) {
tgt.addTarget(humanCreature); sa.getTargets().add(humanCreature);
tgt.addTarget(aiCreature); sa.getTargets().add(aiCreature);
return true; return true;
} }
} }
@@ -67,8 +65,8 @@ public class FightAi extends SpellAbilityAi {
if (ComputerUtilCombat.getDamageToKill(creature1) <= creature2.getNetAttack() if (ComputerUtilCombat.getDamageToKill(creature1) <= creature2.getNetAttack()
&& creature1.getNetAttack() >= ComputerUtilCombat.getDamageToKill(creature2)) { && creature1.getNetAttack() >= ComputerUtilCombat.getDamageToKill(creature2)) {
// todo: check min/max targets; see if we picked the best matchup // todo: check min/max targets; see if we picked the best matchup
tgt.addTarget(creature1); sa.getTargets().add(creature1);
tgt.addTarget(creature2); sa.getTargets().add(creature2);
return true; return true;
} }
} }

View File

@@ -2,7 +2,7 @@ package forge.card.ability.ai;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player; import forge.game.player.Player;
public class GameLossAi extends SpellAbilityAi { 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 // Only one SA Lose the Game card right now, which is Door to
// Nothingness // Nothingness
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
tgt.addTarget(opp); sa.getTargets().add(opp);
} }
// In general, don't return true. // In general, don't return true.
@@ -38,10 +38,10 @@ public class GameLossAi extends SpellAbilityAi {
return false; return false;
} }
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
tgt.addTarget(ai.getOpponent()); sa.getTargets().add(ai.getOpponent());
} }
return true; return true;

View File

@@ -4,7 +4,7 @@ import java.util.Random;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player; import forge.game.player.Player;
import forge.util.MyRandom; import forge.util.MyRandom;
@@ -37,12 +37,12 @@ public class LifeExchangeAi extends SpellAbilityAi {
* and one card that has a conditional (Psychic Transfer) that are * and one card that has a conditional (Psychic Transfer) that are
* not currently handled * not currently handled
*/ */
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
if (opponent.canBeTargetedBy(sa)) { if (opponent.canBeTargetedBy(sa)) {
// never target self, that would be silly for exchange // never target self, that would be silly for exchange
tgt.addTarget(opponent); sa.getTargets().add(opponent);
if (!opponent.canLoseLife()) { if (!opponent.canLoseLife()) {
return false; return false;
} }

View File

@@ -6,7 +6,7 @@ import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.AbilitySub; import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCombat; import forge.game.ai.ComputerUtilCombat;
@@ -112,11 +112,11 @@ public class LifeGainAi extends SpellAbilityAi {
return false; return false;
} }
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
if (sa.canTarget(ai)) { if (sa.canTarget(ai)) {
tgt.addTarget(ai); sa.getTargets().add(ai);
} else { } else {
return false; return false;
} }
@@ -146,13 +146,13 @@ public class LifeGainAi extends SpellAbilityAi {
// If the Target is gaining life, target self. // If the Target is gaining life, target self.
// if the Target is modifying how much life is gained, this needs to be // if the Target is modifying how much life is gained, this needs to be
// handled better // handled better
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
if (sa.canTarget(ai)) { if (sa.canTarget(ai)) {
tgt.addTarget(ai); sa.getTargets().add(ai);
} else if (mandatory && sa.canTarget(ai.getOpponent())) { } else if (mandatory && sa.canTarget(ai.getOpponent())) {
tgt.addTarget(ai.getOpponent()); sa.getTargets().add(ai.getOpponent());
} else { } else {
return false; return false;
} }

View File

@@ -6,7 +6,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.ai.ComputerUtilMana; import forge.game.ai.ComputerUtilMana;
@@ -18,13 +18,7 @@ public class LifeLoseAi extends SpellAbilityAi {
@Override @Override
public boolean chkAIDrawback(SpellAbility sa, Player ai) { public boolean chkAIDrawback(SpellAbility sa, Player ai) {
final Target tgt = sa.getTarget(); List<Player> tgtPlayers = getTargetPlayers(sa);
List<Player> tgtPlayers;
if (tgt != null) {
tgtPlayers = tgt.getTargetPlayers();
} else {
tgtPlayers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa);
}
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final String amountStr = sa.getParam("LifeAmount"); final String amountStr = sa.getParam("LifeAmount");
@@ -98,12 +92,10 @@ public class LifeLoseAi extends SpellAbilityAi {
return false; return false;
} }
final Target tgt = sa.getTarget(); if (sa.usesTargeting()) {
sa.resetTargets();
if (sa.getTarget() != null) {
tgt.resetTargets();
if (sa.canTarget(opp)) { if (sa.canTarget(opp)) {
sa.getTarget().addTarget(opp); sa.getTargets().add(opp);
} else { } else {
return false; return false;
} }
@@ -138,12 +130,12 @@ public class LifeLoseAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(final Player ai, final SpellAbility sa, protected boolean doTriggerAINoCost(final Player ai, final SpellAbility sa,
final boolean mandatory) { final boolean mandatory) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
if (sa.canTarget(ai.getOpponent())) { if (sa.canTarget(ai.getOpponent())) {
tgt.addTarget(ai.getOpponent()); sa.getTargets().add(ai.getOpponent());
} else if (mandatory && sa.canTarget(ai)) { } else if (mandatory && sa.canTarget(ai)) {
tgt.addTarget(ai); sa.getTargets().add(ai);
} else { } else {
return false; return false;
} }
@@ -161,12 +153,7 @@ public class LifeLoseAi extends SpellAbilityAi {
amount = AbilityUtils.calculateAmount(source, amountStr, sa); amount = AbilityUtils.calculateAmount(source, amountStr, sa);
} }
List<Player> tgtPlayers; List<Player> tgtPlayers = getTargetPlayers(sa);
if (tgt != null) {
tgtPlayers = tgt.getTargetPlayers();
} else {
tgtPlayers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa);
}
if (!mandatory && tgtPlayers.contains(ai) && amount > 0 && amount + 3 > ai.getLife()) { if (!mandatory && tgtPlayers.contains(ai) && amount > 0 && amount + 3 > ai.getLife()) {
// For cards like Foul Imp, ETB you lose life // For cards like Foul Imp, ETB you lose life

View File

@@ -7,7 +7,7 @@ import forge.CounterType;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilMana; import forge.game.ai.ComputerUtilMana;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
@@ -51,11 +51,11 @@ public class LifeSetAi extends SpellAbilityAi {
// prevent run-away activations - first time will always return true // prevent run-away activations - first time will always return true
final boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn()); final boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
if (tgt.canOnlyTgtOpponent()) { if (tgt.canOnlyTgtOpponent()) {
tgt.addTarget(opponent); sa.getTargets().add(opponent);
// if we can only target the human, and the Human's life // if we can only target the human, and the Human's life
// would // would
// go up, don't play it. // go up, don't play it.
@@ -67,11 +67,11 @@ public class LifeSetAi extends SpellAbilityAi {
} }
} else { } else {
if ((amount > myLife) && (myLife <= 10)) { if ((amount > myLife) && (myLife <= 10)) {
tgt.addTarget(ai); sa.getTargets().add(ai);
} else if (hlife > amount) { } else if (hlife > amount) {
tgt.addTarget(opponent); sa.getTargets().add(opponent);
} else if (amount > myLife) { } else if (amount > myLife) {
tgt.addTarget(ai); sa.getTargets().add(ai);
} else { } else {
return false; return false;
} }
@@ -128,18 +128,18 @@ public class LifeSetAi extends SpellAbilityAi {
// if the Target is modifying how much life is gained, this needs to // if the Target is modifying how much life is gained, this needs to
// be // be
// handled better // handled better
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
if (tgt.canOnlyTgtOpponent()) { if (tgt.canOnlyTgtOpponent()) {
tgt.addTarget(opponent); sa.getTargets().add(opponent);
} else { } else {
if ((amount > myLife) && (myLife <= 10)) { if ((amount > myLife) && (myLife <= 10)) {
tgt.addTarget(ai); sa.getTargets().add(ai);
} else if (hlife > amount) { } else if (hlife > amount) {
tgt.addTarget(opponent); sa.getTargets().add(opponent);
} else if (amount > myLife) { } else if (amount > myLife) {
tgt.addTarget(ai); sa.getTargets().add(ai);
} else { } else {
return false; return false;
} }

View File

@@ -8,7 +8,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.ai.ComputerUtilMana; 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) { 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(); Player opp = ai.getOpponent();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
if (!sa.canTarget(opp)) { if (!sa.canTarget(opp)) {
if (mandatory && sa.canTarget(ai)) { if (mandatory && sa.canTarget(ai)) {
tgt.addTarget(ai); sa.getTargets().add(ai);
return true; return true;
} }
return false; return false;
@@ -114,22 +114,22 @@ public class MillAi extends SpellAbilityAi {
return false; return false;
} }
tgt.addTarget(opp); sa.getTargets().add(opp);
return true; return true;
} }
if (numCards >= pLibrary.size()) { if (numCards >= pLibrary.size()) {
// Can Mill out Human's deck? Do it! // Can Mill out Human's deck? Do it!
tgt.addTarget(opp); sa.getTargets().add(opp);
return true; return true;
} }
// Obscure case when you know what your top card is so you might? // Obscure case when you know what your top card is so you might?
// want to mill yourself here // want to mill yourself here
// if (AI wants to mill self) // if (AI wants to mill self)
// tgt.addTarget(AllZone.getComputerPlayer()); // sa.getTargets().add(AllZone.getComputerPlayer());
// else // else
tgt.addTarget(opp); sa.getTargets().add(opp);
} }
return true; return true;
} }

View File

@@ -10,7 +10,7 @@ import forge.CardPredicates;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCombat; import forge.game.ai.ComputerUtilCombat;
import forge.game.phase.CombatUtil; import forge.game.phase.CombatUtil;
@@ -35,7 +35,7 @@ public class MustBlockAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(final Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(final Player ai, SpellAbility sa, boolean mandatory) {
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Target abTgt = sa.getTarget(); final TargetRestrictions abTgt = sa.getTargetRestrictions();
// only use on creatures that can attack // only use on creatures that can attack
if (!ai.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)) { if (!ai.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)) {
@@ -89,7 +89,7 @@ public class MustBlockAi extends SpellAbilityAi {
if (blocker == null) { if (blocker == null) {
return false; return false;
} }
abTgt.addTarget(blocker); sa.getTargets().add(blocker);
chance = true; chance = true;
} else { } else {
return false; return false;

View File

@@ -8,7 +8,7 @@ import forge.CardLists;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -22,7 +22,7 @@ public class PhasesAi extends SpellAbilityAi {
@Override @Override
protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) { protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) {
// This still needs to be fleshed out // This still needs to be fleshed out
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Random r = MyRandom.getRandom(); final Random r = MyRandom.getRandom();
@@ -51,7 +51,7 @@ public class PhasesAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player aiPlayer, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player aiPlayer, SpellAbility sa, boolean mandatory) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt == null) { if (tgt == null) {
return mandatory; return mandatory;
@@ -69,7 +69,7 @@ public class PhasesAi extends SpellAbilityAi {
@Override @Override
public boolean chkAIDrawback(SpellAbility sa, Player aiPlayer) { public boolean chkAIDrawback(SpellAbility sa, Player aiPlayer) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
boolean randomReturn = true; boolean randomReturn = true;
@@ -89,7 +89,7 @@ public class PhasesAi extends SpellAbilityAi {
* </p> * </p>
* *
* @param tgt * @param tgt
* a {@link forge.card.spellability.Target} object. * a {@link forge.card.spellability.TargetRestrictions} object.
* @param af * @param af
* a {@link forge.card.ability.AbilityFactory} object. * a {@link forge.card.ability.AbilityFactory} object.
* @param sa * @param sa
@@ -98,7 +98,7 @@ public class PhasesAi extends SpellAbilityAi {
* a boolean. * a boolean.
* @return 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) { final boolean mandatory) {
// Card source = sa.getSourceCard(); // 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) { private boolean phasesUnpreferredTargeting(final Game game, final SpellAbility sa, final boolean mandatory) {
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
List<Card> list = game.getCardsIn(ZoneType.Battlefield); List<Card> list = game.getCardsIn(ZoneType.Battlefield);
list = CardLists.getTargetableCards(CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source), sa); list = CardLists.getTargetableCards(CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source), sa);

View File

@@ -10,7 +10,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.player.Player; import forge.game.player.Player;
@@ -54,14 +54,14 @@ public class PlayAi extends SpellAbilityAi {
boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getRestrictions().getNumberTurnActivations()); boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getRestrictions().getNumberTurnActivations());
List<Card> cards; List<Card> cards;
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
ZoneType zone = tgt.getZone().get(0); ZoneType zone = tgt.getZone().get(0);
cards = CardLists.getValidCards(ai.getGame().getCardsIn(zone), tgt.getValidTgts(), ai, source); cards = CardLists.getValidCards(ai.getGame().getCardsIn(zone), tgt.getValidTgts(), ai, source);
if (cards.isEmpty()) { if (cards.isEmpty()) {
return false; return false;
} }
tgt.addTarget(ComputerUtilCard.getBestAI(cards)); sa.getTargets().add(ComputerUtilCard.getBestAI(cards));
} else if (!sa.hasParam("Valid")) { } else if (!sa.hasParam("Valid")) {
cards = new ArrayList<Card>(AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa)); cards = new ArrayList<Card>(AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa));
if (cards.isEmpty()) { if (cards.isEmpty()) {
@@ -87,7 +87,7 @@ public class PlayAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(final Player ai, final SpellAbility sa, final boolean mandatory) { 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 (tgt != null) {
return false; return false;
} }

View File

@@ -7,7 +7,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
@@ -59,11 +59,10 @@ public class PoisonAi extends SpellAbilityAi {
return false; return false;
} }
final Target tgt = sa.getTarget();
if (sa.getTarget() != null) { if (sa.usesTargeting()) {
tgt.resetTargets(); sa.resetTargets();
sa.getTarget().addTarget(ai.getOpponent()); sa.getTargets().add(ai.getOpponent());
} }
return true; return true;
@@ -72,9 +71,9 @@ public class PoisonAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
tgt.addTarget(ai.getOpponent()); sa.getTargets().add(ai.getOpponent());
} else { } else {
final List<Player> players = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa); final List<Player> players = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa);
for (final Player p : players) { for (final Player p : players) {

View File

@@ -12,7 +12,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
@@ -117,7 +117,7 @@ public class ProtectAi extends SpellAbilityAi {
final Card hostCard = sa.getSourceCard(); final Card hostCard = sa.getSourceCard();
final Game game = ai.getGame(); final Game game = ai.getGame();
// if there is no target and host card isn't in play, don't activate // 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; return false;
} }
@@ -153,7 +153,7 @@ public class ProtectAi extends SpellAbilityAi {
return false; return false;
} }
if ((sa.getTarget() == null) || !sa.getTarget().doesTarget()) { if ((sa.getTargetRestrictions() == null) || !sa.getTargetRestrictions().doesTarget()) {
final List<Card> cards = AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa); final List<Card> cards = AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa);
if (cards.size() == 0) { if (cards.size() == 0) {
@@ -182,8 +182,8 @@ public class ProtectAi extends SpellAbilityAi {
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
tgt.resetTargets(); sa.resetTargets();
List<Card> list = getProtectCreatures(ai, sa); List<Card> list = getProtectCreatures(ai, sa);
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard()); 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. // Don't target cards that will die.
list = ComputerUtil.getSafeTargets(ai, sa, list); list = ComputerUtil.getSafeTargets(ai, sa, list);
while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) {
Card t = null; Card t = null;
// boolean goodt = false; // boolean goodt = false;
if (list.isEmpty()) { 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) { if (mandatory) {
return protectMandatoryTarget(ai, sa, mandatory); return protectMandatoryTarget(ai, sa, mandatory);
} }
tgt.resetTargets(); sa.resetTargets();
return false; return false;
} else { } else {
// TODO is this good enough? for up to amounts? // TODO is this good enough? for up to amounts?
@@ -240,7 +240,7 @@ public class ProtectAi extends SpellAbilityAi {
} }
t = ComputerUtilCard.getBestCreatureAI(list); t = ComputerUtilCard.getBestCreatureAI(list);
tgt.addTarget(t); sa.getTargets().add(t);
list.remove(t); list.remove(t);
} }
@@ -251,16 +251,16 @@ public class ProtectAi extends SpellAbilityAi {
final Game game = ai.getGame(); final Game game = ai.getGame();
List<Card> list = game.getCardsIn(ZoneType.Battlefield); List<Card> 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()); list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard());
if (list.size() < tgt.getMinTargets(sa.getSourceCard(), sa)) { if (list.size() < tgt.getMinTargets(sa.getSourceCard(), sa)) {
tgt.resetTargets(); sa.resetTargets();
return false; return false;
} }
// Remove anything that's already been targeted // Remove anything that's already been targeted
for (final Card c : tgt.getTargetCards()) { for (final Card c : sa.getTargets().getTargetCards()) {
list.remove(c); list.remove(c);
} }
@@ -281,7 +281,7 @@ public class ProtectAi extends SpellAbilityAi {
final List<Card> forced = CardLists.filterControlledBy(list, ai); final List<Card> forced = CardLists.filterControlledBy(list, ai);
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) {
if (pref.isEmpty()) { if (pref.isEmpty()) {
break; break;
} }
@@ -295,10 +295,10 @@ public class ProtectAi extends SpellAbilityAi {
pref.remove(c); 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()) { if (pref2.isEmpty()) {
break; break;
} }
@@ -312,10 +312,10 @@ public class ProtectAi extends SpellAbilityAi {
pref2.remove(c); 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()) { if (forced.isEmpty()) {
break; break;
} }
@@ -329,11 +329,11 @@ public class ProtectAi extends SpellAbilityAi {
forced.remove(c); forced.remove(c);
tgt.addTarget(c); sa.getTargets().add(c);
} }
if (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { if (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) {
tgt.resetTargets(); sa.resetTargets();
return false; return false;
} }
@@ -342,7 +342,7 @@ public class ProtectAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
if (sa.getTarget() == null) { if (sa.getTargetRestrictions() == null) {
if (mandatory) { if (mandatory) {
return true; return true;
} }
@@ -356,7 +356,7 @@ public class ProtectAi extends SpellAbilityAi {
@Override @Override
public boolean chkAIDrawback(SpellAbility sa, Player ai) { public boolean chkAIDrawback(SpellAbility sa, Player ai) {
final Card host = sa.getSourceCard(); final Card host = sa.getSourceCard();
if ((sa.getTarget() == null) || !sa.getTarget().doesTarget()) { if ((sa.getTargetRestrictions() == null) || !sa.getTargetRestrictions().doesTarget()) {
if (host.isCreature()) { if (host.isCreature()) {
// TODO // TODO
} }

View File

@@ -14,7 +14,7 @@ public class ProtectAllAi extends SpellAbilityAi {
protected boolean canPlayAI(Player ai, SpellAbility sa) { protected boolean canPlayAI(Player ai, SpellAbility sa) {
final Card hostCard = sa.getSourceCard(); final Card hostCard = sa.getSourceCard();
// if there is no target and host card isn't in play, don't activate // 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; return false;
} }

View File

@@ -14,7 +14,7 @@ import forge.card.cost.CostPart;
import forge.card.cost.CostTapType; import forge.card.cost.CostTapType;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityRestriction; import forge.card.spellability.SpellAbilityRestriction;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
@@ -142,7 +142,7 @@ public class PumpAi extends PumpAiBase {
} }
//Untargeted //Untargeted
if ((sa.getTarget() == null) || !sa.getTarget().doesTarget()) { if ((sa.getTargetRestrictions() == null) || !sa.getTargetRestrictions().doesTarget()) {
final List<Card> cards = AbilityUtils.getDefinedCards(sa.getSourceCard(), final List<Card> cards = AbilityUtils.getDefinedCards(sa.getSourceCard(),
sa.getParam("Defined"), sa); sa.getParam("Defined"), sa);
@@ -192,8 +192,8 @@ public class PumpAi extends PumpAiBase {
} }
final Player opp = ai.getOpponent(); final Player opp = ai.getOpponent();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
tgt.resetTargets(); sa.resetTargets();
List<Card> list = new ArrayList<Card>(); List<Card> list = new ArrayList<Card>();
if (sa.hasParam("AILogic")) { if (sa.hasParam("AILogic")) {
if (sa.getParam("AILogic").equals("HighestPower")) { if (sa.getParam("AILogic").equals("HighestPower")) {
@@ -201,7 +201,7 @@ public class PumpAi extends PumpAiBase {
list = CardLists.getTargetableCards(list, sa); list = CardLists.getTargetableCards(list, sa);
CardLists.sortByPowerDesc(list); CardLists.sortByPowerDesc(list);
if (!list.isEmpty()) { if (!list.isEmpty()) {
tgt.addTarget(list.get(0)); sa.getTargets().add(list.get(0));
return true; return true;
} else { } else {
return false; return false;
@@ -209,7 +209,7 @@ public class PumpAi extends PumpAiBase {
} }
} else if (sa.isCurse()) { } else if (sa.isCurse()) {
if (sa.canTarget(opp)) { if (sa.canTarget(opp)) {
tgt.addTarget(opp); sa.getTargets().add(opp);
return true; return true;
} }
list = this.getCurseCreatures(ai, sa, defense, attack, keywords); 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); list = this.getPumpCreatures(ai, sa, defense, attack, keywords);
} }
if (sa.canTarget(ai)) { if (sa.canTarget(ai)) {
tgt.addTarget(ai); sa.getTargets().add(ai);
return true; return true;
} }
} }
@@ -251,17 +251,17 @@ public class PumpAi extends PumpAiBase {
list = ComputerUtil.getSafeTargets(ai, sa, list); 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; Card t = null;
// boolean goodt = false; // boolean goodt = false;
if (list.isEmpty()) { 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) { if (mandatory) {
return this.pumpMandatoryTarget(ai, sa, mandatory); return this.pumpMandatoryTarget(ai, sa, mandatory);
} }
tgt.resetTargets(); sa.resetTargets();
return false; return false;
} else { } else {
// TODO is this good enough? for up to amounts? // TODO is this good enough? for up to amounts?
@@ -270,7 +270,7 @@ public class PumpAi extends PumpAiBase {
} }
t = ComputerUtilCard.getBestAI(list); t = ComputerUtilCard.getBestAI(list);
tgt.addTarget(t); sa.getTargets().add(t);
list.remove(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) { private boolean pumpMandatoryTarget(final Player ai, final SpellAbility sa, final boolean mandatory) {
final Game game = ai.getGame(); final Game game = ai.getGame();
List<Card> list = game.getCardsIn(ZoneType.Battlefield); List<Card> list = game.getCardsIn(ZoneType.Battlefield);
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Player opp = ai.getOpponent(); final Player opp = ai.getOpponent();
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard()); list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard());
list = CardLists.getTargetableCards(list, sa); list = CardLists.getTargetableCards(list, sa);
if (list.size() < tgt.getMinTargets(sa.getSourceCard(), sa)) { if (list.size() < tgt.getMinTargets(sa.getSourceCard(), sa)) {
tgt.resetTargets(); sa.resetTargets();
return false; return false;
} }
// Remove anything that's already been targeted // Remove anything that's already been targeted
for (final Card c : tgt.getTargetCards()) { for (final Card c : sa.getTargets().getTargetCards()) {
list.remove(c); list.remove(c);
} }
@@ -307,7 +307,7 @@ public class PumpAi extends PumpAiBase {
forced = CardLists.filterControlledBy(list, opp); forced = CardLists.filterControlledBy(list, opp);
} }
while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) {
if (pref.isEmpty()) { if (pref.isEmpty()) {
break; break;
} }
@@ -321,10 +321,10 @@ public class PumpAi extends PumpAiBase {
pref.remove(c); 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()) { if (forced.isEmpty()) {
break; break;
} }
@@ -338,11 +338,11 @@ public class PumpAi extends PumpAiBase {
forced.remove(c); forced.remove(c);
tgt.addTarget(c); sa.getTargets().add(c);
} }
if (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { if (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) {
tgt.resetTargets(); sa.resetTargets();
return false; return false;
} }
@@ -381,7 +381,7 @@ public class PumpAi extends PumpAiBase {
attack = AbilityUtils.calculateAmount(sa.getSourceCard(), numAttack, sa); attack = AbilityUtils.calculateAmount(sa.getSourceCard(), numAttack, sa);
} }
if (sa.getTarget() == null) { if (sa.getTargetRestrictions() == null) {
if (mandatory) { if (mandatory) {
return true; return true;
} }
@@ -421,7 +421,7 @@ public class PumpAi extends PumpAiBase {
attack = AbilityUtils.calculateAmount(sa.getSourceCard(), numAttack, sa); 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.isCreature()) {
if (!source.hasKeyword("Indestructible") if (!source.hasKeyword("Indestructible")
&& ((source.getNetDefense() + defense) <= source.getDamage())) { && ((source.getNetDefense() + defense) <= source.getDamage())) {

View File

@@ -10,7 +10,7 @@ import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
@@ -49,10 +49,10 @@ public class PumpAllAi extends PumpAiBase {
List<Card> comp = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source); List<Card> comp = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source);
List<Card> human = CardLists.getValidCards(opp.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source); List<Card> 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")) { if (tgt != null && sa.canTarget(opp) && sa.hasParam("IsCurse")) {
tgt.resetTargets(); sa.resetTargets();
sa.getTarget().addTarget(opp); sa.getTargets().add(opp);
comp = new ArrayList<Card>(); comp = new ArrayList<Card>();
} }

View File

@@ -3,7 +3,7 @@ package forge.card.ability.ai;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player; import forge.game.player.Player;
public class RearrangeTopOfLibraryAi extends SpellAbilityAi { public class RearrangeTopOfLibraryAi extends SpellAbilityAi {
@@ -21,11 +21,11 @@ public class RearrangeTopOfLibraryAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
// ability is targeted // ability is targeted
tgt.resetTargets(); sa.resetTargets();
Player opp = ai.getOpponent(); Player opp = ai.getOpponent();
final boolean canTgtHuman = opp.canBeTargetedBy(sa); final boolean canTgtHuman = opp.canBeTargetedBy(sa);
@@ -33,7 +33,7 @@ public class RearrangeTopOfLibraryAi extends SpellAbilityAi {
if (!canTgtHuman) { if (!canTgtHuman) {
return false; return false;
} else { } else {
tgt.addTarget(opp); sa.getTargets().add(opp);
} }
} else { } else {
// if it's just defined, no big deal // if it's just defined, no big deal

View File

@@ -23,11 +23,12 @@ import java.util.List;
import forge.Card; import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.CardPredicates; import forge.CardPredicates;
import forge.ITargetable;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCard; 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) { if (tgt == null) {
// As far as I can tell these Defined Cards will only have one of // As far as I can tell these Defined Cards will only have one of
// them // them
final List<Card> list = AbilityUtils.getDefinedCards(hostCard, sa.getParam("Defined"), sa); final List<Card> list = AbilityUtils.getDefinedCards(hostCard, sa.getParam("Defined"), sa);
if (!game.getStack().isEmpty()) { if (!game.getStack().isEmpty()) {
final List<Object> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa); final List<ITargetable> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa);
for (final Card c : list) { for (final Card c : list) {
if (objects.contains(c)) { if (objects.contains(c)) {
@@ -108,7 +109,7 @@ public class RegenerateAi extends SpellAbilityAi {
} }
} }
} else { } else {
tgt.resetTargets(); sa.resetTargets();
// filter AIs battlefield by what I can target // filter AIs battlefield by what I can target
List<Card> targetables = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, hostCard); List<Card> targetables = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, hostCard);
targetables = CardLists.getTargetableCards(targetables, sa); targetables = CardLists.getTargetableCards(targetables, sa);
@@ -120,7 +121,7 @@ public class RegenerateAi extends SpellAbilityAi {
if (!game.getStack().isEmpty()) { if (!game.getStack().isEmpty()) {
// check stack for something on the stack will kill anything i // check stack for something on the stack will kill anything i
// control // control
final ArrayList<Object> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa); final List<ITargetable> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa);
final List<Card> threatenedTargets = new ArrayList<Card>(); final List<Card> threatenedTargets = new ArrayList<Card>();
@@ -132,7 +133,7 @@ public class RegenerateAi extends SpellAbilityAi {
if (!threatenedTargets.isEmpty()) { if (!threatenedTargets.isEmpty()) {
// Choose "best" of the remaining to regenerate // Choose "best" of the remaining to regenerate
tgt.addTarget(ComputerUtilCard.getBestCreatureAI(threatenedTargets)); sa.getTargets().add(ComputerUtilCard.getBestCreatureAI(threatenedTargets));
chance = true; chance = true;
} }
} else { } else {
@@ -142,14 +143,14 @@ public class RegenerateAi extends SpellAbilityAi {
for (final Card c : combatants) { for (final Card c : combatants) {
if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) { if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) {
tgt.addTarget(c); sa.getTargets().add(c);
chance = true; chance = true;
break; break;
} }
} }
} }
} }
if (tgt.getTargets().isEmpty()) { if (sa.getTargets().isEmpty()) {
return false; return false;
} }
} }
@@ -161,7 +162,7 @@ public class RegenerateAi extends SpellAbilityAi {
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
boolean chance = false; boolean chance = false;
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt == null) { if (tgt == null) {
// If there's no target on the trigger, just say yes. // If there's no target on the trigger, just say yes.
chance = true; chance = true;
@@ -175,8 +176,8 @@ public class RegenerateAi extends SpellAbilityAi {
private static boolean regenMandatoryTarget(final Player ai, final SpellAbility sa, final boolean mandatory) { private static boolean regenMandatoryTarget(final Player ai, final SpellAbility sa, final boolean mandatory) {
final Card hostCard = sa.getSourceCard(); final Card hostCard = sa.getSourceCard();
final Game game = ai.getGame(); final Game game = ai.getGame();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
tgt.resetTargets(); sa.resetTargets();
// filter AIs battlefield by what I can target // filter AIs battlefield by what I can target
List<Card> targetables = game.getCardsIn(ZoneType.Battlefield); List<Card> targetables = game.getCardsIn(ZoneType.Battlefield);
targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), ai, hostCard); 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)) { if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
for (final Card c : combatants) { for (final Card c : combatants) {
if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) { if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) {
tgt.addTarget(c); sa.getTargets().add(c);
return true; return true;
} }
} }
@@ -210,26 +211,26 @@ public class RegenerateAi extends SpellAbilityAi {
if (CardLists.getNotType(compTargetables, "Creature").isEmpty()) { if (CardLists.getNotType(compTargetables, "Creature").isEmpty()) {
for (final Card c : combatants) { for (final Card c : combatants) {
if (c.getShield() == 0) { if (c.getShield() == 0) {
tgt.addTarget(c); sa.getTargets().add(c);
return true; return true;
} }
} }
tgt.addTarget(combatants.get(0)); sa.getTargets().add(combatants.get(0));
return true; return true;
} else { } else {
CardLists.sortByCmcDesc(compTargetables); CardLists.sortByCmcDesc(compTargetables);
for (final Card c : compTargetables) { for (final Card c : compTargetables) {
if (c.getShield() == 0) { if (c.getShield() == 0) {
tgt.addTarget(c); sa.getTargets().add(c);
return true; return true;
} }
} }
tgt.addTarget(compTargetables.get(0)); sa.getTargets().add(compTargetables.get(0));
return true; return true;
} }
} }
tgt.addTarget(ComputerUtilCard.getCheapestPermanentAI(targetables, sa, true)); sa.getTargets().add(ComputerUtilCard.getCheapestPermanentAI(targetables, sa, true));
return true; return true;
} }

View File

@@ -1,11 +1,11 @@
package forge.card.ability.ai; package forge.card.ability.ai;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import forge.Card; import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.CardPredicates; import forge.CardPredicates;
import forge.ITargetable;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
@@ -57,7 +57,7 @@ public class RegenerateAllAi extends SpellAbilityAi {
int numSaved = 0; int numSaved = 0;
if (!game.getStack().isEmpty()) { if (!game.getStack().isEmpty()) {
final ArrayList<Object> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa); final List<ITargetable> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa);
for (final Card c : list) { for (final Card c : list) {
if (objects.contains(c) && c.getShield() == 0) { if (objects.contains(c) && c.getShield() == 0) {

View File

@@ -3,7 +3,7 @@ package forge.card.ability.ai;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode; import forge.game.player.PlayerActionConfirmMode;
@@ -11,14 +11,14 @@ public class RepeatAi extends SpellAbilityAi {
@Override @Override
protected boolean canPlayAI(Player ai, SpellAbility sa) { protected boolean canPlayAI(Player ai, SpellAbility sa) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Player opp = ai.getOpponent(); final Player opp = ai.getOpponent();
if (tgt != null) { if (tgt != null) {
if (!opp.canBeTargetedBy(sa)) { if (!opp.canBeTargetedBy(sa)) {
return false; return false;
} }
tgt.resetTargets(); sa.resetTargets();
tgt.addTarget(opp); sa.getTargets().add(opp);
} }
return true; return true;
} }

View File

@@ -11,7 +11,6 @@ import forge.CardPredicates.Presets;
import forge.CounterType; import forge.CounterType;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -57,7 +56,6 @@ public class RepeatEachAi extends SpellAbilityAi {
sa.setTargetCard(perms.get(0)); sa.setTargetCard(perms.get(0));
} else if ("RemoveAllCounters".equals(logic)) { } else if ("RemoveAllCounters".equals(logic)) {
// Break Dark Depths // Break Dark Depths
Target tgt = sa.getTarget();
List<Card> depthsList = aiPlayer.getCardsIn(ZoneType.Battlefield, "Dark Depths"); List<Card> depthsList = aiPlayer.getCardsIn(ZoneType.Battlefield, "Dark Depths");
depthsList = CardLists.filter(depthsList, new Predicate<Card>() { depthsList = CardLists.filter(depthsList, new Predicate<Card>() {
@Override @Override
@@ -67,7 +65,7 @@ public class RepeatEachAi extends SpellAbilityAi {
}); });
if (depthsList.size() > 0) { if (depthsList.size() > 0) {
tgt.addTarget(depthsList.get(0)); sa.getTargets().add(depthsList.get(0));
return true; return true;
} }
@@ -84,7 +82,7 @@ public class RepeatEachAi extends SpellAbilityAi {
return false; return false;
} }
tgt.addTarget(list.get(0)); sa.getTargets().add(list.get(0));
} else if ("BalanceLands".equals(logic)) { } else if ("BalanceLands".equals(logic)) {
if (CardLists.filter(aiPlayer.getCardsIn(ZoneType.Battlefield), Presets.LANDS).size() >= 5) { if (CardLists.filter(aiPlayer.getCardsIn(ZoneType.Battlefield), Presets.LANDS).size() >= 5) {
return false; return false;

View File

@@ -3,28 +3,28 @@ package forge.card.ability.ai;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
public abstract class RevealAiBase extends SpellAbilityAi { public abstract class RevealAiBase extends SpellAbilityAi {
protected boolean revealHandTargetAI(final Player ai, final SpellAbility sa) { protected boolean revealHandTargetAI(final Player ai, final SpellAbility sa) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
Player opp = ai.getOpponent(); Player opp = ai.getOpponent();
final int humanHandSize = opp.getCardsIn(ZoneType.Hand).size(); final int humanHandSize = opp.getCardsIn(ZoneType.Hand).size();
if (tgt != null) { if (tgt != null) {
// ability is targeted // ability is targeted
tgt.resetTargets(); sa.resetTargets();
final boolean canTgtHuman = opp.canBeTargetedBy(sa); final boolean canTgtHuman = opp.canBeTargetedBy(sa);
if (!canTgtHuman || (humanHandSize == 0)) { if (!canTgtHuman || (humanHandSize == 0)) {
return false; return false;
} else { } else {
tgt.addTarget(opp); sa.getTargets().add(opp);
} }
} else { } else {
// if it's just defined, no big deal // if it's just defined, no big deal

View File

@@ -8,7 +8,7 @@ import forge.CardPredicates;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilMana; import forge.game.ai.ComputerUtilMana;
import forge.game.player.Player; import forge.game.player.Player;
@@ -50,16 +50,16 @@ public class SacrificeAi extends SpellAbilityAi {
private boolean sacrificeTgtAI(final Player ai, final SpellAbility sa) { private boolean sacrificeTgtAI(final Player ai, final SpellAbility sa) {
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final boolean destroy = sa.hasParam("Destroy"); final boolean destroy = sa.hasParam("Destroy");
Player opp = ai.getOpponent(); Player opp = ai.getOpponent();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
if (!opp.canBeTargetedBy(sa)) { if (!opp.canBeTargetedBy(sa)) {
return false; return false;
} }
tgt.addTarget(opp); sa.getTargets().add(opp);
final String valid = sa.getParam("SacValid"); final String valid = sa.getParam("SacValid");
String num = sa.getParam("Amount"); String num = sa.getParam("Amount");
num = (num == null) ? "1" : num; num = (num == null) ? "1" : num;

View File

@@ -4,7 +4,7 @@ import java.util.Random;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player; import forge.game.player.Player;
import forge.util.MyRandom; import forge.util.MyRandom;
@@ -15,13 +15,13 @@ public class ScryAi extends SpellAbilityAi {
*/ */
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { 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 if (tgt != null) { // It doesn't appear that Scry ever targets
// ability is targeted // ability is targeted
tgt.resetTargets(); sa.resetTargets();
tgt.addTarget(ai); sa.getTargets().add(ai);
} }
return true; return true;

View File

@@ -8,7 +8,7 @@ import forge.game.player.Player;
public class SetStateAi extends SpellAbilityAi { public class SetStateAi extends SpellAbilityAi {
@Override @Override
protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) { 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 true;
} }
return false; return false;

View File

@@ -7,7 +7,7 @@ import forge.Card;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
@@ -31,7 +31,7 @@ public class TapAi extends TapAiBase {
return false; return false;
} }
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Random r = MyRandom.getRandom(); final Random r = MyRandom.getRandom();
@@ -49,7 +49,7 @@ public class TapAi extends TapAiBase {
return false; return false;
} }
} else { } else {
tgt.resetTargets(); sa.resetTargets();
if (!tapPrefTargeting(ai, source, tgt, sa, false)) { if (!tapPrefTargeting(ai, source, tgt, sa, false)) {
return false; return false;
} }

View File

@@ -11,7 +11,7 @@ import forge.CardPredicates;
import forge.CardPredicates.Presets; import forge.CardPredicates.Presets;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCard; 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<Card> tapList, final boolean mandatory) { private boolean tapTargetList(final Player ai, final SpellAbility sa, final List<Card> tapList, final boolean mandatory) {
final Card source = sa.getSourceCard(); 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); tapList.remove(c);
} }
@@ -50,13 +50,13 @@ public abstract class TapAiBase extends SpellAbilityAi {
return false; return false;
} }
while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) {
Card choice = null; Card choice = null;
if (tapList.size() == 0) { 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) { if (!mandatory) {
tgt.resetTargets(); sa.resetTargets();
} }
return false; return false;
} else { } else {
@@ -75,9 +75,9 @@ public abstract class TapAiBase extends SpellAbilityAi {
} }
if (choice == null) { // can't find anything left 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) { if (!mandatory) {
tgt.resetTargets(); sa.resetTargets();
} }
return false; return false;
} else { } else {
@@ -89,7 +89,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
} }
tapList.remove(choice); tapList.remove(choice);
tgt.addTarget(choice); sa.getTargets().add(choice);
} }
return true; return true;
@@ -103,7 +103,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
* @param source * @param source
* a {@link forge.Card} object. * a {@link forge.Card} object.
* @param tgt * @param tgt
* a {@link forge.card.spellability.Target} object. * a {@link forge.card.spellability.TargetRestrictions} object.
* @param af * @param af
* a {@link forge.card.ability.AbilityFactory} object. * a {@link forge.card.ability.AbilityFactory} object.
* @param sa * @param sa
@@ -112,7 +112,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
* a boolean. * a boolean.
* @return 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 Player opp = ai.getOpponent();
final Game game = ai.getGame(); final Game game = ai.getGame();
List<Card> tapList = opp.getCardsIn(ZoneType.Battlefield); List<Card> tapList = opp.getCardsIn(ZoneType.Battlefield);
@@ -142,13 +142,13 @@ public abstract class TapAiBase extends SpellAbilityAi {
return false; return false;
} }
while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) {
Card choice = null; Card choice = null;
if (tapList.size() == 0) { 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) { if (!mandatory) {
tgt.resetTargets(); sa.resetTargets();
} }
return false; return false;
} else { } else {
@@ -204,9 +204,9 @@ public abstract class TapAiBase extends SpellAbilityAi {
} }
if (choice == null) { // can't find anything left 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) { if (!mandatory) {
tgt.resetTargets(); sa.resetTargets();
} }
return false; return false;
} else { } else {
@@ -218,7 +218,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
} }
tapList.remove(choice); tapList.remove(choice);
tgt.addTarget(choice); sa.getTargets().add(choice);
} }
return true; return true;
@@ -239,7 +239,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
*/ */
protected boolean tapUnpreferredTargeting(final Player ai, final SpellAbility sa, final boolean mandatory) { protected boolean tapUnpreferredTargeting(final Player ai, final SpellAbility sa, final boolean mandatory) {
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Game game = ai.getGame(); final Game game = ai.getGame();
List<Card> list = game.getCardsIn(ZoneType.Battlefield); List<Card> list = game.getCardsIn(ZoneType.Battlefield);
@@ -280,7 +280,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { 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 Card source = sa.getSourceCard();
if (tgt == null) { if (tgt == null) {
@@ -292,7 +292,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
return true; return true;
} else { } else {
tgt.resetTargets(); sa.resetTargets();
if (tapPrefTargeting(ai, source, tgt, sa, mandatory)) { if (tapPrefTargeting(ai, source, tgt, sa, mandatory)) {
return true; return true;
} else if (mandatory) { } else if (mandatory) {
@@ -306,7 +306,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
@Override @Override
public boolean chkAIDrawback(SpellAbility sa, Player ai) { public boolean chkAIDrawback(SpellAbility sa, Player ai) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
boolean randomReturn = true; boolean randomReturn = true;
@@ -315,7 +315,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
// either self or defined, either way should be fine // either self or defined, either way should be fine
} else { } else {
// target section, maybe pull this out? // target section, maybe pull this out?
tgt.resetTargets(); sa.resetTargets();
if (!tapPrefTargeting(ai, source, tgt, sa, false)) { if (!tapPrefTargeting(ai, source, tgt, sa, false)) {
return false; return false;
} }

View File

@@ -11,7 +11,7 @@ import forge.CardLists;
import forge.CardPredicates.Presets; import forge.CardPredicates.Presets;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.phase.CombatUtil; import forge.game.phase.CombatUtil;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
@@ -45,11 +45,9 @@ public class TapAllAi extends SpellAbilityAi {
List<Card> validTappables = game.getCardsIn(ZoneType.Battlefield); List<Card> validTappables = game.getCardsIn(ZoneType.Battlefield);
final Target tgt = sa.getTarget(); if (sa.usesTargeting()) {
sa.resetTargets();
if (sa.getTarget() != null) { sa.getTargets().add(opp);
tgt.resetTargets();
tgt.addTarget(opp);
validTappables = opp.getCardsIn(ZoneType.Battlefield); validTappables = opp.getCardsIn(ZoneType.Battlefield);
} }
@@ -126,11 +124,11 @@ public class TapAllAi extends SpellAbilityAi {
List<Card> validTappables = getTapAllTargets(valid, source); List<Card> validTappables = getTapAllTargets(valid, source);
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
tgt.addTarget(ai.getOpponent()); sa.getTargets().add(ai.getOpponent());
validTappables = ai.getOpponent().getCardsIn(ZoneType.Battlefield); validTappables = ai.getOpponent().getCardsIn(ZoneType.Battlefield);
} }

View File

@@ -6,7 +6,7 @@ import java.util.Random;
import forge.Card; import forge.Card;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player; import forge.game.player.Player;
import forge.util.MyRandom; import forge.util.MyRandom;
@@ -17,7 +17,7 @@ public class TapOrUntapAi extends TapAiBase {
*/ */
@Override @Override
protected boolean canPlayAI(Player ai, SpellAbility sa) { protected boolean canPlayAI(Player ai, SpellAbility sa) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Random r = MyRandom.getRandom(); final Random r = MyRandom.getRandom();
@@ -38,7 +38,7 @@ public class TapOrUntapAi extends TapAiBase {
return false; return false;
} }
} else { } else {
tgt.resetTargets(); sa.resetTargets();
if (!tapPrefTargeting(ai, source, tgt, sa, false)) { if (!tapPrefTargeting(ai, source, tgt, sa, false)) {
return false; return false;
} }

View File

@@ -7,7 +7,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
@@ -126,13 +126,13 @@ public class TokenAi extends SpellAbilityAi {
final Random r = MyRandom.getRandom(); final Random r = MyRandom.getRandom();
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
if (tgt.canOnlyTgtOpponent() || "Opponent".equals(sa.getParam("AITgts"))) { if (tgt.canOnlyTgtOpponent() || "Opponent".equals(sa.getParam("AITgts"))) {
tgt.addTarget(opp); sa.getTargets().add(opp);
} else { } 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) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
readParameters(sa); readParameters(sa);
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
if (tgt.canOnlyTgtOpponent()) { if (tgt.canOnlyTgtOpponent()) {
tgt.addTarget(ai.getOpponent()); sa.getTargets().add(ai.getOpponent());
} else { } else {
tgt.addTarget(ai); sa.getTargets().add(ai);
} }
} }
if ("X".equals(this.tokenAmount) || "X".equals(this.tokenPower) || "X".equals(this.tokenToughness)) { if ("X".equals(this.tokenAmount) || "X".equals(this.tokenPower) || "X".equals(this.tokenToughness)) {

View File

@@ -8,7 +8,7 @@ import forge.CardLists;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -31,20 +31,19 @@ public class TwoPilesAi extends SpellAbilityAi {
valid = sa.getParam("ValidCards"); valid = sa.getParam("ValidCards");
} }
List<Player> tgtPlayers;
final Player opp = ai.getOpponent(); final Player opp = ai.getOpponent();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
if (tgt.canTgtPlayer()) { if (tgt.canTgtPlayer()) {
tgt.addTarget(opp); sa.getTargets().add(opp);
} }
tgtPlayers = tgt.getTargetPlayers();
} else {
tgtPlayers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa);
} }
List<Player> tgtPlayers = getTargetPlayers(sa);
final Player p = tgtPlayers.get(0); final Player p = tgtPlayers.get(0);
List<Card> pool = new ArrayList<Card>(); List<Card> pool = new ArrayList<Card>();
if (sa.hasParam("DefinedCards")) { if (sa.hasParam("DefinedCards")) {

View File

@@ -10,7 +10,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilMana; import forge.game.ai.ComputerUtilMana;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
@@ -36,9 +36,9 @@ public class UnattachAllAi extends SpellAbilityAi {
boolean chance = r.nextFloat() <= .9; boolean chance = r.nextFloat() <= .9;
// Attach spells always have a target // Attach spells always have a target
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
tgt.resetTargets(); sa.resetTargets();
} }
if (abCost != null && abCost.getTotalMana().countX() > 0 && source.getSVar("X").equals("Count$xPaid")) { 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(); final Player opp = ai.getOpponent();
// Check if there are any valid targets // Check if there are any valid targets
List<ITargetable> targets = new ArrayList<ITargetable>(); List<ITargetable> targets = new ArrayList<ITargetable>();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt == null) { if (tgt == null) {
targets = AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam("Defined"), sa); targets = AbilityUtils.getDefinedObjects(sa.getSourceCard(), sa.getParam("Defined"), sa);
} }

View File

@@ -10,7 +10,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.player.Player; import forge.game.player.Player;
@@ -24,7 +24,7 @@ public class UntapAi extends SpellAbilityAi {
*/ */
@Override @Override
protected boolean canPlayAI(Player ai, SpellAbility sa) { protected boolean canPlayAI(Player ai, SpellAbility sa) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Cost cost = sa.getPayCosts(); final Cost cost = sa.getPayCosts();
@@ -51,7 +51,7 @@ public class UntapAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt == null) { if (tgt == null) {
if (mandatory) { if (mandatory) {
@@ -79,7 +79,7 @@ public class UntapAi extends SpellAbilityAi {
@Override @Override
public boolean chkAIDrawback(SpellAbility sa, Player ai) { public boolean chkAIDrawback(SpellAbility sa, Player ai) {
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
boolean randomReturn = true; boolean randomReturn = true;
@@ -100,7 +100,7 @@ public class UntapAi extends SpellAbilityAi {
* </p> * </p>
* *
* @param tgt * @param tgt
* a {@link forge.card.spellability.Target} object. * a {@link forge.card.spellability.TargetRestrictions} object.
* @param af * @param af
* a {@link forge.card.ability.AbilityFactory} object. * a {@link forge.card.ability.AbilityFactory} object.
* @param sa * @param sa
@@ -109,7 +109,7 @@ public class UntapAi extends SpellAbilityAi {
* a boolean. * a boolean.
* @return 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(); final Card source = sa.getSourceCard();
Player targetController = ai; Player targetController = ai;
@@ -132,12 +132,12 @@ public class UntapAi extends SpellAbilityAi {
return false; return false;
} }
while (tgt.getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) { while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) {
Card choice = null; Card choice = null;
if (untapList.size() == 0) { if (untapList.size() == 0) {
if ((tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (tgt.getNumTargeted() == 0)) { if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (sa.getTargets().getNumTargeted() == 0)) {
tgt.resetTargets(); sa.resetTargets();
return false; return false;
} else { } else {
// TODO is this good enough? for up to amounts? // 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 (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)) {
tgt.resetTargets(); sa.resetTargets();
return false; return false;
} else { } else {
// TODO is this good enough? for up to amounts? // TODO is this good enough? for up to amounts?
@@ -167,7 +167,7 @@ public class UntapAi extends SpellAbilityAi {
} }
untapList.remove(choice); untapList.remove(choice);
tgt.addTarget(choice); sa.getTargets().add(choice);
} }
return true; return true;
} }
@@ -187,7 +187,7 @@ public class UntapAi extends SpellAbilityAi {
*/ */
private boolean untapUnpreferredTargeting(final SpellAbility sa, final boolean mandatory) { private boolean untapUnpreferredTargeting(final SpellAbility sa, final boolean mandatory) {
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
List<Card> list = sa.getActivatingPlayer().getGame().getCardsIn(ZoneType.Battlefield); List<Card> list = sa.getActivatingPlayer().getGame().getCardsIn(ZoneType.Battlefield);
@@ -228,7 +228,7 @@ public class UntapAi extends SpellAbilityAi {
* @param source * @param source
* a {@link forge.Card} object. * a {@link forge.Card} object.
* @param tgt * @param tgt
* a {@link forge.card.spellability.Target} object. * a {@link forge.card.spellability.TargetRestrictions} object.
* @param af * @param af
* a {@link forge.card.ability.AbilityFactory} object. * a {@link forge.card.ability.AbilityFactory} object.
* @param sa * @param sa
@@ -239,8 +239,9 @@ public class UntapAi extends SpellAbilityAi {
* a {@link forge.CardList} object. * a {@link forge.CardList} object.
* @return a boolean. * @return a boolean.
*/ */
private boolean untapTargetList(final Card source, final Target tgt, final SpellAbility sa, final boolean mandatory, final List<Card> tapList) { private boolean untapTargetList(final Card source, final TargetRestrictions tgt, final SpellAbility sa, final boolean mandatory, final List<Card> tapList) {
for (final Card c : tgt.getTargetCards()) {
for (final Card c : sa.getTargets().getTargetCards()) {
tapList.remove(c); tapList.remove(c);
} }
@@ -248,13 +249,13 @@ public class UntapAi extends SpellAbilityAi {
return false; return false;
} }
while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) {
Card choice = null; Card choice = null;
if (tapList.size() == 0) { 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) { if (!mandatory) {
tgt.resetTargets(); sa.resetTargets();
} }
return false; return false;
} else { } else {
@@ -274,9 +275,9 @@ public class UntapAi extends SpellAbilityAi {
} }
if (choice == null) { // can't find anything left 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) { if (!mandatory) {
tgt.resetTargets(); sa.resetTargets();
} }
return false; return false;
} else { } else {
@@ -286,7 +287,7 @@ public class UntapAi extends SpellAbilityAi {
} }
tapList.remove(choice); tapList.remove(choice);
tgt.addTarget(choice); sa.getTargets().add(choice);
} }
return true; return true;

View File

@@ -5,7 +5,6 @@ import java.util.List;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityEffect; import forge.card.ability.SpellAbilityEffect;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.game.phase.ExtraTurn; import forge.game.phase.ExtraTurn;
import forge.game.player.Player; import forge.game.player.Player;
@@ -39,17 +38,10 @@ public class AddTurnEffect extends SpellAbilityEffect {
public void resolve(SpellAbility sa) { public void resolve(SpellAbility sa) {
final int numTurns = AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("NumTurns"), sa); final int numTurns = AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("NumTurns"), sa);
List<Player> tgtPlayers; List<Player> tgtPlayers = getTargetPlayers(sa);
final Target tgt = sa.getTarget();
if (tgt != null) {
tgtPlayers = tgt.getTargetPlayers();
} else {
tgtPlayers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa);
}
for (final Player p : tgtPlayers) { 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++) { for (int i = 0; i < numTurns; i++) {
ExtraTurn extra = p.getGame().getPhaseHandler().addExtraTurn(p); ExtraTurn extra = p.getGame().getPhaseHandler().addExtraTurn(p);
if (sa.hasParam("LoseAtEndStep")) { if (sa.hasParam("LoseAtEndStep")) {

View File

@@ -14,7 +14,6 @@ import forge.card.ability.AbilityFactory;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.replacement.ReplacementEffect; import forge.card.replacement.ReplacementEffect;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.card.staticability.StaticAbility; import forge.card.staticability.StaticAbility;
import forge.card.trigger.Trigger; import forge.card.trigger.Trigger;
import forge.card.trigger.TriggerHandler; import forge.card.trigger.TriggerHandler;
@@ -121,15 +120,7 @@ public class AnimateAllEffect extends AnimateEffectBase {
} }
List<Card> list; List<Card> list;
List<Player> tgtPlayers = null; List<Player> tgtPlayers = getTargetPlayers(sa);
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);
}
if ((tgtPlayers == null) || tgtPlayers.isEmpty()) { if ((tgtPlayers == null) || tgtPlayers.isEmpty()) {
list = game.getCardsIn(ZoneType.Battlefield); list = game.getCardsIn(ZoneType.Battlefield);

View File

@@ -13,7 +13,6 @@ import forge.card.ability.AbilityFactory;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.replacement.ReplacementEffect; import forge.card.replacement.ReplacementEffect;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.card.staticability.StaticAbility; import forge.card.staticability.StaticAbility;
import forge.card.trigger.Trigger; import forge.card.trigger.Trigger;
import forge.card.trigger.TriggerHandler; import forge.card.trigger.TriggerHandler;
@@ -27,8 +26,7 @@ public class AnimateEffect extends AnimateEffectBase {
@Override @Override
public void resolve(final SpellAbility sa) { public void resolve(final SpellAbility sa) {
final Card source = sa.getSourceCard(); final Card source = sa.getSourceCard();
final Card host = sa.getSourceCard(); final Map<String, String> svars = source.getSVars();
final Map<String, String> svars = host.getSVars();
String animateRemembered = null; String animateRemembered = null;
@@ -46,11 +44,11 @@ public class AnimateEffect extends AnimateEffectBase {
// AF specific sa // AF specific sa
int power = -1; int power = -1;
if (sa.hasParam("Power")) { if (sa.hasParam("Power")) {
power = AbilityUtils.calculateAmount(host, sa.getParam("Power"), sa); power = AbilityUtils.calculateAmount(source, sa.getParam("Power"), sa);
} }
int toughness = -1; int toughness = -1;
if (sa.hasParam("Toughness")) { 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(); final Game game = sa.getActivatingPlayer().getGame();
@@ -74,7 +72,7 @@ public class AnimateEffect extends AnimateEffectBase {
// allow ChosenType - overrides anything else specified // allow ChosenType - overrides anything else specified
if (types.contains("ChosenType")) { if (types.contains("ChosenType")) {
types.clear(); types.clear();
types.add(host.getChosenType()); types.add(source.getChosenType());
} }
final ArrayList<String> keywords = new ArrayList<String>(); final ArrayList<String> keywords = new ArrayList<String>();
@@ -106,7 +104,7 @@ public class AnimateEffect extends AnimateEffectBase {
final String colors = sa.getParam("Colors"); final String colors = sa.getParam("Colors");
if (colors.equals("ChosenColor")) { if (colors.equals("ChosenColor")) {
tmpDesc = CardUtil.getShortColorsString(host.getChosenColor()); tmpDesc = CardUtil.getShortColorsString(source.getChosenColor());
} else { } else {
tmpDesc = CardUtil.getShortColorsString(new ArrayList<String>(Arrays.asList(colors.split(",")))); tmpDesc = CardUtil.getShortColorsString(new ArrayList<String>(Arrays.asList(colors.split(","))));
} }
@@ -137,8 +135,7 @@ public class AnimateEffect extends AnimateEffectBase {
sVars.addAll(Arrays.asList(sa.getParam("sVars").split(","))); sVars.addAll(Arrays.asList(sa.getParam("sVars").split(",")));
} }
final Target tgt = sa.getTarget(); List<Card> tgts = getTargetCards(sa);
List<Card> tgts = tgt != null ? tgts = tgt.getTargetCards() : AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa);
for (final Card c : tgts) { for (final Card c : tgts) {
@@ -165,7 +162,7 @@ public class AnimateEffect extends AnimateEffectBase {
final ArrayList<SpellAbility> addedAbilities = new ArrayList<SpellAbility>(); final ArrayList<SpellAbility> addedAbilities = new ArrayList<SpellAbility>();
if (abilities.size() > 0) { if (abilities.size() > 0) {
for (final String s : abilities) { for (final String s : abilities) {
final String actualAbility = host.getSVar(s); final String actualAbility = source.getSVar(s);
final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, c); final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, c);
addedAbilities.add(grantedAbility); addedAbilities.add(grantedAbility);
c.addSpellAbility(grantedAbility); c.addSpellAbility(grantedAbility);
@@ -176,7 +173,7 @@ public class AnimateEffect extends AnimateEffectBase {
final ArrayList<Trigger> addedTriggers = new ArrayList<Trigger>(); final ArrayList<Trigger> addedTriggers = new ArrayList<Trigger>();
if (triggers.size() > 0) { if (triggers.size() > 0) {
for (final String s : triggers) { 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); final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, c, false);
addedTriggers.add(c.addTrigger(parsedTrigger)); addedTriggers.add(c.addTrigger(parsedTrigger));
} }
@@ -196,7 +193,7 @@ public class AnimateEffect extends AnimateEffectBase {
// itself a static ability) // itself a static ability)
if (stAbs.size() > 0) { if (stAbs.size() > 0) {
for (final String s : stAbs) { for (final String s : stAbs) {
final String actualAbility = host.getSVar(s); final String actualAbility = source.getSVar(s);
c.addStaticAbility(actualAbility); c.addStaticAbility(actualAbility);
} }
} }
@@ -204,7 +201,7 @@ public class AnimateEffect extends AnimateEffectBase {
// give sVars // give sVars
if (sVars.size() > 0) { if (sVars.size() > 0) {
for (final String s : sVars) { for (final String s : sVars) {
final String actualsVar = host.getSVar(s); final String actualsVar = source.getSVar(s);
c.setSVar(s, actualsVar); c.setSVar(s, actualsVar);
} }
} }
@@ -230,7 +227,7 @@ public class AnimateEffect extends AnimateEffectBase {
// give Remembered // give Remembered
if (animateRemembered != null) { if (animateRemembered != null) {
for (final Object o : AbilityUtils.getDefinedObjects(host, animateRemembered, sa)) { for (final Object o : AbilityUtils.getDefinedObjects(source, animateRemembered, sa)) {
c.addRemembered(o); c.addRemembered(o);
} }
} }
@@ -266,13 +263,13 @@ public class AnimateEffect extends AnimateEffectBase {
if (sa.hasParam("UntilEndOfCombat")) { if (sa.hasParam("UntilEndOfCombat")) {
game.getEndOfCombat().addUntil(unanimate); game.getEndOfCombat().addUntil(unanimate);
} else if (sa.hasParam("UntilHostLeavesPlay")) { } else if (sa.hasParam("UntilHostLeavesPlay")) {
host.addLeavesPlayCommand(unanimate); source.addLeavesPlayCommand(unanimate);
} else if (sa.hasParam("UntilYourNextUpkeep")) { } else if (sa.hasParam("UntilYourNextUpkeep")) {
game.getUpkeep().addUntil(host.getController(), unanimate); game.getUpkeep().addUntil(source.getController(), unanimate);
} else if (sa.hasParam("UntilControllerNextUntap")) { } else if (sa.hasParam("UntilControllerNextUntap")) {
game.getUntap().addUntil(c.getController(), unanimate); game.getUntap().addUntil(c.getController(), unanimate);
} else if (sa.hasParam("UntilYourNextTurn")) { } else if (sa.hasParam("UntilYourNextTurn")) {
game.getCleanup().addUntil(host.getController(), unanimate); game.getCleanup().addUntil(source.getController(), unanimate);
} else { } else {
game.getEndOfTurn().addUntil(unanimate); game.getEndOfTurn().addUntil(unanimate);
} }
@@ -321,8 +318,7 @@ public class AnimateEffect extends AnimateEffectBase {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
final Target tgt = sa.getTarget(); final List<Card> tgts = getTargetCards(sa);
final List<Card> tgts = tgt != null ? tgt.getTargetCards() : AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa);
for (final Card c : tgts) { for (final Card c : tgts) {
sb.append(c).append(" "); sb.append(c).append(" ");

View File

@@ -12,10 +12,11 @@ import forge.card.ability.AbilityUtils;
import forge.card.ability.ApiType; import forge.card.ability.ApiType;
import forge.card.ability.SpellAbilityEffect; import forge.card.ability.SpellAbilityEffect;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.util.Lang;
public class AttachEffect extends SpellAbilityEffect { public class AttachEffect extends SpellAbilityEffect {
@@ -38,7 +39,7 @@ public class AttachEffect extends SpellAbilityEffect {
Card source = sa.getSourceCard(); Card source = sa.getSourceCard();
Card card = sa.getSourceCard(); Card card = sa.getSourceCard();
final List<ITargetable> targets = getTargetObjects(sa); final List<ITargetable> targets = getTargets(sa);
if (sa.hasParam("Object")) { if (sa.hasParam("Object")) {
card = AbilityUtils.getDefinedCards(source, sa.getParam("Object"), sa).get(0); card = AbilityUtils.getDefinedCards(source, sa.getParam("Object"), sa).get(0);
@@ -61,13 +62,10 @@ public class AttachEffect extends SpellAbilityEffect {
sb.append(" Attach to "); sb.append(" Attach to ");
final List<ITargetable> targets = getTargetObjects(sa); final List<ITargetable> targets = getTargets(sa);
// Should never allow more than one Attachment per card // Should never allow more than one Attachment per card
for (final Object o : targets) { sb.append(Lang.joinHomogenous(targets));
sb.append(o).append(" ");
}
return sb.toString(); return sb.toString();
} }
@@ -179,7 +177,7 @@ public class AttachEffect extends SpellAbilityEffect {
} }
aura.setActivatingPlayer(source.getController()); aura.setActivatingPlayer(source.getController());
final Game game = source.getGame(); final Game game = source.getGame();
final Target tgt = aura.getTarget(); final TargetRestrictions tgt = aura.getTargetRestrictions();
Player p = source.getController(); Player p = source.getController();
if (tgt.canTgtPlayer()) { if (tgt.canTgtPlayer()) {

View File

@@ -11,7 +11,7 @@ import forge.card.ability.SpellAbilityEffect;
import forge.card.cardfactory.CardFactoryUtil; import forge.card.cardfactory.CardFactoryUtil;
import forge.card.spellability.Ability; import forge.card.spellability.Ability;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.card.trigger.TriggerType; import forge.card.trigger.TriggerType;
import forge.game.Game; import forge.game.Game;
@@ -33,7 +33,7 @@ public class BecomesBlockedEffect extends SpellAbilityEffect {
public void resolve(SpellAbility sa) { public void resolve(SpellAbility sa) {
final Game game = sa.getActivatingPlayer().getGame(); final Game game = sa.getActivatingPlayer().getGame();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
for (final Card c : getTargetCards(sa)) { for (final Card c : getTargetCards(sa)) {
if ((tgt == null) || c.canBeTargetedBy(sa)) { if ((tgt == null) || c.canBeTargetedBy(sa)) {
game.getCombat().setBlocked(c); game.getCombat().setBlocked(c);

View File

@@ -5,6 +5,7 @@ import java.util.List;
import forge.card.ability.SpellAbilityEffect; import forge.card.ability.SpellAbilityEffect;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityStackInstance; import forge.card.spellability.SpellAbilityStackInstance;
import forge.card.spellability.TargetChoices;
import forge.game.zone.MagicStack; import forge.game.zone.MagicStack;
/** /**
@@ -18,7 +19,7 @@ public class ChangeTargetsEffect extends SpellAbilityEffect {
*/ */
@Override @Override
public void resolve(SpellAbility sa) { public void resolve(SpellAbility sa) {
final List<SpellAbility> sas = getTargetSpellAbilities(sa); final List<SpellAbility> sas = getTargetSpells(sa);
final boolean remember = sa.hasParam("RememberTargetedCard"); final boolean remember = sa.hasParam("RememberTargetedCard");
final MagicStack stack = sa.getActivatingPlayer().getGame().getStack(); final MagicStack stack = sa.getActivatingPlayer().getGame().getStack();
@@ -33,7 +34,8 @@ public class ChangeTargetsEffect extends SpellAbilityEffect {
while(changingTgtSI != null) { while(changingTgtSI != null) {
// Update targets, with a potential new target // Update targets, with a potential new target
SpellAbility changingTgtSA = changingTgtSI.getSpellAbility(); SpellAbility changingTgtSA = changingTgtSI.getSpellAbility();
changingTgtSI.updateTarget(sa.getActivatingPlayer().getController().chooseTargets(changingTgtSA)); TargetChoices newTarget = sa.getActivatingPlayer().getController().chooseTargets(changingTgtSA);
changingTgtSI.updateTarget(newTarget);
changingTgtSI = changingTgtSI.getSubInstace(); changingTgtSI = changingTgtSI.getSubInstace();
} }

View File

@@ -46,7 +46,7 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect {
List<Card> cards = new ArrayList<Card>(); List<Card> cards = new ArrayList<Card>();
List<Player> tgtPlayers = getTargetPlayersEmptyAsDefault(sa); List<Player> tgtPlayers = getTargetPlayers(sa);
final Game game = sa.getActivatingPlayer().getGame(); final Game game = sa.getActivatingPlayer().getGame();
if ((tgtPlayers == null) || tgtPlayers.isEmpty() || sa.hasParam("UseAllOriginZones")) { 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 // Auras without Candidates stay in their current location
if (c.isAura()) { if (c.isAura()) {
final SpellAbility saAura = AttachEffect.getAttachSpellAbility(c); final SpellAbility saAura = AttachEffect.getAttachSpellAbility(c);
if (!saAura.getTarget().hasCandidates(saAura, false)) { if (!saAura.getTargetRestrictions().hasCandidates(saAura, false)) {
continue; continue;
} }
} }

View File

@@ -5,6 +5,8 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import forge.Card; import forge.Card;
import forge.CardCharacteristicName; import forge.CardCharacteristicName;
@@ -18,7 +20,7 @@ import forge.card.ability.ai.ChangeZoneAi;
import forge.card.spellability.AbilitySub; import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityStackInstance; import forge.card.spellability.SpellAbilityStackInstance;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.card.trigger.TriggerType; import forge.card.trigger.TriggerType;
import forge.game.Game; import forge.game.Game;
import forge.game.player.Player; import forge.game.player.Player;
@@ -70,15 +72,15 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
sb.append(" "); sb.append(" ");
// Player whose cards will change zones // Player whose cards will change zones
List<Player> fetchers = new ArrayList<Player>(); List<Player> fetchers = null;
if (sa.hasParam("DefinedPlayer")) { if (sa.hasParam("DefinedPlayer")) {
fetchers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("DefinedPlayer"), sa); fetchers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("DefinedPlayer"), sa);
} }
if (fetchers.isEmpty() && sa.hasParam("ValidTgts") && sa.getTarget() != null) { if (fetchers == null && sa.hasParam("ValidTgts") && sa.usesTargeting()) {
fetchers = sa.getTarget().getTargetPlayers(); fetchers = Lists.newArrayList(sa.getTargets().getTargetPlayers());
} }
if (fetchers.isEmpty()) { if (fetchers == null) {
fetchers.add(sa.getSourceCard().getController()); fetchers = Lists.newArrayList(sa.getSourceCard().getController());
} }
final String fetcherNames = Lang.joinHomogenous(fetchers, Player.Accessors.FN_GET_NAME); 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(); final StringBuilder sbTargets = new StringBuilder();
List<Card> tgts; Iterable<Card> tgts;
if (sa.getTarget() != null) { if (sa.usesTargeting()) {
tgts = sa.getTarget().getTargetCards(); tgts = sa.getTargets().getTargetCards();
} else { } else {
// otherwise add self to list and go from there // otherwise add self to list and go from there
tgts = new ArrayList<Card>(); tgts = sa.knownDetermineDefined(sa.getParam("Defined"));
for (final Card c : sa.knownDetermineDefined(sa.getParam("Defined"))) {
tgts.add(c);
}
} }
for (final Card c : tgts) { for (final Card c : tgts) {
@@ -255,7 +254,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
final String targetname = sbTargets.toString(); 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"; final String fromGraveyard = " from the graveyard";
@@ -367,11 +366,9 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
* @param sa * @param sa
* a {@link forge.card.spellability.SpellAbility} object. * a {@link forge.card.spellability.SpellAbility} object.
*/ */
private static void changeKnownOriginResolve(final SpellAbility sa) { private void changeKnownOriginResolve(final SpellAbility sa) {
List<Card> tgtCards; Iterable<Card> tgtCards = getTargetCards(sa);
List<SpellAbility> sas; final TargetRestrictions tgt = sa.getTargetRestrictions();
final Target tgt = sa.getTarget();
final Player player = sa.getActivatingPlayer(); final Player player = sa.getActivatingPlayer();
final Card hostCard = sa.getSourceCard(); final Card hostCard = sa.getSourceCard();
final Game game = player.getGame(); final Game game = player.getGame();
@@ -379,23 +376,8 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination")); final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination"));
final List<ZoneType> origin = ZoneType.listValueOf(sa.getParam("Origin")); final List<ZoneType> origin = ZoneType.listValueOf(sa.getParam("Origin"));
if (tgt != null) {
tgtCards = tgt.getTargetCards();
} else {
tgtCards = new ArrayList<Card>();
for (final Card c : AbilityUtils.getDefinedCards(hostCard, sa.getParam("Defined"), sa)) {
tgtCards.add(c);
}
}
// changing zones for spells on the stack // changing zones for spells on the stack
if (tgt != null) { for (final SpellAbility tgtSA : getTargetSpells(sa)) {
sas = tgt.getTargetSAs();
} else {
sas = AbilityUtils.getDefinedSpellAbilities(hostCard, sa.getParam("Defined"), sa);
}
for (final SpellAbility tgtSA : sas) {
if (!tgtSA.isSpell()) { // Catch any abilities or triggers that slip through somehow if (!tgtSA.isSpell()) { // Catch any abilities or triggers that slip through somehow
continue; continue;
} }
@@ -422,135 +404,134 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
boolean optional = sa.hasParam("Optional"); boolean optional = sa.hasParam("Optional");
if (tgtCards.size() != 0) {
for (final Card tgtC : tgtCards) { for (final Card tgtC : tgtCards) {
if (tgt != null && tgtC.isInPlay() && !tgtC.canBeTargetedBy(sa)) { if (tgt != null && tgtC.isInPlay() && !tgtC.canBeTargetedBy(sa)) {
continue; 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<Card> 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); // Auras without Candidates stay in their current
if (optional && false == player.getController().confirmAction(sa, null, prompt) ) // location
continue; 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 (sa.hasParam("Ninjutsu") || sa.hasParam("Attacking")) {
// What should they attack?
if (originZone == null || !origin.contains(originZone.getZoneType())) { // TODO Ninjutsu needs to actually select the Defender, instead of auto selecting player
continue; List<GameEntity> defenders = game.getCombat().getDefenders();
} if (!defenders.isEmpty()) {
// Blockeres are already declared, set this to unblocked
Card movedCard = null; game.getCombat().addAttacker(tgtC, defenders.get(0), false);
}
if (destination.equals(ZoneType.Library)) { }
// library position is zero indexed if (sa.hasParam("Tapped") || sa.hasParam("Ninjutsu")) {
final int libraryPosition = sa.hasParam("LibraryPosition") ? Integer.parseInt(sa.getParam("LibraryPosition")) : 0; tgtC.setTapped(true);
movedCard = game.getAction().moveToLibrary(tgtC, libraryPosition);
// for things like Gaea's Blessing
if (sa.hasParam("Shuffle")) {
tgtC.getOwner().shuffle();
} }
} else { } else {
if (destination.equals(ZoneType.Battlefield)) { movedCard = game.getAction().moveTo(destination, tgtC);
if (sa.hasParam("Tapped") || sa.hasParam("Ninjutsu")) { // If a card is Exiled from the stack, remove its spells from the stack
tgtC.setTapped(true); if (sa.hasParam("Fizzle")) {
} ArrayList<SpellAbility> spells = tgtC.getSpellAbilities();
if (sa.hasParam("GainControl")) { for (SpellAbility spell : spells) {
if (sa.hasParam("NewController")) { if (tgtC.isInZone(ZoneType.Exile)) {
final Player p = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("NewController"), sa).get(0); final SpellAbilityStackInstance si = game.getStack().getInstanceFromSpellAbility(spell);
tgtC.setController(p, game.getNextTimestamp()); if (si != null) {
} else { game.getStack().remove(si);
tgtC.setController(player, game.getNextTimestamp());
}
}
if (sa.hasParam("AttachedTo")) {
List<Card> 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<GameEntity> 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<SpellAbility> 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 (remember != null) {
} hostCard.addRemembered(movedCard);
if (forget != null) { }
hostCard.getRemembered().remove(movedCard); if (forget != null) {
} hostCard.getRemembered().remove(movedCard);
if (imprint != null) { }
hostCard.addImprinted(movedCard); if (imprint != null) {
} hostCard.addImprinted(movedCard);
} }
} }
} }
@@ -582,8 +563,8 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
Player chooser = null; Player chooser = null;
if (sa.hasParam("Chooser")) { if (sa.hasParam("Chooser")) {
final String choose = sa.getParam("Chooser"); final String choose = sa.getParam("Chooser");
if (choose.equals("Targeted") && (sa.getTarget().getTargetPlayers() != null)) { if (choose.equals("Targeted") && sa.getTargets().isTargetingAnyPlayer()) {
chooser = sa.getTarget().getTargetPlayers().get(0); chooser = sa.getTargets().getFirstTargetedPlayer();
} else { } else {
chooser = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), choose, sa).get(0); 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 boolean optional = sa.hasParam("Optional");
final Game game = player.getGame(); final Game game = player.getGame();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
final List<Player> players = tgt.getTargetPlayers(); final List<Player> players = Lists.newArrayList(sa.getTargets().getTargetPlayers());
player = sa.hasParam("DefinedPlayer") ? player : players.get(0); player = sa.hasParam("DefinedPlayer") ? player : players.get(0);
if (players.contains(player) && !player.canBeTargetedBy(sa)) { if (players.contains(player) && !player.canBeTargetedBy(sa)) {
return; return;

View File

@@ -12,7 +12,7 @@ import forge.card.CardType;
import forge.card.ability.SpellAbilityEffect; import forge.card.ability.SpellAbilityEffect;
import forge.card.cardfactory.CardFactoryUtil; import forge.card.cardfactory.CardFactoryUtil;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -37,7 +37,7 @@ public class ChooseCardEffect extends SpellAbilityEffect {
final Game game = sa.getActivatingPlayer().getGame(); final Game game = sa.getActivatingPlayer().getGame();
final ArrayList<Card> chosen = new ArrayList<Card>(); final ArrayList<Card> chosen = new ArrayList<Card>();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final List<Player> tgtPlayers = getTargetPlayers(sa); final List<Player> tgtPlayers = getTargetPlayers(sa);
ZoneType choiceZone = ZoneType.Battlefield; ZoneType choiceZone = ZoneType.Battlefield;

View File

@@ -19,7 +19,7 @@ import forge.card.CardRulesPredicates;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityEffect; import forge.card.ability.SpellAbilityEffect;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -46,7 +46,7 @@ public class ChooseCardNameEffect extends SpellAbilityEffect {
public void resolve(SpellAbility sa) { public void resolve(SpellAbility sa) {
final Card host = sa.getSourceCard(); final Card host = sa.getSourceCard();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final List<Player> tgtPlayers = getTargetPlayers(sa); final List<Player> tgtPlayers = getTargetPlayers(sa);
String valid = "Card"; String valid = "Card";

View File

@@ -11,7 +11,7 @@ import forge.CardPredicates;
import forge.Constant; import forge.Constant;
import forge.card.ability.SpellAbilityEffect; import forge.card.ability.SpellAbilityEffect;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.player.Player; import forge.game.player.Player;
@@ -42,7 +42,7 @@ public class ChooseColorEffect extends SpellAbilityEffect {
final List<Player> tgtPlayers = getTargetPlayers(sa); final List<Player> tgtPlayers = getTargetPlayers(sa);
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
for (final Player p : tgtPlayers) { for (final Player p : tgtPlayers) {
if ((tgt == null) || p.canBeTargetedBy(sa)) { if ((tgt == null) || p.canBeTargetedBy(sa)) {

View File

@@ -13,7 +13,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityEffect; import forge.card.ability.SpellAbilityEffect;
import forge.card.spellability.AbilitySub; import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player; import forge.game.player.Player;
import forge.gui.GuiChoose; import forge.gui.GuiChoose;
import forge.util.Aggregates; import forge.util.Aggregates;
@@ -41,9 +41,9 @@ public class ChooseGenericEffect extends SpellAbilityEffect {
choices.put(s, theseParams.get("ChoiceDescription")); choices.put(s, theseParams.get("ChoiceDescription"));
} }
final List<Player> tgtPlayers = getDefinedPlayersBeforeTargetOnes(sa); final List<Player> tgtPlayers = getDefinedPlayersOrTargeted(sa);
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
for (final Player p : tgtPlayers) { for (final Player p : tgtPlayers) {
if (tgt != null && !p.canBeTargetedBy(sa)) { if (tgt != null && !p.canBeTargetedBy(sa)) {

View File

@@ -9,7 +9,7 @@ import forge.Card;
import forge.card.ability.SpellAbilityEffect; import forge.card.ability.SpellAbilityEffect;
import forge.card.cardfactory.CardFactoryUtil; import forge.card.cardfactory.CardFactoryUtil;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player; import forge.game.player.Player;
import forge.gui.GuiDialog; 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 int max = StringUtils.isNumeric(sMax) ? Integer.parseInt(sMax) : CardFactoryUtil.xCount(card, card.getSVar(sMax));
final List<Player> tgtPlayers = getTargetPlayers(sa); final List<Player> tgtPlayers = getTargetPlayers(sa);
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
for (final Player p : tgtPlayers) { for (final Player p : tgtPlayers) {
if ((tgt == null) || p.canBeTargetedBy(sa)) { if ((tgt == null) || p.canBeTargetedBy(sa)) {

View File

@@ -6,7 +6,7 @@ import forge.Card;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityEffect; import forge.card.ability.SpellAbilityEffect;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player; import forge.game.player.Player;
public class ChoosePlayerEffect extends SpellAbilityEffect { public class ChoosePlayerEffect extends SpellAbilityEffect {
@@ -29,7 +29,7 @@ public class ChoosePlayerEffect extends SpellAbilityEffect {
final List<Player> tgtPlayers = getTargetPlayers(sa); final List<Player> tgtPlayers = getTargetPlayers(sa);
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final List<Player> choices = sa.hasParam("Choices") ? AbilityUtils.getDefinedPlayers( final List<Player> choices = sa.hasParam("Choices") ? AbilityUtils.getDefinedPlayers(
sa.getSourceCard(), sa.getParam("Choices"), sa) : sa.getActivatingPlayer().getGame().getPlayers(); sa.getSourceCard(), sa.getParam("Choices"), sa) : sa.getActivatingPlayer().getGame().getPlayers();

View File

@@ -5,8 +5,6 @@ import java.util.List;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
import forge.Card; import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.ITargetable; import forge.ITargetable;
@@ -16,7 +14,7 @@ import forge.card.ability.SpellAbilityEffect;
import forge.card.cardfactory.CardFactoryUtil; import forge.card.cardfactory.CardFactoryUtil;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityStackInstance; import forge.card.spellability.SpellAbilityStackInstance;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCombat; import forge.game.ai.ComputerUtilCombat;
@@ -42,7 +40,7 @@ public class ChooseSourceEffect extends SpellAbilityEffect {
final Card host = sa.getSourceCard(); final Card host = sa.getSourceCard();
final Game game = sa.getActivatingPlayer().getGame(); final Game game = sa.getActivatingPlayer().getGame();
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final List<Player> tgtPlayers = getTargetPlayers(sa); final List<Player> tgtPlayers = getTargetPlayers(sa);
@@ -190,19 +188,10 @@ public class ChooseSourceEffect extends SpellAbilityEffect {
} }
final List<? extends ITargetable> objects; List<? extends ITargetable> objects = getTargets(abilityOnStack);
final Target threatTgt = abilityOnStack.getTarget();
if (threatTgt == null) { if (!abilityOnStack.usesTargeting() && !abilityOnStack.hasParam("Defined") && abilityOnStack.hasParam("ValidPlayers"))
if (abilityOnStack.hasParam("Defined")) { objects = AbilityUtils.getDefinedPlayers(source, abilityOnStack.getParam("ValidPlayers"), abilityOnStack);
objects = AbilityUtils.getDefinedObjects(source, abilityOnStack.getParam("Defined"), abilityOnStack);
} else if (abilityOnStack.hasParam("ValidPlayers")) {
objects = AbilityUtils.getDefinedPlayers(source, abilityOnStack.getParam("ValidPlayers"), abilityOnStack);
} else
objects = Lists.<ITargetable>newArrayList();
} else {
objects = threatTgt.getTargetPlayers();
}
if (!objects.contains(ai) || abilityOnStack.hasParam("NoPrevention")) { if (!objects.contains(ai) || abilityOnStack.hasParam("NoPrevention")) {
continue; continue;

View File

@@ -10,7 +10,7 @@ import forge.Constant;
import forge.card.CardType; import forge.card.CardType;
import forge.card.ability.SpellAbilityEffect; import forge.card.ability.SpellAbilityEffect;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player; import forge.game.player.Player;
public class ChooseTypeEffect extends SpellAbilityEffect { 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<Player> tgtPlayers = getTargetPlayers(sa); final List<Player> tgtPlayers = getTargetPlayers(sa);
if( !validTypes.isEmpty()) { if( !validTypes.isEmpty()) {

View File

@@ -15,7 +15,7 @@ import forge.card.ability.SpellAbilityEffect;
import forge.card.cardfactory.CardFactory; import forge.card.cardfactory.CardFactory;
import forge.card.cardfactory.CardFactoryUtil; import forge.card.cardfactory.CardFactoryUtil;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.card.trigger.Trigger; import forge.card.trigger.Trigger;
import forge.card.trigger.TriggerHandler; import forge.card.trigger.TriggerHandler;
import forge.game.Game; import forge.game.Game;
@@ -32,14 +32,14 @@ public class CloneEffect extends SpellAbilityEffect {
Card tgtCard = host; Card tgtCard = host;
Card cardToCopy = host; Card cardToCopy = host;
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (sa.hasParam("Defined")) { if (sa.hasParam("Defined")) {
List<Card> cloneSources = AbilityUtils.getDefinedCards(host, sa.getParam("Defined"), sa); List<Card> cloneSources = AbilityUtils.getDefinedCards(host, sa.getParam("Defined"), sa);
if (!cloneSources.isEmpty()) { if (!cloneSources.isEmpty()) {
cardToCopy = cloneSources.get(0); cardToCopy = cloneSources.get(0);
} }
} else if (tgt != null) { } else if (tgt != null) {
cardToCopy = tgt.getTargetCards().get(0); cardToCopy = sa.getTargets().getFirstTargetedCard();
} }
List<Card> cloneTargets = AbilityUtils.getDefinedCards(host, sa.getParam("CloneTarget"), sa); List<Card> 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 // find cloning source i.e. thing to be copied
Card cardToCopy = null; Card cardToCopy = null;
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (sa.hasParam("Defined")) { if (sa.hasParam("Defined")) {
List<Card> cloneSources = AbilityUtils.getDefinedCards(host, sa.getParam("Defined"), sa); List<Card> cloneSources = AbilityUtils.getDefinedCards(host, sa.getParam("Defined"), sa);
if (!cloneSources.isEmpty()) { if (!cloneSources.isEmpty()) {
cardToCopy = cloneSources.get(0); cardToCopy = cloneSources.get(0);
} }
} else if (tgt != null) { } else if (tgt != null) {
cardToCopy = tgt.getTargetCards().get(0); cardToCopy = sa.getTargets().getFirstTargetedCard();
} }
if (cardToCopy == null) { if (cardToCopy == null) {
return; return;

View File

@@ -3,11 +3,13 @@ package forge.card.ability.effects;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.google.common.collect.Lists;
import forge.Card; import forge.Card;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityEffect; import forge.card.ability.SpellAbilityEffect;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player; import forge.game.player.Player;
@@ -20,8 +22,8 @@ public class ControlExchangeEffect extends SpellAbilityEffect {
protected String getStackDescription(SpellAbility sa) { protected String getStackDescription(SpellAbility sa) {
Card object1 = null; Card object1 = null;
Card object2 = null; Card object2 = null;
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
List<Card> tgts = tgt == null ? new ArrayList<Card>() : tgt.getTargetCards(); List<Card> tgts = tgt == null ? new ArrayList<Card>() : Lists.newArrayList(sa.getTargets().getTargetCards());
if (tgts.size() > 0) { if (tgts.size() > 0) {
object1 = tgts.get(0); object1 = tgts.get(0);
} }
@@ -45,8 +47,8 @@ public class ControlExchangeEffect extends SpellAbilityEffect {
public void resolve(SpellAbility sa) { public void resolve(SpellAbility sa) {
Card object1 = null; Card object1 = null;
Card object2 = null; Card object2 = null;
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
List<Card> tgts = tgt == null ? new ArrayList<Card>() : tgt.getTargetCards(); List<Card> tgts = tgt == null ? new ArrayList<Card>() : Lists.newArrayList(sa.getTargets().getTargetCards());
if (tgts.size() > 0) { if (tgts.size() > 0) {
object1 = tgts.get(0); object1 = tgts.get(0);
} }

View File

@@ -1,6 +1,5 @@
package forge.card.ability.effects; package forge.card.ability.effects;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@@ -11,7 +10,6 @@ import forge.card.ability.SpellAbilityEffect;
import forge.card.mana.ManaCost; import forge.card.mana.ManaCost;
import forge.card.spellability.Ability; import forge.card.spellability.Ability;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.game.Game; import forge.game.Game;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -24,13 +22,7 @@ public class ControlGainEffect extends SpellAbilityEffect {
protected String getStackDescription(SpellAbility sa) { protected String getStackDescription(SpellAbility sa) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
List<Player> newController = getTargetPlayers(sa, "NewController");
final Target tgt = sa.getTarget();
List<Player> newController = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("NewController"), sa);
if ((tgt != null) && tgt.getTargetPlayers() != null && !tgt.getTargetPlayers().isEmpty()) {
newController = tgt.getTargetPlayers();
}
if (newController.size() == 0) { if (newController.size() == 0) {
newController.add(sa.getActivatingPlayer()); newController.add(sa.getActivatingPlayer());
} }
@@ -74,7 +66,6 @@ public class ControlGainEffect extends SpellAbilityEffect {
@Override @Override
public void resolve(SpellAbility sa) { public void resolve(SpellAbility sa) {
List<Card> tgtCards = new ArrayList<Card>();
Card source = sa.getSourceCard(); Card source = sa.getSourceCard();
final boolean bUntap = sa.hasParam("Untap"); final boolean bUntap = sa.hasParam("Untap");
@@ -86,28 +77,16 @@ public class ControlGainEffect extends SpellAbilityEffect {
final List<String> kws = sa.hasParam("AddKWs") ? Arrays.asList(sa.getParam("AddKWs").split(" & ")) : null; final List<String> kws = sa.hasParam("AddKWs") ? Arrays.asList(sa.getParam("AddKWs").split(" & ")) : null;
final List<String> lose = sa.hasParam("LoseControl") ? Arrays.asList(sa.getParam("LoseControl").split(",")) : null; final List<String> lose = sa.hasParam("LoseControl") ? Arrays.asList(sa.getParam("LoseControl").split(",")) : null;
final Target tgt = sa.getTarget(); final List<Player> controllers = getDefinedPlayersOrTargeted(sa, "NewController");
final List<Player> 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<Player>();
final Player newController = controllers.isEmpty() ? sa.getActivatingPlayer() : controllers.get(0); final Player newController = controllers.isEmpty() ? sa.getActivatingPlayer() : controllers.get(0);
final Game game = newController.getGame(); final Game game = newController.getGame();
final List<Card> tgtCards;
if (sa.hasParam("AllValid")) { if (sa.hasParam("AllValid")) {
tgtCards = game.getCardsIn(ZoneType.Battlefield); tgtCards = AbilityUtils.filterListByType(game.getCardsIn(ZoneType.Battlefield), sa.getParam("AllValid"), sa);
tgtCards = AbilityUtils.filterListByType(tgtCards, sa.getParam("AllValid"), sa); } else
} else if (sa.hasParam("Defined")) {
tgtCards = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa);
} else {
tgtCards = getTargetCards(sa); tgtCards = getTargetCards(sa);
}
// check for lose control criteria right away // check for lose control criteria right away
if (lose != null && lose.contains("LeavesPlay") && !source.isInZone(ZoneType.Battlefield)) { if (lose != null && lose.contains("LeavesPlay") && !source.isInZone(ZoneType.Battlefield)) {

View File

@@ -25,7 +25,7 @@ import forge.card.cardfactory.CardFactoryUtil;
import forge.card.mana.ManaCost; import forge.card.mana.ManaCost;
import forge.card.spellability.Ability; import forge.card.spellability.Ability;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.player.Player; import forge.game.player.Player;
@@ -70,7 +70,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
sa.getParam("NumCopies"), sa) : 1; sa.getParam("NumCopies"), sa) : 1;
List<Card> tgtCards = getTargetCards(sa); List<Card> tgtCards = getTargetCards(sa);
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (sa.hasParam("ValidSupportedCopy")) { if (sa.hasParam("ValidSupportedCopy")) {
List<PaperCard> cards = Lists.newArrayList(CardDb.instance().getUniqueCards()); List<PaperCard> cards = Lists.newArrayList(CardDb.instance().getUniqueCards());

View File

@@ -6,6 +6,7 @@ import java.util.List;
import forge.Card; import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.ITargetable;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityEffect; import forge.card.ability.SpellAbilityEffect;
import forge.card.cardfactory.CardFactory; import forge.card.cardfactory.CardFactory;
@@ -15,14 +16,10 @@ import forge.gui.GuiChoose;
public class CopySpellAbilityEffect extends SpellAbilityEffect { public class CopySpellAbilityEffect extends SpellAbilityEffect {
// *************************************************************************
// ************************* CopySpell *************************************
// *************************************************************************
@Override @Override
protected String getStackDescription(SpellAbility sa) { protected String getStackDescription(SpellAbility sa) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
final List<SpellAbility> tgtSpells = getTargetSpellAbilities(sa); final List<SpellAbility> tgtSpells = getTargetSpells(sa);
sb.append("Copy "); sb.append("Copy ");
// TODO Someone fix this Description when Copying Charms // 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); controller = AbilityUtils.getDefinedPlayers(card, sa.getParam("Controller"), sa).get(0);
} }
final List<SpellAbility> tgtSpells = getTargetSpellAbilities(sa); final List<SpellAbility> tgtSpells = getTargetSpells(sa);
if (tgtSpells.size() == 0) { if (tgtSpells.size() == 0) {
@@ -112,12 +109,13 @@ public class CopySpellAbilityEffect extends SpellAbilityEffect {
chosenSA = GuiChoose.one("Select a spell to copy", tgtSpells); chosenSA = GuiChoose.one("Select a spell to copy", tgtSpells);
} }
chosenSA.setActivatingPlayer(controller); chosenSA.setActivatingPlayer(controller);
List<Object> candidates = chosenSA.getTarget().getAllCandidates(chosenSA, true); List<ITargetable> candidates = chosenSA.getTargetRestrictions().getAllCandidates(chosenSA, true);
if (sa.hasParam("CanTargetPlayer")) { if (sa.hasParam("CanTargetPlayer")) {
// Radiate // Radiate
// Remove targeted players because getAllCandidates include all the valid players // Remove targeted players because getAllCandidates include all the valid players
candidates.removeAll(chosenSA.getTarget().getTargetPlayers()); for(Player p : chosenSA.getTargets().getTargetPlayers())
for (Object o : candidates) { candidates.remove(p);
for (ITargetable o : candidates) {
CardFactory.copySpellontoStack(card, chosenSA.getSourceCard(), chosenSA, true, o); CardFactory.copySpellontoStack(card, chosenSA.getSourceCard(), chosenSA, true, o);
} }
} else {// Precursor Golem, Ink-Treader Nephilim } else {// Precursor Golem, Ink-Treader Nephilim

View File

@@ -37,7 +37,7 @@ public class CounterEffect extends SpellAbilityEffect {
sas.add(spell); sas.add(spell);
} }
} else { } else {
sas = getTargetSpellAbilities(sa); sas = getTargetSpells(sa);
} }
sb.append("countering"); sb.append("countering");
@@ -82,7 +82,7 @@ public class CounterEffect extends SpellAbilityEffect {
sas.add(spell); sas.add(spell);
} }
} else { } else {
sas = getTargetSpellAbilities(sa); sas = getTargetSpells(sa);
} }
if (sa.hasParam("ForgetOtherTargets")) { if (sa.hasParam("ForgetOtherTargets")) {

View File

@@ -9,7 +9,6 @@ import forge.CounterType;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityEffect; import forge.card.ability.SpellAbilityEffect;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.gui.GuiChoose; import forge.gui.GuiChoose;
public class CountersMoveEffect extends SpellAbilityEffect { public class CountersMoveEffect extends SpellAbilityEffect {
@@ -17,16 +16,10 @@ public class CountersMoveEffect extends SpellAbilityEffect {
@Override @Override
protected String getStackDescription(SpellAbility sa) { protected String getStackDescription(SpellAbility sa) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
final Card host = sa.getSourceCard();
Card source = null; Card source = null;
List<Card> srcCards; List<Card> srcCards = getDefinedCardsOrTargeted(sa, "Source");
final Target tgt = sa.getTarget();
if (!sa.hasParam("Source") && tgt != null) {
srcCards = tgt.getTargetCards();
} else {
srcCards = AbilityUtils.getDefinedCards(host, sa.getParam("Source"), sa);
}
if (srcCards.size() > 0) { if (srcCards.size() > 0) {
source = srcCards.get(0); source = srcCards.get(0);
} }
@@ -74,25 +67,14 @@ public class CountersMoveEffect extends SpellAbilityEffect {
} }
Card source = null; Card source = null;
List<Card> srcCards; List<Card> srcCards = getDefinedCardsOrTargeted(sa, "Source");
final Target tgt = sa.getTarget();
if (!sa.hasParam("Source") && tgt != null) {
srcCards = tgt.getTargetCards();
} else {
srcCards = AbilityUtils.getDefinedCards(host, sa.getParam("Source"), sa);
}
if (srcCards.size() > 0) { if (srcCards.size() > 0) {
source = srcCards.get(0); source = srcCards.get(0);
} }
if (sa.getParam("CounterNum").equals("All")) { if (sa.getParam("CounterNum").equals("All")) {
amount = source.getCounters(cType); amount = source.getCounters(cType);
} }
List<Card> tgtCards; List<Card> tgtCards = getTargetCards(sa);
if (!sa.hasParam("Defined") && tgt != null) {
tgtCards = tgt.getTargetCards();
} else {
tgtCards = AbilityUtils.getDefinedCards(host, sa.getParam("Defined"), sa);
}
for (final Card dest : tgtCards) { for (final Card dest : tgtCards) {
if ((null != source) && (null != dest)) { if ((null != source) && (null != dest)) {

View File

@@ -8,7 +8,7 @@ import forge.CounterType;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityEffect; import forge.card.ability.SpellAbilityEffect;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -48,9 +48,9 @@ public class CountersPutAllEffect extends SpellAbilityEffect {
List<Card> cards = game.getCardsIn(zone); List<Card> cards = game.getCardsIn(zone);
cards = CardLists.getValidCards(cards, valid, sa.getSourceCard().getController(), sa.getSourceCard()); cards = CardLists.getValidCards(cards, valid, sa.getSourceCard().getController(), sa.getSourceCard());
final Target tgt = sa.getTarget(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
final Player pl = sa.getTargetPlayer(); final Player pl = sa.getTargets().getFirstTargetedPlayer();
cards = CardLists.filterControlledBy(cards, pl); cards = CardLists.filterControlledBy(cards, pl);
} }

View File

@@ -9,7 +9,6 @@ import forge.CounterType;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityEffect; import forge.card.ability.SpellAbilityEffect;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.card.trigger.TriggerType; import forge.card.trigger.TriggerType;
import forge.game.zone.Zone; import forge.game.zone.Zone;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -41,8 +40,7 @@ public class CountersPutEffect extends SpellAbilityEffect {
} else { } else {
sb.append(" on "); sb.append(" on ");
} }
final Target tgt = sa.getTarget(); final List<Card> tgtCards = getTargetCards(sa);
final List<Card> tgtCards = tgt != null ? tgt.getTargetCards() : AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa);
final Iterator<Card> it = tgtCards.iterator(); final Iterator<Card> it = tgtCards.iterator();
while (it.hasNext()) { while (it.hasNext()) {
@@ -92,18 +90,11 @@ public class CountersPutEffect extends SpellAbilityEffect {
} }
} }
List<Card> tgtCards; List<Card> tgtCards = getTargetCards(sa);
final Target tgt = sa.getTarget();
if (tgt != null && (tgt.getTargetPlayers().size() == 0)) {
tgtCards = tgt.getTargetCards();
} else {
tgtCards = AbilityUtils.getDefinedCards(card, sa.getParam("Defined"), sa);
}
for (final Card tgtCard : tgtCards) { for (final Card tgtCard : tgtCards) {
counterAmount = (sa.getTarget() != null && sa.hasParam("DividedAsYouChoose")) ? sa.getTarget().getDividedValue(tgtCard) : counterAmount; counterAmount = (sa.usesTargeting() && sa.hasParam("DividedAsYouChoose")) ? sa.getTargetRestrictions().getDividedValue(tgtCard) : counterAmount;
if ((tgt == null) || tgtCard.canBeTargetedBy(sa)) { if (!sa.usesTargeting() || tgtCard.canBeTargetedBy(sa)) {
if (max != -1) { if (max != -1) {
counterAmount = max - tgtCard.getCounters(counterType); counterAmount = max - tgtCard.getCounters(counterType);
} }

Some files were not shown because too many files have changed in this diff Show More