- Force certain triggers to wait for the next WaitingTrigger run (e.g. Fix Balefire Liege issue), there may be a few more of these that need to be forced

- Fixed "BecomesTarget" triggering for the same Object more than once for the same spell
This commit is contained in:
Sol
2013-01-08 04:29:56 +00:00
parent daee42b4da
commit fb27a0d956
14 changed files with 56 additions and 46 deletions

View File

@@ -269,7 +269,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|| (cur == CardCharacteristicName.Transformed && state == CardCharacteristicName.Original)) {
HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Transformer", this);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Transformed, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Transformed, runParams, false);
}
return true;
@@ -375,7 +375,7 @@ public class Card extends GameEntity implements Comparable<Card> {
// Run triggers
final Map<String, Object> runParams = new TreeMap<String, Object>();
runParams.put("Card", this);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.TurnFaceUp, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.TurnFaceUp, runParams, false);
}
return result;
}
@@ -1243,7 +1243,7 @@ public class Card extends GameEntity implements Comparable<Card> {
runParams.put("Card", this);
runParams.put("CounterType", counterType);
for (int i = 0; i < addAmount; i++) {
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.CounterAdded, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.CounterAdded, runParams, false);
}
// play the Add Counter sound
@@ -1282,7 +1282,7 @@ public class Card extends GameEntity implements Comparable<Card> {
runParams.put("Card", this);
runParams.put("CounterType", counterName);
for (int i = 0; i < delta; i++) {
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.CounterRemoved, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.CounterRemoved, runParams, false);
}
if (counterName.equals(CounterType.TIME) && (newValue == 0)) {
@@ -3834,7 +3834,7 @@ public class Card extends GameEntity implements Comparable<Card> {
final Map<String, Object> runParams = new TreeMap<String, Object>();
runParams.put("Equipment", this);
runParams.put("Card", c);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Unequip, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Unequip, runParams, false);
}
/**
@@ -4838,7 +4838,7 @@ public class Card extends GameEntity implements Comparable<Card> {
// Run triggers
final Map<String, Object> runParams = new TreeMap<String, Object>();
runParams.put("Card", this);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Taps, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Taps, runParams, false);
}
this.setTapped(true);
@@ -4856,7 +4856,7 @@ public class Card extends GameEntity implements Comparable<Card> {
// Run triggers
final Map<String, Object> runParams = new TreeMap<String, Object>();
runParams.put("Card", this);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Untaps, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Untaps, runParams, false);
// Play the Untap sound
Singletons.getModel().getGame().getEvents().post(new SetTappedEvent(false));
@@ -8278,7 +8278,7 @@ public class Card extends GameEntity implements Comparable<Card> {
runParams.put("DamageTarget", this);
runParams.put("DamageAmount", damageToAdd);
runParams.put("IsCombatDamage", isCombat);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.DamageDone, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.DamageDone, runParams, false);
if (this.isPlaneswalker()) {
this.subtractCounter(CounterType.LOYALTY, damageToAdd);

View File

@@ -237,7 +237,7 @@ public class GameAction {
runParams.put("Origin", null);
}
runParams.put("Destination", zoneTo.getZoneType().name());
game.getTriggerHandler().runTrigger(TriggerType.ChangesZone, runParams);
game.getTriggerHandler().runTrigger(TriggerType.ChangesZone, runParams, false);
// AllZone.getStack().chooseOrderOfSimultaneousStackEntryAll();
if (suppress) {
@@ -443,7 +443,7 @@ public class GameAction {
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Card", c);
game.getTriggerHandler().runTrigger(TriggerType.ChangesController, runParams);
game.getTriggerHandler().runTrigger(TriggerType.ChangesController, runParams, false);
game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone);
for (Player p : game.getPlayers()) {
@@ -700,7 +700,7 @@ public class GameAction {
runParams.put("Origin", null);
}
runParams.put("Destination", ZoneType.Library.name());
game.getTriggerHandler().runTrigger(TriggerType.ChangesZone, runParams);
game.getTriggerHandler().runTrigger(TriggerType.ChangesZone, runParams, false);
if (p != null) {
p.updateLabelObservers();
@@ -1050,7 +1050,7 @@ public class GameAction {
this.checkStaticAbilities();
final HashMap<String, Object> runParams = new HashMap<String, Object>();
game.getTriggerHandler().runTrigger(TriggerType.Always, runParams);
game.getTriggerHandler().runTrigger(TriggerType.Always, runParams, false);
for (Card c : game.getCardsIn(ZoneType.Battlefield)) {
@@ -1292,7 +1292,7 @@ public class GameAction {
// Run triggers
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Card", c);
game.getTriggerHandler().runTrigger(TriggerType.Sacrificed, runParams);
game.getTriggerHandler().runTrigger(TriggerType.Sacrificed, runParams, false);
return true;
}

View File

@@ -53,7 +53,7 @@ public class ClashEffect extends SpellEffect {
runParams.put("Won", "False");
}
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Clashed, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Clashed, runParams, false);
}
}

View File

@@ -1247,7 +1247,7 @@ public class CardFactoryUtil {
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Card", spell.getSourceCard());
runParams.put("Championed", card);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Championed, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Championed, runParams, false);
}
}
} // selectCard()

View File

@@ -144,7 +144,7 @@ public class AbilityManaPart implements java.io.Serializable {
runParams.put("Player", player);
runParams.put("AbilityMana", sa);
runParams.put("Produced", produced);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.TapsForMana, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.TapsForMana, runParams, false);
} // end produceMana(String)

View File

@@ -120,7 +120,7 @@ public class SpellPermanent extends Spell {
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Card", source);
runParams.put("Championed", source.getChampionedCard());
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Championed, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Championed, runParams, false);
} else {
Singletons.getModel().getGame().getAction().sacrifice(this.getSourceCard(), null);
}

View File

@@ -262,8 +262,9 @@ public class TriggerHandler {
* a {@link java.lang.String} object.
* @param runParams
* a {@link java.util.Map} object.
* @param forceHeldTriggers Force certain triggers to be added the waitingTriggers if stack isnt frozen
*/
public final void runTrigger(final TriggerType mode, final Map<String, Object> runParams) {
public final void runTrigger(final TriggerType mode, final Map<String, Object> runParams, boolean holdTrigger) {
if (this.suppressedModes.contains(mode)) {
return;
}
@@ -272,7 +273,7 @@ public class TriggerHandler {
//runWaitingTrigger(new TriggerWaiting(mode, runParams));
if (game.getStack().isFrozen()) {
if (game.getStack().isFrozen() || holdTrigger) {
waitingTriggers.add(new TriggerWaiting(mode, runParams));
} else {
runWaitingTrigger(new TriggerWaiting(mode, runParams), true);

View File

@@ -502,7 +502,7 @@ public class GameState {
final Map<String, Object> runParams = new TreeMap<String, Object>();
runParams.put("Player", p);
this.getTriggerHandler().runTrigger(TriggerType.LosesGame, runParams);
this.getTriggerHandler().runTrigger(TriggerType.LosesGame, runParams, false);
}

View File

@@ -676,7 +676,7 @@ public class Combat {
// Run Unblocked Trigger
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Attacker", attacker);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.AttackerUnblocked, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.AttackerUnblocked, runParams, false);
}
}

View File

@@ -2799,7 +2799,7 @@ public class CombatUtil {
otherAttackers.remove(c);
runParams.put("OtherAttackers", otherAttackers);
runParams.put("Attacked", Singletons.getModel().getGame().getCombat().getDefenderByAttacker(c));
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Attacks, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Attacks, runParams, false);
// Annihilator:
if (!c.getDamageHistory().getCreatureAttackedThisCombat()) {
@@ -2917,7 +2917,7 @@ public class CombatUtil {
// Run triggers
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Card", c);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.AttackerUnblocked, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.AttackerUnblocked, runParams, false);
}
/**
@@ -2958,12 +2958,12 @@ public class CombatUtil {
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Attacker", a);
runParams.put("Blocker", b);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Blocks, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Blocks, runParams, false);
if (!a.getDamageHistory().getCreatureGotBlockedThisCombat()) {
final int blockers = Singletons.getModel().getGame().getCombat().getBlockers(a).size();
runParams.put("NumBlockers", blockers);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.AttackerBlocked, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.AttackerBlocked, runParams, false);
// Bushido
for (final Ability ab : CardFactoryUtil.getBushidoEffects(a)) {

View File

@@ -395,7 +395,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Phase", this.getPhase().Name);
runParams.put("Player", this.getPlayerTurn());
game.getTriggerHandler().runTrigger(TriggerType.Phase, runParams);
game.getTriggerHandler().runTrigger(TriggerType.Phase, runParams, false);
}

View File

@@ -200,7 +200,7 @@ public class PhaseUtil {
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Attackers", list);
runParams.put("AttackingPlayer", Singletons.getModel().getGame().getCombat().getAttackingPlayer());
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.AttackersDeclared, runParams);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.AttackersDeclared, runParams, false);
for (final Card c : list) {
CombatUtil.checkDeclareAttackers(c);

View File

@@ -256,7 +256,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
// Run triggers
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Scheme", activeScheme);
game.getTriggerHandler().runTrigger(TriggerType.SetInMotion, runParams);
game.getTriggerHandler().runTrigger(TriggerType.SetInMotion, runParams, false);
}
/**
@@ -458,7 +458,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Player", this);
runParams.put("LifeAmount", lifeGain);
game.getTriggerHandler().runTrigger(TriggerType.LifeGained, runParams);
game.getTriggerHandler().runTrigger(TriggerType.LifeGained, runParams, false);
} else {
System.out.println("Player - trying to gain negative or 0 life");
}
@@ -514,7 +514,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Player", this);
runParams.put("LifeAmount", toLose);
game.getTriggerHandler().runTrigger(TriggerType.LifeLost, runParams);
game.getTriggerHandler().runTrigger(TriggerType.LifeLost, runParams, false);
return lifeLost;
}
@@ -654,7 +654,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
runParams.put("DamageTarget", this);
runParams.put("DamageAmount", damageToDo);
runParams.put("IsCombatDamage", isCombat);
game.getTriggerHandler().runTrigger(TriggerType.DamageDone, runParams);
game.getTriggerHandler().runTrigger(TriggerType.DamageDone, runParams, false);
return true;
}
@@ -1438,7 +1438,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Card", c);
runParams.put("Number", this.numDrawnThisTurn);
game.getTriggerHandler().runTrigger(TriggerType.Drawn, runParams);
game.getTriggerHandler().runTrigger(TriggerType.Drawn, runParams, false);
}
// lose:
else if (!Preferences.DEV_MODE || Singletons.getModel().getPreferences().getPrefBoolean(FPref.DEV_MILLING_LOSS)) {
@@ -1723,7 +1723,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
runParams.put("Player", this);
runParams.put("Card", c);
runParams.put("Cause", cause);
game.getTriggerHandler().runTrigger(TriggerType.Discarded, runParams);
game.getTriggerHandler().runTrigger(TriggerType.Discarded, runParams, false);
} // end doDiscard
@@ -1895,7 +1895,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
// Run triggers
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Player", this);
game.getTriggerHandler().runTrigger(TriggerType.Shuffled, runParams);
game.getTriggerHandler().runTrigger(TriggerType.Shuffled, runParams, false);
// Play the shuffle sound
Singletons.getModel().getGame().getEvents().post(new ShuffleEvent());
@@ -1963,7 +1963,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
// Run triggers
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Card", land);
game.getTriggerHandler().runTrigger(TriggerType.LandPlayed, runParams);
game.getTriggerHandler().runTrigger(TriggerType.LandPlayed, runParams, false);
}
game.getStack().unfreezeStack();

View File

@@ -19,6 +19,7 @@ package forge.game.zone;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Stack;
@@ -694,40 +695,48 @@ public class MagicStack extends MyObservable {
// run for them.
if (!sp.getSourceCard().isCopiedSpell() && !(sp instanceof AbilityStatic) && !sp.isCopied()) {
// Run SpellAbilityCast triggers
final HashMap<String, Object> runParams = new HashMap<String, Object>();
HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Cost", sp.getPayCosts());
runParams.put("Player", sp.getSourceCard().getController());
runParams.put("Activator", sp.getActivatingPlayer());
runParams.put("CastSA", sp);
game.getTriggerHandler().runTrigger(TriggerType.SpellAbilityCast, runParams);
game.getTriggerHandler().runTrigger(TriggerType.SpellAbilityCast, runParams, true);
// Run SpellCast triggers
if (sp.isSpell()) {
game.getTriggerHandler().runTrigger(TriggerType.SpellCast, runParams);
game.getTriggerHandler().runTrigger(TriggerType.SpellCast, runParams, true);
}
// Run AbilityCast triggers
if (sp.isAbility() && !sp.isTrigger()) {
game.getTriggerHandler().runTrigger(TriggerType.AbilityCast, runParams);
game.getTriggerHandler().runTrigger(TriggerType.AbilityCast, runParams, true);
}
// Run Cycled triggers
if (sp.isCycling()) {
runParams.clear();
runParams.put("Card", sp.getSourceCard());
game.getTriggerHandler().runTrigger(TriggerType.Cycled, runParams);
game.getTriggerHandler().runTrigger(TriggerType.Cycled, runParams, false);
}
// Run BecomesTarget triggers
runParams.clear();
// Create a new object, since the triggers aren't happening right away
runParams = new HashMap<String, Object>();
runParams.put("SourceSA", sp);
if (chosenTargets.size() > 0) {
HashSet<Object> distinctObjects = new HashSet<Object>();
for (final TargetChoices tc : chosenTargets) {
if ((tc != null) && (tc.getTargetCards() != null)) {
for (final Object tgt : tc.getTargets()) {
runParams.put("Target", tgt);
// Track distinct objects so Becomes targets don't trigger for things like:
// Seeds of Strength or Pyrotechnics
if (distinctObjects.contains(tgt)) {
continue;
}
game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams);
distinctObjects.add(tgt);
runParams.put("Target", tgt);
game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false);
}
}
}
@@ -738,11 +747,11 @@ public class MagicStack extends MyObservable {
else if (sp.getTargetCard() != null) {
runParams.put("Target", sp.getTargetCard());
game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams);
game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false);
} else if (sp.getTargetPlayer() != null) {
runParams.put("Target", sp.getTargetPlayer());
game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams);
game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false);
}
}