mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
- 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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user