diff --git a/.gitattributes b/.gitattributes index cb6033d8ab4..cfcce973122 100644 --- a/.gitattributes +++ b/.gitattributes @@ -11827,6 +11827,7 @@ src/main/java/forge/util/StorageImmediatelySerialized.java svneol=native#text/pl src/main/java/forge/util/StorageReaderFile.java -text src/main/java/forge/util/StorageReaderFolder.java -text src/main/java/forge/util/StorageView.java -text +src/main/java/forge/util/TextUtil.java -text src/main/java/forge/util/XmlUtil.java -text src/main/java/forge/util/package-info.java -text src/main/java/forge/view/FView.java svneol=native#text/plain diff --git a/src/main/java/forge/CombatUtil.java b/src/main/java/forge/CombatUtil.java index 98b3f7af878..3e381860682 100644 --- a/src/main/java/forge/CombatUtil.java +++ b/src/main/java/forge/CombatUtil.java @@ -1435,7 +1435,8 @@ public class CombatUtil { return false; } - if (trigParams.get("Mode").equals("Attacks")) { + TriggerType mode = trigger.getMode(); + if (mode == TriggerType.Attacks ) { willTrigger = true; if (attacker.isAttacking()) { return false; // The trigger should have triggered already @@ -1450,7 +1451,7 @@ public class CombatUtil { } // defender == null means unblocked - if ((defender == null) && trigParams.get("Mode").equals("AttackerUnblocked")) { + if ((defender == null) && mode == TriggerType.AttackerUnblocked) { willTrigger = true; if (trigParams.containsKey("ValidCard")) { if (!TriggerReplacementBase.matchesValid(attacker, trigParams.get("ValidCard").split(","), source)) { @@ -1463,7 +1464,7 @@ public class CombatUtil { return willTrigger; } - if (trigParams.get("Mode").equals("Blocks")) { + if (mode == TriggerType.Blocks) { willTrigger = true; if (trigParams.containsKey("ValidBlocked")) { if (!TriggerReplacementBase.matchesValid(attacker, trigParams.get("ValidBlocked").split(","), source)) { @@ -1475,7 +1476,7 @@ public class CombatUtil { return false; } } - } else if (trigParams.get("Mode").equals("AttackerBlocked") && (defender != null)) { + } else if (mode == TriggerType.AttackerBlocked && (defender != null)) { willTrigger = true; if (trigParams.containsKey("ValidBlocker")) { if (!TriggerReplacementBase.matchesValid(defender, trigParams.get("ValidBlocker").split(","), source)) { diff --git a/src/main/java/forge/ComputerAIGeneral.java b/src/main/java/forge/ComputerAIGeneral.java index 817e24762e3..7e104f86d90 100644 --- a/src/main/java/forge/ComputerAIGeneral.java +++ b/src/main/java/forge/ComputerAIGeneral.java @@ -29,6 +29,7 @@ import forge.card.cardfactory.CardFactoryUtil; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellPermanent; import forge.card.trigger.Trigger; +import forge.card.trigger.TriggerType; /** *

