mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 02:38:02 +00:00
- Simplified handling of hasFizzled
- Fizzling will now remove Targets that don't have the same timestamp in their current form as the one that was targeted
This commit is contained in:
@@ -124,6 +124,63 @@ public class TargetChoices {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* removeTarget.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param card
|
||||||
|
* a {@link forge.Card} object.
|
||||||
|
* @return a boolean.
|
||||||
|
*/
|
||||||
|
public final boolean removeTarget(final Card card) {
|
||||||
|
// Do I decrement numTargeted for fizzling targets?
|
||||||
|
if (!this.targetCards.contains(card)) {
|
||||||
|
this.targetCards.remove(card);
|
||||||
|
//this.numTargeted--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* removeTarget.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param pl
|
||||||
|
* a {@link forge.game.player.Player} object.
|
||||||
|
* @return a boolean.
|
||||||
|
*/
|
||||||
|
public final boolean removeTarget(final Player pl) {
|
||||||
|
// Do I decrement numTargeted for fizzling targets?
|
||||||
|
if (!this.targetPlayers.contains(pl)) {
|
||||||
|
this.targetPlayers.remove(pl);
|
||||||
|
//this.numTargeted--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* removeTarget.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param sa
|
||||||
|
* a {@link forge.card.spellability.SpellAbility} object.
|
||||||
|
* @return a boolean.
|
||||||
|
*/
|
||||||
|
public final boolean removeTarget(final SpellAbility sa) {
|
||||||
|
// Do I decrement numTargeted for fizzling targets?
|
||||||
|
if (!this.targetSAs.contains(sa)) {
|
||||||
|
this.targetSAs.remove(sa);
|
||||||
|
//this.numTargeted--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Getter for the field <code>targetCards</code>.
|
* Getter for the field <code>targetCards</code>.
|
||||||
|
|||||||
@@ -1171,61 +1171,68 @@ public class MagicStack extends MyObservable {
|
|||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public final boolean hasFizzled(final SpellAbility sa, final Card source) {
|
public final boolean hasFizzled(final SpellAbility sa, final Card source) {
|
||||||
// By default this has not fizzled
|
// Can't fizzle unless there are some targets
|
||||||
boolean fizzle = false;
|
boolean fizzle = false;
|
||||||
|
|
||||||
boolean firstTarget = true;
|
Target tgt = sa.getTarget();
|
||||||
|
if (tgt != null) {
|
||||||
SpellAbility fizzSA = sa;
|
if (tgt.getMinTargets(source, sa) == 0 && tgt.getNumTargeted() == 0) {
|
||||||
|
// Nothing targeted, and nothing needs to be targeted.
|
||||||
while (true) {
|
|
||||||
final Target tgt = fizzSA.getTarget();
|
|
||||||
if ((tgt != null) && (tgt.getMinTargets(source, fizzSA) == 0) && (tgt.getNumTargeted() == 0)) {
|
|
||||||
// Don't assume fizzled for minTargets == 0 and nothing is
|
|
||||||
// targeted
|
|
||||||
} else if (firstTarget
|
|
||||||
&& ((tgt != null) || (fizzSA.getTargetCard() != null) || (fizzSA.getTargetPlayer() != null))) {
|
|
||||||
// If there is at least 1 target, fizzle switches because ALL
|
|
||||||
// targets need to be invalid
|
|
||||||
fizzle = true;
|
|
||||||
firstTarget = false;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
if (tgt != null) {
|
// Some targets were chosen, fizzling for this subability is now possible
|
||||||
|
fizzle = true;
|
||||||
// With multi-targets, as long as one target is still legal,
|
// With multi-targets, as long as one target is still legal,
|
||||||
// we'll try to go through as much as possible
|
// we'll try to go through as much as possible
|
||||||
final ArrayList<Object> tgts = tgt.getTargets();
|
final ArrayList<Object> tgts = tgt.getTargets();
|
||||||
|
final TargetChoices choices = tgt.getTargetChoices();
|
||||||
for (final Object o : tgts) {
|
for (final Object o : tgts) {
|
||||||
|
boolean invalidTarget = false;
|
||||||
if (o instanceof Player) {
|
if (o instanceof Player) {
|
||||||
final Player p = (Player) o;
|
final Player p = (Player) o;
|
||||||
fizzle &= !(p.canBeTargetedBy(fizzSA));
|
invalidTarget = !(p.canBeTargetedBy(sa));
|
||||||
|
// TODO Remove target?
|
||||||
|
if (invalidTarget) {
|
||||||
|
choices.removeTarget(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (o instanceof Card) {
|
else if (o instanceof Card) {
|
||||||
final Card card = (Card) o;
|
final Card card = (Card) o;
|
||||||
fizzle &= !(CardFactoryUtil.isTargetStillValid(fizzSA, card));
|
Card current = AllZoneUtil.getCardState(card);
|
||||||
}
|
|
||||||
if (o instanceof SpellAbility) {
|
|
||||||
final SpellAbility tgtSA = (SpellAbility) o;
|
|
||||||
fizzle &= !(TargetSelection.matchSpellAbility(fizzSA, tgtSA, tgt));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (fizzSA.getTargetCard() != null) {
|
|
||||||
// Fizzling will only work for Abilities that use the Target
|
|
||||||
// class,
|
|
||||||
// since the info isn't available otherwise
|
|
||||||
fizzle &= !CardFactoryUtil.isTargetStillValid(fizzSA, fizzSA.getTargetCard());
|
|
||||||
} else if (fizzSA.getTargetPlayer() != null) {
|
|
||||||
fizzle &= !fizzSA.getTargetPlayer().canBeTargetedBy(fizzSA);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fizzSA.getSubAbility() != null) {
|
invalidTarget = current.getTimestamp() != card.getTimestamp();
|
||||||
fizzSA = fizzSA.getSubAbility();
|
|
||||||
} else {
|
invalidTarget |= !(CardFactoryUtil.isTargetStillValid(sa, card));
|
||||||
break;
|
|
||||||
|
if (invalidTarget) {
|
||||||
|
choices.removeTarget(card);
|
||||||
|
}
|
||||||
|
// Remove targets
|
||||||
|
}
|
||||||
|
else if (o instanceof SpellAbility) {
|
||||||
|
final SpellAbility tgtSA = (SpellAbility) o;
|
||||||
|
invalidTarget = !(TargetSelection.matchSpellAbility(sa, tgtSA, tgt));
|
||||||
|
// TODO Remove target?
|
||||||
|
if (invalidTarget) {
|
||||||
|
choices.removeTarget(tgtSA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fizzle &= invalidTarget;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (sa.getTargetCard() != null) {
|
||||||
|
fizzle = !CardFactoryUtil.isTargetStillValid(sa, sa.getTargetCard());
|
||||||
|
}
|
||||||
|
else if (sa.getTargetPlayer() != null) {
|
||||||
|
fizzle = !sa.getTargetPlayer().canBeTargetedBy(sa);
|
||||||
|
}
|
||||||
|
|
||||||
return fizzle;
|
if (sa.getSubAbility() == null) {
|
||||||
|
return fizzle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasFizzled(sa.getSubAbility(), source) && fizzle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user