static utility methods dealing with ability targets moved from TargetChooser to SpellAbility as instance methods

This commit is contained in:
Maxmtg
2013-04-01 15:06:20 +00:00
parent 0700036b96
commit b532e7147e
5 changed files with 96 additions and 95 deletions

View File

@@ -8,7 +8,6 @@ import forge.card.cardfactory.CardFactoryUtil;
import forge.card.cost.Cost;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.card.spellability.TargetChooser;
import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCost;
import forge.game.ai.ComputerUtilMana;
@@ -50,7 +49,7 @@ public class CounterAi extends SpellAbilityAi {
}
tgt.resetTargets();
if (TargetChooser.matchSpellAbility(sa, topSA, tgt)) {
if (sa.canTargetSpellAbility(topSA)) {
tgt.addTarget(topSA);
} else {
return false;
@@ -120,7 +119,7 @@ public class CounterAi extends SpellAbilityAi {
}
tgt.resetTargets();
if (TargetChooser.matchSpellAbility(sa, topSA, tgt)) {
if (sa.canTargetSpellAbility(topSA)) {
tgt.addTarget(topSA);
} else {
return false;

View File

@@ -15,7 +15,6 @@ import forge.card.cost.Cost;
import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.card.spellability.TargetChooser;
import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCombat;
@@ -143,7 +142,7 @@ public class DamageDealAi extends DamageAiBase {
final ArrayList<Object> objects = tgt.getTargets();
if (saMe.hasParam("TargetUnique")) {
objects.addAll(TargetChooser.getUniqueTargets(saMe));
objects.addAll(saMe.getUniqueTargets());
}
for (final Object o : objects) {
if (o instanceof Card) {

View File

@@ -1313,7 +1313,7 @@ public abstract class SpellAbility implements ISpellAbility {
return false;
}
if (entity.isValid(this.getTarget().getValidTgts(), this.getActivatingPlayer(), this.getSourceCard())
&& (!this.getTarget().isUniqueTargets() || !TargetChooser.getUniqueTargets(this).contains(entity))
&& (!this.getTarget().isUniqueTargets() || !this.getUniqueTargets().contains(entity))
&& entity.canBeTargetedBy(this)) {
return true;
}
@@ -1679,4 +1679,92 @@ public abstract class SpellAbility implements ISpellAbility {
public void setCopied(boolean isCopied0) {
this.isCopied = isCopied0;
}
/**
* Gets the unique targets.
*
* @param ability
* the ability
* @return the unique targets
*/
public final ArrayList<Object> getUniqueTargets() {
final ArrayList<Object> targets = new ArrayList<Object>();
SpellAbility child = this;
while (child instanceof AbilitySub) {
child = ((AbilitySub) child).getParent();
if (child != null && child.getTarget() != null) {
targets.addAll(child.getTarget().getTargets());
}
}
return targets;
}
public boolean canTargetSpellAbility(final SpellAbility topSA) {
final Target tgt = this.getTarget();
final String saType = tgt.getTargetSpellAbilityType();
if (null == saType) {
// just take this to mean no restrictions - carry on.
} else if (topSA instanceof Spell) {
if (!saType.contains("Spell")) {
return false;
}
} else if (topSA.isTrigger()) {
if (!saType.contains("Triggered")) {
return false;
}
} else if (topSA instanceof AbilityActivated) {
if (!saType.contains("Activated")) {
return false;
}
} else {
return false; //Static ability? Whatever.
}
final String splitTargetRestrictions = tgt.getSAValidTargeting();
if (splitTargetRestrictions != null) {
// TODO What about spells with SubAbilities with Targets?
final Target matchTgt = topSA.getTarget();
if (matchTgt == null) {
return false;
}
boolean result = false;
for (final Object o : matchTgt.getTargets()) {
if (matchesValid(o, splitTargetRestrictions.split(","))) {
result = true;
break;
}
}
if (!result) {
return false;
}
}
return topSA.getSourceCard().isValid(tgt.getValidTgts(), this.getActivatingPlayer(), this.getSourceCard());
}
private boolean matchesValid(final Object o, final String[] valids) {
final Card srcCard = this.getSourceCard();
final Player activatingPlayer = this.getActivatingPlayer();
if (o instanceof Card) {
final Card c = (Card) o;
return c.isValid(valids, activatingPlayer, srcCard);
}
if (o instanceof Player) {
Player p = (Player) o;
if (p.isValid(valids, activatingPlayer, srcCard)) {
return true;
}
}
return false;
}
}

View File

@@ -158,25 +158,7 @@ public class TargetChooser {
return chooseTargets();
}
/**
* Gets the unique targets.
*
* @param ability
* the ability
* @return the unique targets
*/
public static final ArrayList<Object> getUniqueTargets(final SpellAbility ability) {
final ArrayList<Object> targets = new ArrayList<Object>();
SpellAbility child = ability;
while (child instanceof AbilitySub) {
child = ((AbilitySub) child).getParent();
if (child != null && child.getTarget() != null) {
targets.addAll(child.getTarget().getTargets());
}
}
return targets;
}
// these have been copied over from CardFactoryUtil as they need two extra
// parameters for target selection.
@@ -204,7 +186,7 @@ public class TargetChooser {
choices.remove(tgt.getSourceCard());
}
}
ArrayList<Object> objects = getUniqueTargets(this.ability);
ArrayList<Object> objects = this.ability.getUniqueTargets();
if (tgt.isUniqueTargets()) {
for (final Object o : objects) {
@@ -419,7 +401,7 @@ public class TargetChooser {
}
for (int i = 0; i < choosables.size(); i++) {
if (!TargetChooser.matchSpellAbility(ability, choosables.get(i), getTgt())) {
if (!ability.canTargetSpellAbility(choosables.get(i))) {
choosables.remove(i);
}
}
@@ -439,70 +421,4 @@ public class TargetChooser {
* a {@link forge.card.spellability.Target} object.
* @return a boolean.
*/
public static boolean matchSpellAbility(final SpellAbility sa, final SpellAbility topSA, final Target tgt) {
final String saType = tgt.getTargetSpellAbilityType();
if (null == saType) {
// just take this to mean no restrictions - carry on.
} else if (topSA instanceof Spell) {
if (!saType.contains("Spell")) {
return false;
}
} else if (topSA.isTrigger()) {
if (!saType.contains("Triggered")) {
return false;
}
} else if (topSA instanceof AbilityActivated) {
if (!saType.contains("Activated")) {
return false;
}
} else {
return false; //Static ability? Whatever.
}
final String splitTargetRestrictions = tgt.getSAValidTargeting();
if (splitTargetRestrictions != null) {
// TODO What about spells with SubAbilities with Targets?
final Target matchTgt = topSA.getTarget();
if (matchTgt == null) {
return false;
}
boolean result = false;
for (final Object o : matchTgt.getTargets()) {
if (TargetChooser.matchesValid(o, splitTargetRestrictions.split(","), sa)) {
result = true;
break;
}
}
if (!result) {
return false;
}
}
return topSA.getSourceCard().isValid(tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard());
}
private static boolean matchesValid(final Object o, final String[] valids, final SpellAbility sa) {
final Card srcCard = sa.getSourceCard();
final Player activatingPlayer = sa.getActivatingPlayer();
if (o instanceof Card) {
final Card c = (Card) o;
return c.isValid(valids, activatingPlayer, srcCard);
}
if (o instanceof Player) {
Player p = (Player) o;
if (p.isValid(valids, sa.getActivatingPlayer(), sa.getSourceCard())) {
return true;
}
}
return false;
}
}

View File

@@ -42,7 +42,6 @@ import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityStackInstance;
import forge.card.spellability.Target;
import forge.card.spellability.TargetChoices;
import forge.card.spellability.TargetChooser;
import forge.card.trigger.Trigger;
import forge.card.trigger.TriggerType;
import forge.control.input.InputPayManaExecuteCommands;
@@ -885,7 +884,7 @@ public class MagicStack extends MyObservable {
}
else if (o instanceof SpellAbility) {
final SpellAbility tgtSA = (SpellAbility) o;
invalidTarget = !(TargetChooser.matchSpellAbility(sa, tgtSA, tgt));
invalidTarget = !(sa.canTargetSpellAbility(tgtSA));
// TODO Remove target?
if (invalidTarget) {
choices.removeTarget(tgtSA);