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/AbilityUtils.java -text
src/main/java/forge/card/ability/ApiType.java -text
src/main/java/forge/card/ability/SaTargetRountines.java -text
src/main/java/forge/card/ability/SpellAbilityAi.java -text
src/main/java/forge/card/ability/SpellAbilityEffect.java -text
src/main/java/forge/card/ability/SpellApiBased.java -text
@@ -14324,8 +14325,8 @@ src/main/java/forge/card/spellability/SpellAbilityRestriction.java svneol=native
src/main/java/forge/card/spellability/SpellAbilityStackInstance.java svneol=native#text/plain
src/main/java/forge/card/spellability/SpellAbilityVariables.java svneol=native#text/plain
src/main/java/forge/card/spellability/SpellPermanent.java svneol=native#text/plain
src/main/java/forge/card/spellability/Target.java svneol=native#text/plain
src/main/java/forge/card/spellability/TargetChoices.java svneol=native#text/plain
src/main/java/forge/card/spellability/TargetRestrictions.java svneol=native#text/plain
src/main/java/forge/card/spellability/TargetSelection.java svneol=native#text/plain
src/main/java/forge/card/spellability/package-info.java svneol=native#text/plain
src/main/java/forge/card/staticability/StaticAbility.java svneol=native#text/plain

View File

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

View File

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

View File

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

View File

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

