mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 03:08:02 +00:00
static utility methods dealing with ability targets moved from TargetChooser to SpellAbility as instance methods
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user