mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
- Fixed BecomesTarget sometimes not triggering.
This commit is contained in:
@@ -277,6 +277,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
*/
|
*/
|
||||||
public final void add(final SpellAbility sp) {
|
public final void add(final SpellAbility sp) {
|
||||||
FThreads.assertExecutedByEdt(false);
|
FThreads.assertExecutedByEdt(false);
|
||||||
|
SpellAbilityStackInstance si = null;
|
||||||
|
|
||||||
if (sp.isManaAbility()) { // Mana Abilities go straight through
|
if (sp.isManaAbility()) { // Mana Abilities go straight through
|
||||||
AbilityUtils.resolve(sp);
|
AbilityUtils.resolve(sp);
|
||||||
@@ -295,7 +296,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.frozen) {
|
if (this.frozen) {
|
||||||
final SpellAbilityStackInstance si = new SpellAbilityStackInstance(sp);
|
si = new SpellAbilityStackInstance(sp);
|
||||||
this.frozenStack.push(si);
|
this.frozenStack.push(si);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -319,7 +320,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
sp.getSourceCard().addOptionalCostPaid(s);
|
sp.getSourceCard().addOptionalCostPaid(s);
|
||||||
}
|
}
|
||||||
if (sp.getSourceCard().isCopiedSpell()) {
|
if (sp.getSourceCard().isCopiedSpell()) {
|
||||||
this.push(sp);
|
si = this.push(sp);
|
||||||
} else {
|
} else {
|
||||||
if (sp.isMultiKicker()) {
|
if (sp.isMultiKicker()) {
|
||||||
final Player activating = sp.getActivatingPlayer();
|
final Player activating = sp.getActivatingPlayer();
|
||||||
@@ -336,7 +337,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The ability is added to stack HERE
|
// The ability is added to stack HERE
|
||||||
this.push(sp);
|
si = this.push(sp);
|
||||||
|
|
||||||
if (sp.isReplicate()) {
|
if (sp.isReplicate()) {
|
||||||
// TODO: convert multikicker/replicate support in abCost so this
|
// TODO: convert multikicker/replicate support in abCost so this
|
||||||
@@ -360,19 +361,16 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
CardFactory.copySpellontoStack(sp.getSourceCard(), sp.getSourceCard(), sp, false, null);
|
CardFactory.copySpellontoStack(sp.getSourceCard(), sp.getSourceCard(), sp, false, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copied spells aren't cast
|
// Copied spells aren't cast per se so triggers shouldn't run for them.
|
||||||
// per se so triggers shouldn't
|
HashMap<String, Object> runParams = new HashMap<String, Object>();
|
||||||
// run for them.
|
|
||||||
if (!(sp instanceof AbilityStatic) && !sp.isCopied()) {
|
if (!(sp instanceof AbilityStatic) && !sp.isCopied()) {
|
||||||
// Run SpellAbilityCast triggers
|
// Run SpellAbilityCast triggers
|
||||||
HashMap<String, Object> runParams = new HashMap<String, Object>();
|
|
||||||
runParams.put("Cost", sp.getPayCosts());
|
runParams.put("Cost", sp.getPayCosts());
|
||||||
runParams.put("Player", sp.getSourceCard().getController());
|
runParams.put("Player", sp.getSourceCard().getController());
|
||||||
runParams.put("Activator", sp.getActivatingPlayer());
|
runParams.put("Activator", sp.getActivatingPlayer());
|
||||||
runParams.put("CastSA", sp);
|
runParams.put("CastSA", si.getSpellAbility());
|
||||||
game.getTriggerHandler().runTrigger(TriggerType.SpellAbilityCast, runParams, true);
|
game.getTriggerHandler().runTrigger(TriggerType.SpellAbilityCast, runParams, true);
|
||||||
|
|
||||||
// Run SpellCast triggers
|
// Run SpellCast triggers
|
||||||
@@ -391,38 +389,37 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
runParams.put("Card", sp.getSourceCard());
|
runParams.put("Card", sp.getSourceCard());
|
||||||
game.getTriggerHandler().runTrigger(TriggerType.Cycled, runParams, false);
|
game.getTriggerHandler().runTrigger(TriggerType.Cycled, runParams, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Run BecomesTarget triggers
|
// Run BecomesTarget triggers
|
||||||
// Create a new object, since the triggers aren't happening right away
|
// Create a new object, since the triggers aren't happening right away
|
||||||
final List<TargetChoices> chosenTargets = sp.getAllTargetChoices();
|
final List<TargetChoices> chosenTargets = sp.getAllTargetChoices();
|
||||||
runParams = new HashMap<String, Object>();
|
runParams = new HashMap<String, Object>();
|
||||||
runParams.put("SourceSA", sp);
|
runParams.put("SourceSA", si.getSpellAbility());
|
||||||
if (!chosenTargets.isEmpty()) {
|
if (!chosenTargets.isEmpty()) {
|
||||||
HashSet<Object> distinctObjects = new HashSet<Object>();
|
HashSet<Object> distinctObjects = new HashSet<Object>();
|
||||||
for (final TargetChoices tc : chosenTargets) {
|
for (final TargetChoices tc : chosenTargets) {
|
||||||
if ((tc != null) && (tc.getTargetCards() != null)) {
|
if (tc != null && tc.getTargetCards() != null) {
|
||||||
for (final Object tgt : tc.getTargets()) {
|
for (final Object tgt : tc.getTargets()) {
|
||||||
// Track distinct objects so Becomes targets don't trigger for things like:
|
// Track distinct objects so Becomes targets don't trigger for things like:
|
||||||
// Seeds of Strength or Pyrotechnics
|
// Seeds of Strength
|
||||||
if (distinctObjects.contains(tgt)) {
|
if (distinctObjects.contains(tgt)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
distinctObjects.add(tgt);
|
|
||||||
runParams.put("Target", tgt);
|
|
||||||
game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
distinctObjects.add(tgt);
|
||||||
|
runParams.put("Target", tgt);
|
||||||
|
game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// Not sure these clauses are necessary. Consider it a precaution
|
||||||
|
// for backwards compatibility for hardcoded cards.
|
||||||
|
else if (sp.getTargetCard() != null) {
|
||||||
|
runParams.put("Target", sp.getTargetCard());
|
||||||
|
|
||||||
// Not sure these clauses are necessary. Consider it a precaution
|
game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false);
|
||||||
// for backwards compatibility for hardcoded cards.
|
|
||||||
else if (sp.getTargetCard() != null) {
|
|
||||||
runParams.put("Target", sp.getTargetCard());
|
|
||||||
|
|
||||||
game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.simultaneousStackEntryList.isEmpty()) {
|
if (!this.simultaneousStackEntryList.isEmpty()) {
|
||||||
@@ -455,7 +452,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Push should only be used by add.
|
// Push should only be used by add.
|
||||||
private void push(final SpellAbility sp) {
|
private SpellAbilityStackInstance push(final SpellAbility sp) {
|
||||||
if (null == sp.getActivatingPlayer()) {
|
if (null == sp.getActivatingPlayer()) {
|
||||||
sp.setActivatingPlayer(sp.getSourceCard().getController());
|
sp.setActivatingPlayer(sp.getSourceCard().getController());
|
||||||
System.out.println(sp.getSourceCard().getName() + " - activatingPlayer not set before adding to stack.");
|
System.out.println(sp.getSourceCard().getName() + " - activatingPlayer not set before adding to stack.");
|
||||||
@@ -482,6 +479,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
final Command ripple = new RippleExecutor(sp.getActivatingPlayer(), sp.getSourceCard());
|
final Command ripple = new RippleExecutor(sp.getActivatingPlayer(), sp.getSourceCard());
|
||||||
ripple.run();
|
ripple.run();
|
||||||
}
|
}
|
||||||
|
return si;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user