diff --git a/.gitattributes b/.gitattributes index 044c02014bb..79e38ccf2b3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14259,6 +14259,7 @@ src/main/java/forge/game/event/GameEventPlayerPoisoned.java -text src/main/java/forge/game/event/GameEventPlayerPriority.java -text src/main/java/forge/game/event/GameEventShuffle.java -text src/main/java/forge/game/event/GameEventSpellAbilityCast.java -text +src/main/java/forge/game/event/GameEventSpellRemovedFromStack.java -text src/main/java/forge/game/event/GameEventSpellResolved.java -text src/main/java/forge/game/event/GameEventTokenCreated.java -text src/main/java/forge/game/event/GameEventTurnBegan.java -text diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index 71f68339aa3..13cd84733f8 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -3918,8 +3918,8 @@ public class Card extends GameEntity implements Comparable { * @param n * a int. */ - public final void setReplicateMagnitude(final int n) { - this.replicateMagnitude = n; + public final void resetReplicateMagnitude() { + this.replicateMagnitude = 0; } /** diff --git a/src/main/java/forge/card/ability/effects/EndTurnEffect.java b/src/main/java/forge/card/ability/effects/EndTurnEffect.java index dfa0eb8958d..bd14ba684cc 100644 --- a/src/main/java/forge/card/ability/effects/EndTurnEffect.java +++ b/src/main/java/forge/card/ability/effects/EndTurnEffect.java @@ -41,7 +41,6 @@ public class EndTurnEffect extends SpellAbilityEffect { game.getPhaseHandler().endTurnByEffect(); // Update observers - game.getStack().updateObservers(); for (Player p : game.getPlayers()) { p.updateObservers(); p.updateLabelObservers(); diff --git a/src/main/java/forge/control/FControlGameEventHandler.java b/src/main/java/forge/control/FControlGameEventHandler.java index 7aa727a25d9..cb980163df7 100644 --- a/src/main/java/forge/control/FControlGameEventHandler.java +++ b/src/main/java/forge/control/FControlGameEventHandler.java @@ -13,6 +13,9 @@ import forge.game.event.GameEventAnteCardsSelected; import forge.game.event.GameEventGameFinished; import forge.game.event.GameEventGameOutcome; import forge.game.event.GameEventPlayerControl; +import forge.game.event.GameEventSpellAbilityCast; +import forge.game.event.GameEventSpellRemovedFromStack; +import forge.game.event.GameEventSpellResolved; import forge.game.event.GameEventTurnBegan; import forge.game.event.GameEventTurnPhase; import forge.game.event.IGameEventVisitor; @@ -24,6 +27,7 @@ import forge.gui.match.CMatchUI; import forge.gui.match.VMatchUI; import forge.gui.match.ViewWinLose; import forge.gui.match.controllers.CMessage; +import forge.gui.match.controllers.CStack; import forge.gui.match.nonsingleton.VHand; import forge.gui.match.nonsingleton.VField.PhaseLabel; @@ -113,4 +117,30 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base { } }); return null; } + + private final AtomicBoolean stackUpdPlanned = new AtomicBoolean(false); + private final Runnable updStack = new Runnable() { @Override public void run() { + stackUpdPlanned.set(false); + CStack.SINGLETON_INSTANCE.update(); + } + }; + + @Override + public Void visit(GameEventSpellAbilityCast event) { + if ( !stackUpdPlanned.getAndSet(true) ) + FThreads.invokeInEdtNowOrLater(updStack); + return null; + } + @Override + public Void visit(GameEventSpellResolved event) { + if ( !stackUpdPlanned.getAndSet(true) ) + FThreads.invokeInEdtNowOrLater(updStack); + return null; + } + @Override + public Void visit(GameEventSpellRemovedFromStack event) { + if ( !stackUpdPlanned.getAndSet(true) ) + FThreads.invokeInEdtNowOrLater(updStack); + return null; + } } \ No newline at end of file diff --git a/src/main/java/forge/game/GameActionUtil.java b/src/main/java/forge/game/GameActionUtil.java index 4c9ad5aa974..2242644f1af 100644 --- a/src/main/java/forge/game/GameActionUtil.java +++ b/src/main/java/forge/game/GameActionUtil.java @@ -74,7 +74,7 @@ import forge.util.TextUtil; */ public final class GameActionUtil { - private static final class CascadeAbility extends Ability { + public static final class CascadeAbility extends Ability { private final Player controller; private final Card cascCard; @@ -132,7 +132,7 @@ public final class GameActionUtil { } } - private static final class CascadeExecutor implements Command { + public static final class CascadeExecutor implements Command { private final Card c; private final Game game; private final Player controller; @@ -144,7 +144,7 @@ public final class GameActionUtil { * @param controller * @param c */ - private CascadeExecutor(Player controller, Card c, final Game game) { + public CascadeExecutor(Player controller, Card c, final Game game) { this.controller = controller; this.c = c; this.game = game; @@ -187,7 +187,7 @@ public final class GameActionUtil { * TODO: Write javadoc for this type. * */ - private static final class RippleAbility extends Ability { + public static final class RippleAbility extends Ability { private final Player controller; private final int rippleCount; private final Card rippleCard; @@ -263,7 +263,7 @@ public final class GameActionUtil { * TODO: Write javadoc for this type. * */ - private static final class RippleExecutor implements Command { + public static final class RippleExecutor implements Command { private final Player controller; private final Card c; private static final long serialVersionUID = -845154812215847505L; @@ -273,7 +273,7 @@ public final class GameActionUtil { * @param controller * @param c */ - private RippleExecutor(Player controller, Card c) { + public RippleExecutor(Player controller, Card c) { this.controller = controller; this.c = c; } @@ -316,24 +316,6 @@ public final class GameActionUtil { throw new AssertionError(); } - /** - *

- * executePlayCardEffects. - *

- * - * @param sa - * a {@link forge.card.spellability.SpellAbility} object. - */ - public static void executePlayCardEffects(final SpellAbility sa) { - // (called from MagicStack.java) - - final Game game = sa.getActivatingPlayer().getGame(); - final Command cascade = new CascadeExecutor(sa.getActivatingPlayer(), sa.getSourceCard(), game); - cascade.run(); - final Command ripple = new RippleExecutor(sa.getActivatingPlayer(), sa.getSourceCard()); - ripple.run(); - } - // this is for cards like Sengir Vampire /** *

diff --git a/src/main/java/forge/game/event/GameEventSpellAbilityCast.java b/src/main/java/forge/game/event/GameEventSpellAbilityCast.java index 5bda7d08450..c2750be130e 100644 --- a/src/main/java/forge/game/event/GameEventSpellAbilityCast.java +++ b/src/main/java/forge/game/event/GameEventSpellAbilityCast.java @@ -9,9 +9,11 @@ import forge.card.spellability.SpellAbility; public class GameEventSpellAbilityCast extends GameEvent { public final SpellAbility sa; + public final boolean replicate; - public GameEventSpellAbilityCast(SpellAbility sp) { + public GameEventSpellAbilityCast(SpellAbility sp, boolean replicate) { sa = sp; + this.replicate = replicate; } /* (non-Javadoc) diff --git a/src/main/java/forge/game/event/GameEventSpellRemovedFromStack.java b/src/main/java/forge/game/event/GameEventSpellRemovedFromStack.java new file mode 100644 index 00000000000..15c8ff86131 --- /dev/null +++ b/src/main/java/forge/game/event/GameEventSpellRemovedFromStack.java @@ -0,0 +1,22 @@ +package forge.game.event; + +import forge.card.spellability.SpellAbility; + +/** + * TODO: Write javadoc for this type. + * + */ +public class GameEventSpellRemovedFromStack extends GameEvent { + public final SpellAbility sa; + + public GameEventSpellRemovedFromStack(SpellAbility spellAbility) { + sa = spellAbility; + } + + @Override + public T visit(IGameEventVisitor visitor) { + // TODO Auto-generated method stub + return visitor.visit(this); + } + +} diff --git a/src/main/java/forge/game/event/IGameEventVisitor.java b/src/main/java/forge/game/event/IGameEventVisitor.java index acb41edb71f..2bd0f9069a0 100644 --- a/src/main/java/forge/game/event/IGameEventVisitor.java +++ b/src/main/java/forge/game/event/IGameEventVisitor.java @@ -33,6 +33,7 @@ public interface IGameEventVisitor { T visit(GameEventShuffle event); T visit(GameEventSpellAbilityCast gameEventSpellAbilityCast); T visit(GameEventSpellResolved event); + T visit(GameEventSpellRemovedFromStack event); T visit(GameEventTokenCreated event); T visit(GameEventTurnBegan gameEventTurnBegan); T visit(GameEventTurnEnded event); @@ -68,6 +69,7 @@ public interface IGameEventVisitor { public T visit(GameEventShuffle event) { return null; } public T visit(GameEventSpellResolved event) { return null; } public T visit(GameEventSpellAbilityCast event) { return null; } + public T visit(GameEventSpellRemovedFromStack event) { return null; } public T visit(GameEventTokenCreated event) { return null; } public T visit(GameEventTurnBegan event) { return null; } public T visit(GameEventTurnEnded event) { return null; } diff --git a/src/main/java/forge/game/zone/MagicStack.java b/src/main/java/forge/game/zone/MagicStack.java index b69cf840298..09b6af97b9e 100644 --- a/src/main/java/forge/game/zone/MagicStack.java +++ b/src/main/java/forge/game/zone/MagicStack.java @@ -31,6 +31,7 @@ import com.esotericsoftware.minlog.Log; import forge.Card; import forge.CardLists; +import forge.Command; import forge.FThreads; import forge.Singletons; import forge.CardPredicates.Presets; @@ -51,11 +52,13 @@ import forge.card.spellability.Target; import forge.card.spellability.TargetChoices; import forge.card.trigger.Trigger; import forge.card.trigger.TriggerType; -import forge.game.GameActionUtil; import forge.game.Game; +import forge.game.GameActionUtil.CascadeExecutor; +import forge.game.GameActionUtil.RippleExecutor; import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCard; import forge.game.event.GameEventSpellAbilityCast; +import forge.game.event.GameEventSpellRemovedFromStack; import forge.game.event.GameEventSpellResolved; import forge.game.player.HumanPlay; import forge.game.player.Player; @@ -63,7 +66,6 @@ import forge.game.player.PlayerController.ManaPaymentPurpose; import forge.gui.GuiChoose; import forge.gui.input.InputSelectCards; import forge.gui.input.InputSelectCardsFromList; -import forge.util.MyObservable; /** *

@@ -73,7 +75,7 @@ import forge.util.MyObservable; * @author Forge * @version $Id$ */ -public class MagicStack extends MyObservable implements Iterable { +public class MagicStack /* extends MyObservable */ implements Iterable { private final List simultaneousStackEntryList = new ArrayList(); // They don't provide a LIFO queue, so had to use a deque @@ -133,7 +135,6 @@ public class MagicStack extends MyObservable implements Iterable
(C at beginning of class name denotes a control class.) * */ -public enum CStack implements ICDoc, Observer { +public enum CStack implements ICDoc { /** */ SINGLETON_INSTANCE; @@ -40,32 +36,15 @@ public enum CStack implements ICDoc, Observer { public void initialize() { } - private final Runnable upd = new Runnable() { @Override public void run() { - SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc()); - VStack.SINGLETON_INSTANCE.updateStack(model, viewer); - } }; - - /* (non-Javadoc) - * @see java.util.Observer#update(java.util.Observable, java.lang.Object) - */ - @Override - public void update(final Observable arg0, Object arg1) { - update(); - } - - /* (non-Javadoc) - * @see forge.gui.framework.ICDoc#update() - */ @Override public void update() { - FThreads.invokeInEdtNowOrLater(upd); + SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc()); + VStack.SINGLETON_INSTANCE.updateStack(model, viewer); } public void setModel(MagicStack model, LobbyPlayer guiPlayer) { this.model = model; this.viewer = guiPlayer; - - model.addObserver(this); } }