@@ -153,7 +154,7 @@ public class ComputerAIGeneral implements Computer { final ArrayList triggers = card.getTriggers(); for (final Trigger tr : triggers) { final HashMap params = tr.getMapParams(); - if (!params.get("Mode").equals("ChangesZone")) { + if (tr.getMode() != TriggerType.ChangesZone) { continue; } diff --git a/src/main/java/forge/ComputerUtilAttack.java b/src/main/java/forge/ComputerUtilAttack.java index e7d9efd2dfb..743df52f8ce 100644 --- a/src/main/java/forge/ComputerUtilAttack.java +++ b/src/main/java/forge/ComputerUtilAttack.java @@ -25,6 +25,7 @@ import java.util.Random; import forge.Constant.Zone; import forge.card.cardfactory.CardFactoryUtil; import forge.card.trigger.Trigger; +import forge.card.trigger.TriggerType; import forge.util.MyRandom; //doesHumanAttackAndWin() uses the global variable AllZone.getComputerPlayer() @@ -88,8 +89,7 @@ public class ComputerUtilAttack { for (final Card attacker : in) { final ArrayList registeredTriggers = attacker.getTriggers(); for (final Trigger trigger : registeredTriggers) { - final HashMap trigParams = trigger.getMapParams(); - if (trigParams.get("Mode").equals("Attacks")) { + if( trigger.getMode() == TriggerType.Attacks) { list.add(attacker); } } diff --git a/src/main/java/forge/GameAction.java b/src/main/java/forge/GameAction.java index d6e3ff63208..8eae68db3e3 100644 --- a/src/main/java/forge/GameAction.java +++ b/src/main/java/forge/GameAction.java @@ -80,18 +80,18 @@ public class GameAction { * changeZone. *

* - * @param prev + * @param zoneFrom * a {@link forge.PlayerZone} object. - * @param zone + * @param zoneTo * a {@link forge.PlayerZone} object. * @param c * a {@link forge.Card} object. * @return a {@link forge.Card} object. */ - public static Card changeZone(final PlayerZone prev, final PlayerZone zone, final Card c) { - if ((prev == null) && !c.isToken()) { - zone.add(c); - Player p = zone.getPlayer(); + public static Card changeZone(final PlayerZone zoneFrom, final PlayerZone zoneTo, final Card c) { + if ((zoneFrom == null) && !c.isToken()) { + zoneTo.add(c); + Player p = zoneTo.getPlayer(); if (p != null) { p.updateLabelObservers(); } @@ -99,23 +99,23 @@ public class GameAction { } boolean suppress; - if ((prev == null) && !c.isToken()) { + if ((zoneFrom == null) && !c.isToken()) { suppress = true; } else if (c.isToken()) { suppress = false; } else { - suppress = prev.equals(zone); + suppress = zoneFrom.equals(zoneTo); } if (!suppress) { HashMap repParams = new HashMap(); repParams.put("Event", "Moved"); repParams.put("Affected", c); - repParams.put("Origin", prev != null ? prev.getZoneType() : null); - repParams.put("Destination", zone.getZoneType()); + repParams.put("Origin", zoneFrom != null ? zoneFrom.getZoneType() : null); + repParams.put("Destination", zoneTo.getZoneType()); if (AllZone.getReplacementHandler().run(repParams)) { - if (AllZone.getStack().isResolving(c) && !zone.is(Constant.Zone.Graveyard)) { + if (AllZone.getStack().isResolving(c) && !zoneTo.is(Constant.Zone.Graveyard)) { return Singletons.getModel().getGameAction().moveToGraveyard(c); } return c; @@ -128,8 +128,8 @@ public class GameAction { // Don't copy Tokens, Cards staying in same zone, or cards entering // Battlefield - if (c.isToken() || suppress || zone.is(Constant.Zone.Battlefield) || zone.is(Constant.Zone.Stack) - || (prev.is(Constant.Zone.Stack) && zone.is(Constant.Zone.Battlefield))) { + if (c.isToken() || suppress || zoneTo.is(Constant.Zone.Battlefield) || zoneTo.is(Constant.Zone.Stack) + || (zoneFrom.is(Constant.Zone.Stack) && zoneTo.is(Constant.Zone.Battlefield))) { lastKnownInfo = c; copied = c; } else { @@ -160,34 +160,34 @@ public class GameAction { AllZone.getTriggerHandler().suppressMode(TriggerType.ChangesZone); } - zone.add(copied); + zoneTo.add(copied); // Tokens outside the battlefield disappear immideately. - if (copied.isToken() && !zone.is(Constant.Zone.Battlefield)) { - zone.remove(copied); + if (copied.isToken() && !zoneTo.is(Constant.Zone.Battlefield)) { + zoneTo.remove(copied); } - if (prev != null) { - if (prev.is(Constant.Zone.Battlefield) && c.isCreature()) { + if (zoneFrom != null) { + if (zoneFrom.is(Constant.Zone.Battlefield) && c.isCreature()) { AllZone.getCombat().removeFromCombat(c); } - prev.remove(c); + zoneFrom.remove(c); } - Player p = zone.getPlayer(); + Player p = zoneTo.getPlayer(); if (p != null) { p.updateLabelObservers(); } final HashMap runParams = new HashMap(); runParams.put("Card", lastKnownInfo); - if (prev != null) { - runParams.put("Origin", prev.getZoneType().name()); + if (zoneFrom != null) { + runParams.put("Origin", zoneFrom.getZoneType().name()); } else { runParams.put("Origin", null); } - runParams.put("Destination", zone.getZoneType().name()); + runParams.put("Destination", zoneTo.getZoneType().name()); AllZone.getTriggerHandler().runTrigger(TriggerType.ChangesZone, runParams); // AllZone.getStack().chooseOrderOfSimultaneousStackEntryAll(); @@ -198,10 +198,10 @@ public class GameAction { // remove all counters from the card if destination is not the // battlefield // UNLESS we're dealing with Skullbriar, the Walking Grave - if (!zone.is(Constant.Zone.Battlefield)) { + if (!zoneTo.is(Constant.Zone.Battlefield)) { // remove all counters from the card if destination is not the battlefield // UNLESS we're dealing with Skullbriar, the Walking Grave - if (!(c.getName().equals("Skullbriar, the Walking Grave") && !zone.is(Constant.Zone.Hand) && !zone + if (!(c.getName().equals("Skullbriar, the Walking Grave") && !zoneTo.is(Constant.Zone.Hand) && !zoneTo .is(Constant.Zone.Library))) { copied.clearCounters(); } diff --git a/src/main/java/forge/card/spellability/SpellPermanent.java b/src/main/java/forge/card/spellability/SpellPermanent.java index f0df9efb703..4fbee74eb5c 100644 --- a/src/main/java/forge/card/spellability/SpellPermanent.java +++ b/src/main/java/forge/card/spellability/SpellPermanent.java @@ -433,7 +433,7 @@ public class SpellPermanent extends Spell { // These triggers all care for ETB effects final HashMap params = tr.getMapParams(); - if (!params.get("Mode").equals("ChangesZone")) { + if (tr.getMode() != TriggerType.ChangesZone) { continue; } diff --git a/src/main/java/forge/card/trigger/Trigger.java b/src/main/java/forge/card/trigger/Trigger.java index 8a546753877..5939157169a 100644 --- a/src/main/java/forge/card/trigger/Trigger.java +++ b/src/main/java/forge/card/trigger/Trigger.java @@ -124,6 +124,8 @@ public abstract class Trigger extends TriggerReplacementBase { /** The run params. */ private Map runParams; + + private TriggerType mode; /** The overriding ability. */ private SpellAbility overridingAbility = null; @@ -696,4 +698,20 @@ public abstract class Trigger extends TriggerReplacementBase { public void setId(final int id0) { this.id = id0; } + + /** + * TODO: Write javadoc for this method. + * @return + */ + public TriggerType getMode() { + return mode; + } + + /** + * TODO: Write javadoc for this method. + * @param triggerType + */ + void setMode(TriggerType triggerType) { + mode = triggerType; + } } diff --git a/src/main/java/forge/card/trigger/TriggerHandler.java b/src/main/java/forge/card/trigger/TriggerHandler.java index 63f6df24b33..5457c4d069e 100644 --- a/src/main/java/forge/card/trigger/TriggerHandler.java +++ b/src/main/java/forge/card/trigger/TriggerHandler.java @@ -20,7 +20,6 @@ package forge.card.trigger; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; - import forge.AllZone; import forge.AllZoneUtil; import forge.Card; @@ -329,15 +328,16 @@ public class TriggerHandler { if (this.suppressedModes.contains(mode)) { return; } - + final Player playerAP = Singletons.getModel().getGameState().getPhaseHandler().getPlayerTurn(); - if (playerAP == null) { // This should only happen outside of games, so it's safe to just // abort. return; } + //System.out.println("T:" + mode.toString() + " > " + TextUtil.mapToString(runParams) ); + // This is done to allow the list of triggers to be modified while // triggers are running. final ArrayList delayedTriggersWorkingCopy = new ArrayList(this.delayedTriggers); @@ -418,8 +418,7 @@ public class TriggerHandler { */ private boolean runSingleTrigger(final Trigger regtrig, final TriggerType mode, final Map runParams) { final Map params = regtrig.getMapParams(); - - if (!params.get("Mode").equals(mode.toString())) { + if (regtrig.getMode() != mode) { return false; // Not the right mode. } if (!regtrig.zonesCheck()) { @@ -440,6 +439,7 @@ public class TriggerHandler { // don't trigger again. } } + if (!regtrig.performTest(runParams)) { return false; // Test failed. } diff --git a/src/main/java/forge/card/trigger/TriggerSpellAbilityCast.java b/src/main/java/forge/card/trigger/TriggerSpellAbilityCast.java index cf92c04a02d..9404ff3e023 100644 --- a/src/main/java/forge/card/trigger/TriggerSpellAbilityCast.java +++ b/src/main/java/forge/card/trigger/TriggerSpellAbilityCast.java @@ -60,15 +60,15 @@ public class TriggerSpellAbilityCast extends Trigger { final Card cast = spellAbility.getSourceCard(); final SpellAbilityStackInstance si = AllZone.getStack().getInstanceFromSpellAbility(spellAbility); - if (this.getMapParams().get("Mode").equals("SpellCast")) { + if (this.getMode() == TriggerType.SpellCast) { if (!spellAbility.isSpell()) { return false; } - } else if (this.getMapParams().get("Mode").equals("AbilityCast")) { + } else if (this.getMode() == TriggerType.AbilityCast) { if (!spellAbility.isAbility()) { return false; } - } else if (this.getMapParams().get("Mode").equals("SpellAbilityCast")) { + } else if (this.getMode() == TriggerType.SpellAbilityCast) { // Empty block for readability. } diff --git a/src/main/java/forge/card/trigger/TriggerType.java b/src/main/java/forge/card/trigger/TriggerType.java index 98089ffe054..44de330461c 100644 --- a/src/main/java/forge/card/trigger/TriggerType.java +++ b/src/main/java/forge/card/trigger/TriggerType.java @@ -84,7 +84,9 @@ public enum TriggerType { Class[] pp = c.getParameterTypes(); if ( pp[0] == HashMap.class ) { try { - return c.newInstance(mapParams, host, intrinsic); + Trigger res = c.newInstance(mapParams, host, intrinsic); + res.setMode(this); + return res; } catch (IllegalArgumentException e) { // TODO Auto-generated catch block ignores the exception, but sends it to System.err and probably forge.log. e.printStackTrace(); diff --git a/src/main/java/forge/gui/home/sanctioned/CSubmenuSealed.java b/src/main/java/forge/gui/home/sanctioned/CSubmenuSealed.java index 494f5bfcecb..8dca8934460 100644 --- a/src/main/java/forge/gui/home/sanctioned/CSubmenuSealed.java +++ b/src/main/java/forge/gui/home/sanctioned/CSubmenuSealed.java @@ -28,7 +28,7 @@ import forge.item.CardPrinted; import forge.item.ItemPool; import forge.properties.ForgeProps; import forge.properties.NewConstants; -import net.slightlymagic.braids.util.UtilFunctions; +import forge.util.TextUtil; import org.apache.commons.lang3.StringUtils; /** @@ -190,7 +190,7 @@ public enum CSubmenuSealed implements ICSubmenu { sd = new SealedDeck("Custom"); } else { - throw new IllegalStateException("choice <<" + UtilFunctions.safeToString(o) + throw new IllegalStateException("choice <<" + TextUtil.safeToString(o) + ">> does not equal any of the sealedTypes."); } diff --git a/src/main/java/forge/util/TextUtil.java b/src/main/java/forge/util/TextUtil.java new file mode 100644 index 00000000000..213a1de8053 --- /dev/null +++ b/src/main/java/forge/util/TextUtil.java @@ -0,0 +1,45 @@ +package forge.util; + +import java.util.Map; +import java.util.Map.Entry; + +/** + * TODO: Write javadoc for this type. + * + */ +public class TextUtil { + + /** + * Safely converts an object to a String. + * + * @param obj + * to convert; may be null + * + * @return "null" if obj is null, obj.toString() otherwise + */ + public static String safeToString(final Object obj) { + String result; + + if (obj == null) { + result = "null"; + } else { + result = obj.toString(); + } + + return result; + } + + public static String mapToString(Map map) { + StringBuilder mapAsString = new StringBuilder(); + boolean isFirst = true; + for(Entry p : map.entrySet()) { + if( isFirst ) + isFirst = false; + else + mapAsString.append("; "); + mapAsString.append( p.getKey() + " => " + (p.getValue() == null ? "(null)" : p.getValue().toString()) ); + } + return mapAsString.toString(); + } + +} diff --git a/src/main/java/net/slightlymagic/braids/util/UtilFunctions.java b/src/main/java/net/slightlymagic/braids/util/UtilFunctions.java index 2024c69fddd..9b71d138270 100644 --- a/src/main/java/net/slightlymagic/braids/util/UtilFunctions.java +++ b/src/main/java/net/slightlymagic/braids/util/UtilFunctions.java @@ -28,14 +28,6 @@ import javax.swing.SwingUtilities; */ public final class UtilFunctions { - /** - * Do not instantiate. - */ - private UtilFunctions() { - // empty - } - - /** * Invoke the given Runnable in an Event Dispatch Thread and wait for it to * finish; but try to use SwingUtilities.invokeLater instead whenever @@ -71,26 +63,5 @@ public final class UtilFunctions { } } - - /** - * Safely converts an object to a String. - * - * @param obj - * to convert; may be null - * - * @return "null" if obj is null, obj.toString() otherwise - */ - public static String safeToString(final Object obj) { - String result; - - if (obj == null) { - result = "null"; - } else { - result = obj.toString(); - } - - return result; - } - }