From ca831aee053aebc840c62c8ec96e5ec9b2b79cad Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 6 Feb 2014 01:02:44 +0100 Subject: [PATCH] if multiple permanents come to battlefield at the same time, they are aware now of each other. (e.g. useful for for Valakut, the Molten Pinnacle). --- Mage/src/mage/abilities/AbilityImpl.java | 2 ++ .../src/mage/abilities/effects/EffectImpl.java | 8 +++----- Mage/src/mage/game/Game.java | 6 ++++++ Mage/src/mage/game/GameImpl.java | 5 +++++ Mage/src/mage/game/GameState.java | 18 ++++++++++++++++++ .../src/mage/game/permanent/PermanentImpl.java | 6 +++++- 6 files changed, 39 insertions(+), 6 deletions(-) diff --git a/Mage/src/mage/abilities/AbilityImpl.java b/Mage/src/mage/abilities/AbilityImpl.java index df7d477acf7..07c3da4f17f 100644 --- a/Mage/src/mage/abilities/AbilityImpl.java +++ b/Mage/src/mage/abilities/AbilityImpl.java @@ -159,6 +159,8 @@ public abstract class AbilityImpl> implements Ability { if (effect.applyEffectsAfter()) { game.applyEffects(); } + // effects like entersBattlefield have to trigger simultanously so objects see each other + game.getState().handleSimultaneousEvent(game); } } return result; diff --git a/Mage/src/mage/abilities/effects/EffectImpl.java b/Mage/src/mage/abilities/effects/EffectImpl.java index a5fa63225f4..8bf08bc8c11 100644 --- a/Mage/src/mage/abilities/effects/EffectImpl.java +++ b/Mage/src/mage/abilities/effects/EffectImpl.java @@ -118,11 +118,9 @@ public abstract class EffectImpl> implements Effect { @Override public void setValue(String key, Object value) { - if (values == null) { - synchronized (this) { - if (values == null) { - values = new HashMap(); - } + synchronized (this) { + if (values == null) { + values = new HashMap(); } } values.put(key, value); diff --git a/Mage/src/mage/game/Game.java b/Mage/src/mage/game/Game.java index 9fd27049dc3..3035f2a4539 100644 --- a/Mage/src/mage/game/Game.java +++ b/Mage/src/mage/game/Game.java @@ -172,6 +172,12 @@ public interface Game extends MageItem, Serializable { //game event methods void fireEvent(GameEvent event); + /** + * The events are stored until the resolution of the current effect ends + * and fired then all together (e.g. X lands enter the battlefield from Scapeshift) + * @param event + */ + void addSimultaneousEvent(GameEvent event); boolean replaceEvent(GameEvent event); //game play methods diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index b0026657400..8086c8660d6 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -1790,6 +1790,11 @@ public abstract class GameImpl> implements Game, Serializa return state.getPriorityPlayerId(); } + @Override + public void addSimultaneousEvent(GameEvent event) { + state.addSimultaneousEvent(event, this); + } + @Override public void fireEvent(GameEvent event) { state.handleEvent(event, this); diff --git a/Mage/src/mage/game/GameState.java b/Mage/src/mage/game/GameState.java index 3e3b0abb01b..f1367b83bba 100644 --- a/Mage/src/mage/game/GameState.java +++ b/Mage/src/mage/game/GameState.java @@ -96,6 +96,7 @@ public class GameState implements Serializable, Copyable { private final Map> otherAbilities = new HashMap>(); private final TurnMods turnMods; private final Watchers watchers; + private UUID activePlayerId; private UUID priorityPlayerId; @@ -114,6 +115,7 @@ public class GameState implements Serializable, Copyable { private Combat combat; private Map values = new HashMap(); private Map zones = new HashMap(); + private List simultaneousEvents = new ArrayList(); public GameState() { players = new Players(); @@ -172,6 +174,7 @@ public class GameState implements Serializable, Copyable { otherAbilities.put(entry.getKey(), entry.getValue().copy()); } this.paused = state.paused; + this.simultaneousEvents.addAll(state.simultaneousEvents); } @Override @@ -482,6 +485,20 @@ public class GameState implements Serializable, Copyable { Player origPlayer = players.get(copyPlayer.getId()); origPlayer.restore(copyPlayer); } + this.simultaneousEvents = state.simultaneousEvents; + } + + public void addSimultaneousEvent(GameEvent event, Game game) { + simultaneousEvents.add(event); + } + + public void handleSimultaneousEvent(Game game) { + if (!simultaneousEvents.isEmpty()) { + for (GameEvent event:simultaneousEvents) { + this.handleEvent(event, game); + } + simultaneousEvents.clear(); + } } public void handleEvent(GameEvent event, Game game) { @@ -665,6 +682,7 @@ public class GameState implements Serializable, Copyable { watchers.clear(); values.clear(); zones.clear(); + simultaneousEvents.clear(); } public void pause() { diff --git a/Mage/src/mage/game/permanent/PermanentImpl.java b/Mage/src/mage/game/permanent/PermanentImpl.java index 1f7817b2bb1..a9582888d28 100644 --- a/Mage/src/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/mage/game/permanent/PermanentImpl.java @@ -748,7 +748,11 @@ public abstract class PermanentImpl> extends CardImpl EntersTheBattlefieldEvent event = new EntersTheBattlefieldEvent(this, sourceId, getControllerId(), fromZone); if (!game.replaceEvent(event)) { if (fireEvent) { - game.fireEvent(event); + if (sourceId == null) { // play lands + game.fireEvent(event); + } else { // from effects + game.addSimultaneousEvent(event); + } } } }