View File

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

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.PlayerActionConfirmMode;
public abstract class SpellAbilityAi {
public abstract class SpellAbilityAi extends SaTargetRountines {
public final boolean canPlayAIWithSubs(final Player aiPlayer, final SpellAbility sa) {
if (!canPlayAI(aiPlayer, sa)) {

View File

@@ -1,20 +1,15 @@
package forge.card.ability;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.apache.commons.lang3.StringUtils;
import forge.Card;
import forge.ITargetable;
import forge.card.cardfactory.CardFactoryUtil;
import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.game.player.Player;
/**
* <p>
@@ -25,7 +20,7 @@ import forge.game.player.Player;
* @version $Id: AbilityFactoryAlterLife.java 17656 2012-10-22 19:32:56Z Max mtg $
*/
public abstract class SpellAbilityEffect {
public abstract class SpellAbilityEffect extends SaTargetRountines {
public abstract void resolve(final SpellAbility sa);
@@ -123,49 +118,4 @@ import forge.game.player.Player;
}
}
}
protected List<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.spellability.AbilityManaPart;
import forge.card.spellability.Spell;
import forge.card.spellability.Target;
import forge.card.spellability.TargetRestrictions;
public class SpellApiBased extends Spell {
private static final long serialVersionUID = -6741797239508483250L;
private final SpellAbilityEffect effect;
private final SpellAbilityAi ai;
public SpellApiBased(ApiType api0, Card sourceCard, Cost abCost, Target tgt, Map<String, String> params0) {
public SpellApiBased(ApiType api0, Card sourceCard, Cost abCost, TargetRestrictions tgt, Map<String, String> params0) {
super(sourceCard, abCost);
this.setTarget(tgt);
this.setTargetRestrictions(tgt);
params = params0;
api = api0;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,7 +6,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCost;
import forge.game.ai.ComputerUtilMana;
@@ -18,13 +18,7 @@ public class LifeLoseAi extends SpellAbilityAi {
@Override
public boolean chkAIDrawback(SpellAbility sa, Player ai) {
final Target tgt = sa.getTarget();
List<Player> tgtPlayers;
if (tgt != null) {
tgtPlayers = tgt.getTargetPlayers();
} else {
tgtPlayers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa);
}
List<Player> tgtPlayers = getTargetPlayers(sa);
final Card source = sa.getSourceCard();
final String amountStr = sa.getParam("LifeAmount");
@@ -98,12 +92,10 @@ public class LifeLoseAi extends SpellAbilityAi {
return false;
}
final Target tgt = sa.getTarget();
if (sa.getTarget() != null) {
tgt.resetTargets();
if (sa.usesTargeting()) {
sa.resetTargets();
if (sa.canTarget(opp)) {
sa.getTarget().addTarget(opp);
sa.getTargets().add(opp);
} else {
return false;
}
@@ -138,12 +130,12 @@ public class LifeLoseAi extends SpellAbilityAi {
@Override
protected boolean doTriggerAINoCost(final Player ai, final SpellAbility sa,
final boolean mandatory) {
final Target tgt = sa.getTarget();
final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) {
if (sa.canTarget(ai.getOpponent())) {
tgt.addTarget(ai.getOpponent());
sa.getTargets().add(ai.getOpponent());
} else if (mandatory && sa.canTarget(ai)) {
tgt.addTarget(ai);
sa.getTargets().add(ai);
} else {
return false;
}
@@ -161,12 +153,7 @@ public class LifeLoseAi extends SpellAbilityAi {
amount = AbilityUtils.calculateAmount(source, amountStr, sa);
}
List<Player> tgtPlayers;
if (tgt != null) {
tgtPlayers = tgt.getTargetPlayers();
} else {
tgtPlayers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa);
}
List<Player> tgtPlayers = getTargetPlayers(sa);
if (!mandatory && tgtPlayers.contains(ai) && amount > 0 && amount + 3 > ai.getLife()) {
// 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.SpellAbilityAi;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilMana;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
@@ -51,11 +51,11 @@ public class LifeSetAi extends SpellAbilityAi {
// prevent run-away activations - first time will always return true
final boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());
final Target tgt = sa.getTarget();
final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) {
tgt.resetTargets();
sa.resetTargets();
if (tgt.canOnlyTgtOpponent()) {
tgt.addTarget(opponent);
sa.getTargets().add(opponent);
// if we can only target the human, and the Human's life
// would
// go up, don't play it.
@@ -67,11 +67,11 @@ public class LifeSetAi extends SpellAbilityAi {
}
} else {
if ((amount > myLife) && (myLife <= 10)) {
tgt.addTarget(ai);
sa.getTargets().add(ai);
} else if (hlife > amount) {
tgt.addTarget(opponent);
sa.getTargets().add(opponent);
} else if (amount > myLife) {
tgt.addTarget(ai);
sa.getTargets().add(ai);
} else {
return false;
}
@@ -128,18 +128,18 @@ public class LifeSetAi extends SpellAbilityAi {
// if the Target is modifying how much life is gained, this needs to
// be
// handled better
final Target tgt = sa.getTarget();
final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) {
tgt.resetTargets();
sa.resetTargets();
if (tgt.canOnlyTgtOpponent()) {
tgt.addTarget(opponent);
sa.getTargets().add(opponent);
} else {
if ((amount > myLife) && (myLife <= 10)) {
tgt.addTarget(ai);
sa.getTargets().add(ai);
} else if (hlife > amount) {
tgt.addTarget(opponent);
sa.getTargets().add(opponent);
} else if (amount > myLife) {
tgt.addTarget(ai);
sa.getTargets().add(ai);
} else {
return false;
}

View File

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

View File

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

View File

@@ -8,7 +8,7 @@ import forge.CardLists;
import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.card.spellability.TargetRestrictions;
import forge.game.Game;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
@@ -22,7 +22,7 @@ public class PhasesAi extends SpellAbilityAi {
@Override
protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) {
// This still needs to be fleshed out
final Target tgt = sa.getTarget();
final TargetRestrictions tgt = sa.getTargetRestrictions();
final Card source = sa.getSourceCard();
final Random r = MyRandom.getRandom();
@@ -51,7 +51,7 @@ public class PhasesAi extends SpellAbilityAi {
@Override
protected boolean doTriggerAINoCost(Player aiPlayer, SpellAbility sa, boolean mandatory) {
final Target tgt = sa.getTarget();
final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt == null) {
return mandatory;
@@ -69,7 +69,7 @@ public class PhasesAi extends SpellAbilityAi {
@Override
public boolean chkAIDrawback(SpellAbility sa, Player aiPlayer) {
final Target tgt = sa.getTarget();
final TargetRestrictions tgt = sa.getTargetRestrictions();
boolean randomReturn = true;
@@ -89,7 +89,7 @@ public class PhasesAi extends SpellAbilityAi {
* </p>
*
* @param tgt
* a {@link forge.card.spellability.Target} object.
* a {@link forge.card.spellability.TargetRestrictions} object.
* @param af
* a {@link forge.card.ability.AbilityFactory} object.
* @param sa
@@ -98,7 +98,7 @@ public class PhasesAi extends SpellAbilityAi {
* a boolean.
* @return a boolean.
*/
private boolean phasesPrefTargeting(final Target tgt, final SpellAbility sa,
private boolean phasesPrefTargeting(final TargetRestrictions tgt, final SpellAbility sa,
final boolean mandatory) {
// Card source = sa.getSourceCard();
@@ -135,7 +135,7 @@ public class PhasesAi extends SpellAbilityAi {
*/
private boolean phasesUnpreferredTargeting(final Game game, final SpellAbility sa, final boolean mandatory) {
final Card source = sa.getSourceCard();
final Target tgt = sa.getTarget();
final TargetRestrictions tgt = sa.getTargetRestrictions();
List<Card> list = game.getCardsIn(ZoneType.Battlefield);
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.cost.Cost;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCost;
import forge.game.player.Player;
@@ -54,14 +54,14 @@ public class PlayAi extends SpellAbilityAi {
boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getRestrictions().getNumberTurnActivations());
List<Card> cards;
final Target tgt = sa.getTarget();
final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) {
ZoneType zone = tgt.getZone().get(0);
cards = CardLists.getValidCards(ai.getGame().getCardsIn(zone), tgt.getValidTgts(), ai, source);
if (cards.isEmpty()) {
return false;
}
tgt.addTarget(ComputerUtilCard.getBestAI(cards));
sa.getTargets().add(ComputerUtilCard.getBestAI(cards));
} else if (!sa.hasParam("Valid")) {
cards = new ArrayList<Card>(AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa));
if (cards.isEmpty()) {
@@ -87,7 +87,7 @@ public class PlayAi extends SpellAbilityAi {
@Override
protected boolean doTriggerAINoCost(final Player ai, final SpellAbility sa, final boolean mandatory) {
final Target tgt = sa.getTarget();
final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) {
return false;
}

View File

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

View File

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

View File

@@ -14,7 +14,7 @@ public class ProtectAllAi extends SpellAbilityAi {
protected boolean canPlayAI(Player ai, SpellAbility sa) {
final Card hostCard = sa.getSourceCard();
// if there is no target and host card isn't in play, don't activate
if ((sa.getTarget() == null) && !hostCard.isInPlay()) {
if ((sa.getTargetRestrictions() == null) && !hostCard.isInPlay()) {
return false;
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,11 +1,11 @@
package forge.card.ability.ai;
import java.util.ArrayList;
import java.util.List;
import forge.Card;
import forge.CardLists;
import forge.CardPredicates;
import forge.ITargetable;
import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility;
@@ -57,7 +57,7 @@ public class RegenerateAllAi extends SpellAbilityAi {
int numSaved = 0;
if (!game.getStack().isEmpty()) {
final ArrayList<Object> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa);
final List<ITargetable> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa);
for (final Card c : list) {
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.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode;
@@ -11,14 +11,14 @@ public class RepeatAi extends SpellAbilityAi {
@Override
protected boolean canPlayAI(Player ai, SpellAbility sa) {
final Target tgt = sa.getTarget();
final TargetRestrictions tgt = sa.getTargetRestrictions();
final Player opp = ai.getOpponent();
if (tgt != null) {
if (!opp.canBeTargetedBy(sa)) {
return false;
}
tgt.resetTargets();
tgt.addTarget(opp);
sa.resetTargets();
sa.getTargets().add(opp);
}
return true;
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,7 +8,7 @@ import forge.game.player.Player;
public class SetStateAi extends SpellAbilityAi {
@Override
protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) {
if (sa.getTarget() == null && "Transform".equals(sa.getParam("Mode"))) {
if (sa.getTargetRestrictions() == null && "Transform".equals(sa.getParam("Mode"))) {
return true;
}
return false;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,7 +10,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilMana;
import forge.game.phase.PhaseType;
@@ -36,9 +36,9 @@ public class UnattachAllAi extends SpellAbilityAi {
boolean chance = r.nextFloat() <= .9;
// Attach spells always have a target
final Target tgt = sa.getTarget();
final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) {
tgt.resetTargets();
sa.resetTargets();
}
if (abCost != null && abCost.getTotalMana().countX() > 0 && source.getSVar("X").equals("Count$xPaid")) {
@@ -69,7 +69,7 @@ public class UnattachAllAi extends SpellAbilityAi {
final Player opp = ai.getOpponent();
// Check if there are any valid targets
List<ITargetable> targets = new ArrayList<ITargetable>();
final Target tgt = sa.getTarget();
final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt == null) {
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.cost.Cost;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCost;
import forge.game.player.Player;
@@ -24,7 +24,7 @@ public class UntapAi extends SpellAbilityAi {
*/
@Override
protected boolean canPlayAI(Player ai, SpellAbility sa) {
final Target tgt = sa.getTarget();
final TargetRestrictions tgt = sa.getTargetRestrictions();
final Card source = sa.getSourceCard();
final Cost cost = sa.getPayCosts();
@@ -51,7 +51,7 @@ public class UntapAi extends SpellAbilityAi {
@Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
final Target tgt = sa.getTarget();
final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt == null) {
if (mandatory) {
@@ -79,7 +79,7 @@ public class UntapAi extends SpellAbilityAi {
@Override
public boolean chkAIDrawback(SpellAbility sa, Player ai) {
final Target tgt = sa.getTarget();
final TargetRestrictions tgt = sa.getTargetRestrictions();
boolean randomReturn = true;
@@ -100,7 +100,7 @@ public class UntapAi extends SpellAbilityAi {
* </p>
*
* @param tgt
* a {@link forge.card.spellability.Target} object.
* a {@link forge.card.spellability.TargetRestrictions} object.
* @param af
* a {@link forge.card.ability.AbilityFactory} object.
* @param sa
@@ -109,7 +109,7 @@ public class UntapAi extends SpellAbilityAi {
* a boolean.
* @return a boolean.
*/
private static boolean untapPrefTargeting(final Player ai, final Target tgt, final SpellAbility sa, final boolean mandatory) {
private static boolean untapPrefTargeting(final Player ai, final TargetRestrictions tgt, final SpellAbility sa, final boolean mandatory) {
final Card source = sa.getSourceCard();
Player targetController = ai;
@@ -132,12 +132,12 @@ public class UntapAi extends SpellAbilityAi {
return false;
}
while (tgt.getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) {
while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) {
Card choice = null;
if (untapList.size() == 0) {
if ((tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (tgt.getNumTargeted() == 0)) {
tgt.resetTargets();
if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (sa.getTargets().getNumTargeted() == 0)) {
sa.resetTargets();
return false;
} else {
// TODO is this good enough? for up to amounts?
@@ -157,8 +157,8 @@ public class UntapAi extends SpellAbilityAi {
}
if (choice == null) { // can't find anything left
if ((tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (tgt.getNumTargeted() == 0)) {
tgt.resetTargets();
if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (sa.getTargets().getNumTargeted() == 0)) {
sa.resetTargets();
return false;
} else {
// TODO is this good enough? for up to amounts?
@@ -167,7 +167,7 @@ public class UntapAi extends SpellAbilityAi {
}
untapList.remove(choice);
tgt.addTarget(choice);
sa.getTargets().add(choice);
}
return true;
}
@@ -187,7 +187,7 @@ public class UntapAi extends SpellAbilityAi {
*/
private boolean untapUnpreferredTargeting(final SpellAbility sa, final boolean mandatory) {
final Card source = sa.getSourceCard();
final Target tgt = sa.getTarget();
final TargetRestrictions tgt = sa.getTargetRestrictions();
List<Card> list = sa.getActivatingPlayer().getGame().getCardsIn(ZoneType.Battlefield);
@@ -228,7 +228,7 @@ public class UntapAi extends SpellAbilityAi {
* @param source
* a {@link forge.Card} object.
* @param tgt
* a {@link forge.card.spellability.Target} object.
* a {@link forge.card.spellability.TargetRestrictions} object.
* @param af
* a {@link forge.card.ability.AbilityFactory} object.
* @param sa
@@ -239,8 +239,9 @@ public class UntapAi extends SpellAbilityAi {
* a {@link forge.CardList} object.
* @return a boolean.
*/
private boolean untapTargetList(final Card source, final Target tgt, final SpellAbility sa, final boolean mandatory, final List<Card> tapList) {
for (final Card c : tgt.getTargetCards()) {
private boolean untapTargetList(final Card source, final TargetRestrictions tgt, final SpellAbility sa, final boolean mandatory, final List<Card> tapList) {
for (final Card c : sa.getTargets().getTargetCards()) {
tapList.remove(c);
}
@@ -248,13 +249,13 @@ public class UntapAi extends SpellAbilityAi {
return false;
}
while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) {
while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) {
Card choice = null;
if (tapList.size() == 0) {
if ((tgt.getNumTargeted() < tgt.getMinTargets(source, sa)) || (tgt.getNumTargeted() == 0)) {
if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(source, sa)) || (sa.getTargets().getNumTargeted() == 0)) {
if (!mandatory) {
tgt.resetTargets();
sa.resetTargets();
}
return false;
} else {
@@ -274,9 +275,9 @@ public class UntapAi extends SpellAbilityAi {
}
if (choice == null) { // can't find anything left
if ((tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (tgt.getNumTargeted() == 0)) {
if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (sa.getTargets().getNumTargeted() == 0)) {
if (!mandatory) {
tgt.resetTargets();
sa.resetTargets();
}
return false;
} else {
@@ -286,7 +287,7 @@ public class UntapAi extends SpellAbilityAi {
}
tapList.remove(choice);
tgt.addTarget(choice);
sa.getTargets().add(choice);
}
return true;

View File

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

View File

@@ -14,7 +14,6 @@ import forge.card.ability.AbilityFactory;
import forge.card.ability.AbilityUtils;
import forge.card.replacement.ReplacementEffect;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.card.staticability.StaticAbility;
import forge.card.trigger.Trigger;
import forge.card.trigger.TriggerHandler;
@@ -121,15 +120,7 @@ public class AnimateAllEffect extends AnimateEffectBase {
}
List<Card> list;
List<Player> tgtPlayers = null;
final Target tgt = sa.getTarget();
if (tgt != null) {
tgtPlayers = tgt.getTargetPlayers();
} else if (sa.hasParam("Defined")) {
// use it
tgtPlayers = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("Defined"), sa);
}
List<Player> tgtPlayers = getTargetPlayers(sa);
if ((tgtPlayers == null) || tgtPlayers.isEmpty()) {
list = game.getCardsIn(ZoneType.Battlefield);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -11,7 +11,7 @@ import forge.CardPredicates;
import forge.Constant;
import forge.card.ability.SpellAbilityEffect;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.card.spellability.TargetRestrictions;
import forge.game.Game;
import forge.game.ai.ComputerUtilCard;
import forge.game.player.Player;
@@ -42,7 +42,7 @@ public class ChooseColorEffect extends SpellAbilityEffect {
final List<Player> tgtPlayers = getTargetPlayers(sa);
final Target tgt = sa.getTarget();
final TargetRestrictions tgt = sa.getTargetRestrictions();
for (final Player p : tgtPlayers) {
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.spellability.AbilitySub;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player;
import forge.gui.GuiChoose;
import forge.util.Aggregates;
@@ -41,9 +41,9 @@ public class ChooseGenericEffect extends SpellAbilityEffect {
choices.put(s, theseParams.get("ChoiceDescription"));
}
final List<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) {
if (tgt != null && !p.canBeTargetedBy(sa)) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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