diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDev.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDev.java index 1357ca4e74c..1f7c25086c7 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDev.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDev.java @@ -40,6 +40,7 @@ public final class CDev implements ICDoc { view.getLblCardToLibrary().addMouseListener(madCardToLibrary); view.getLblCardToGraveyard().addMouseListener(madCardToGraveyard); view.getLblCardToExile().addMouseListener(madCardToExile); + view.getLblCastSpell().addMouseListener(madCastASpell); view.getLblRepeatAddCard().addMouseListener(madRepeatAddCard); view.getLblCounterPermanent().addMouseListener(madCounter); view.getLblTapPermanent().addMouseListener(madTap); @@ -167,6 +168,16 @@ public final class CDev implements ICDoc { getController().cheat().addCardToExile(); } + private final MouseListener madCastASpell = new MouseAdapter() { + @Override + public void mousePressed(final MouseEvent e) { + castASpell(); + } + }; + public void castASpell() { + getController().cheat().castASpell(); + } + private final MouseListener madRepeatAddCard = new MouseAdapter() { @Override public void mousePressed(final MouseEvent e) { diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/views/VDev.java b/forge-gui-desktop/src/main/java/forge/screens/match/views/VDev.java index ed2f8ea06ef..108416db019 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/views/VDev.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/views/VDev.java @@ -65,13 +65,14 @@ public class VDev implements IVDoc, IDevListener { private final DevLabel lblUntapPermanent = new DevLabel("Untap Permanents"); private final DevLabel lblSetLife = new DevLabel("Set Player Life"); private final DevLabel lblWinGame = new DevLabel("Win Game"); - private final DevLabel lblCardToBattlefield = new DevLabel("Add Card to Play"); + private final DevLabel lblCardToBattlefield = new DevLabel("Add Card to Battlefield"); private final DevLabel lblExileFromPlay = new DevLabel("Exile Card from Play"); private final DevLabel lblCardToHand = new DevLabel("Add Card to Hand"); private final DevLabel lblExileFromHand = new DevLabel("Exile Card from Hand"); private final DevLabel lblCardToLibrary = new DevLabel("Add Card to Library"); private final DevLabel lblCardToGraveyard = new DevLabel("Add Card to Graveyard"); private final DevLabel lblCardToExile = new DevLabel("Add Card to Exile"); + private final DevLabel lblCastSpell = new DevLabel("Cast Spell/Play Land"); private final DevLabel lblRepeatAddCard = new DevLabel("Repeat Last Add Card"); private final DevLabel lblRemoveFromGame = new DevLabel("Remove Card from Game"); @@ -98,13 +99,14 @@ public class VDev implements IVDoc, IDevListener { viewport.add(this.lblCardToLibrary, halfConstraintsLeft); viewport.add(this.lblCardToGraveyard, halfConstraints); viewport.add(this.lblCardToExile, halfConstraintsLeft); - viewport.add(this.lblRepeatAddCard, halfConstraints); + viewport.add(this.lblCastSpell, halfConstraints); + viewport.add(this.lblRepeatAddCard, halfConstraintsLeft); + viewport.add(this.lblRemoveFromGame, halfConstraints); viewport.add(this.lblExileFromHand, halfConstraintsLeft); viewport.add(this.lblExileFromPlay, halfConstraints); - viewport.add(this.lblRemoveFromGame, halfConstraintsLeft); - viewport.add(this.lblSetLife, halfConstraints); + viewport.add(this.lblSetLife, halfConstraintsLeft); + viewport.add(this.lblWinGame, halfConstraints); viewport.add(this.lblCounterPermanent, constraints); - viewport.add(this.lblWinGame, constraints); viewport.add(this.lblSetupGame, halfConstraintsLeft); viewport.add(this.lblDumpGame, halfConstraints); viewport.add(this.lblTapPermanent, halfConstraintsLeft); @@ -227,11 +229,15 @@ public class VDev implements IVDoc, IDevListener { return lblRepeatAddCard; } + /** @return {@link forge.screens.match.views.VDev.DevLabel} */ + public DevLabel getLblCastSpell() { + return this.lblCastSpell; + } + /** @return {@link forge.screens.match.views.VDev.DevLabel} */ public DevLabel getLblExileFromPlay() { return this.lblExileFromPlay; } - /** @return {@link forge.screens.match.views.VDev.DevLabel} */ public DevLabel getLblRemoveFromGame() { return this.lblRemoveFromGame; diff --git a/forge-gui-mobile/src/forge/screens/match/views/VDevMenu.java b/forge-gui-mobile/src/forge/screens/match/views/VDevMenu.java index 3f1e61d28d0..051dd166659 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VDevMenu.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VDevMenu.java @@ -44,7 +44,7 @@ public class VDevMenu extends FDropDownMenu { }); } })); - addItem(new FMenuItem("Add Card to Play", new FEventHandler() { + addItem(new FMenuItem("Add Card to Battlefield", new FEventHandler() { @Override public void handleEvent(FEvent e) { ThreadUtil.invokeInGameThread(new Runnable() { @@ -88,6 +88,17 @@ public class VDevMenu extends FDropDownMenu { }); } })); + addItem(new FMenuItem("Cast Spell/Play Land", new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + ThreadUtil.invokeInGameThread(new Runnable() { + @Override + public void run() { + MatchController.instance.getGameController().cheat().castASpell(); + } + }); + } + })); addItem(new FMenuItem("Repeat Last Add Card", new FEventHandler() { @Override public void handleEvent(FEvent e) { diff --git a/forge-gui/release-files/CHANGES.txt b/forge-gui/release-files/CHANGES.txt index 9c4c9e8c888..f826201932a 100644 --- a/forge-gui/release-files/CHANGES.txt +++ b/forge-gui/release-files/CHANGES.txt @@ -17,7 +17,7 @@ Texture filtering is now enabled by default for new Mobile Forge installations o This release features a new quest world designed by Seravy, called "The Gates of Magic". It is a quest world built from all starter level sets : Starter, Portal, Portal 2 and Portal 3 Kingdoms. Includes 30 duels and 15 challenges, all fully tested. - Developer Mode improvements - -The Developer Mode panel has been reorganized, many buttons were grouped by function. Several new functions have been added to make debugging and setting up game states easier: Add Card To Library/Graveyard/Exile, Repeat Last Add Card (which repeats whichever add card operation you have performed last automatically), Remove Card from the Game (which completely removes the card, leaving no trace, which may be useful if a card was added to the game by mistake). +The Developer Mode panel has been reorganized, many buttons were grouped by function. Several new functions have been added to make debugging and setting up game states easier: Add Card To Library/Graveyard/Exile, Repeat Last Add Card (which repeats whichever add card operation you have performed last automatically), Remove Card from the Game (which completely removes the card, leaving no trace, which may be useful if a card was added to the game by mistake). Also, the former button "Add Card to Play" was reorganized into two functions: one of them is "Add Card to Battlefield", which functions like the other Add Card to X buttons and adds the card straight to the battlefield, without placing the spell on stack first and without resolving it and firing any ETB triggers; the other is "Cast Spell/Play Land", which places the chosen spell on stack if appropriate, which then resolves and causes triggers to fire (if a land is chosen, it is played, and the ETB triggers on the land fire as well, if appropriate). - Bug fixes - As always, this release of Forge features an assortment of bug fixes and improvements based on user feedback during the previous release run. diff --git a/forge-gui/src/main/java/forge/interfaces/IDevModeCheats.java b/forge-gui/src/main/java/forge/interfaces/IDevModeCheats.java index 6f18c94628a..857e908654f 100644 --- a/forge-gui/src/main/java/forge/interfaces/IDevModeCheats.java +++ b/forge-gui/src/main/java/forge/interfaces/IDevModeCheats.java @@ -34,6 +34,8 @@ public interface IDevModeCheats { void addCardToExile(); + void castASpell(); + void repeatLastAddition(); /* @@ -119,6 +121,9 @@ public interface IDevModeCheats { public void addCardToExile() { } @Override + public void castASpell() { + } + @Override public void repeatLastAddition() { } @Override diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 01189ce978e..9434c9278d7 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -1780,6 +1780,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont private ZoneType lastAddedZone; private Player lastAddedPlayer; private SpellAbility lastAddedSA; + private boolean lastTrigs; private DevModeCheats() { } @@ -2072,7 +2073,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont */ @Override public void addCardToHand() { - addCardToZone(ZoneType.Hand, false); + addCardToZone(ZoneType.Hand, false, false); } /* @@ -2082,7 +2083,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont */ @Override public void addCardToBattlefield() { - addCardToZone(ZoneType.Battlefield, false); + addCardToZone(ZoneType.Battlefield, false, true); } /* @@ -2092,7 +2093,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont */ @Override public void addCardToLibrary() { - addCardToZone(ZoneType.Library, false); + addCardToZone(ZoneType.Library, false, false); } /* @@ -2102,7 +2103,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont */ @Override public void addCardToGraveyard() { - addCardToZone(ZoneType.Graveyard, false); + addCardToZone(ZoneType.Graveyard, false, false); } /* @@ -2112,7 +2113,17 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont */ @Override public void addCardToExile() { - addCardToZone(ZoneType.Exile, false); + addCardToZone(ZoneType.Exile, false, false); + } + + /* + * (non-Javadoc) + * + * @see forge.player.IDevModeCheats#addCardToExile() + */ + @Override + public void castASpell() { + addCardToZone(ZoneType.Battlefield, false, false); } /* @@ -2122,12 +2133,13 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont */ @Override public void repeatLastAddition() { - addCardToZone(null, true); + addCardToZone(null, true, lastTrigs); } - private void addCardToZone(ZoneType zone, final boolean repeatLast) { + private void addCardToZone(ZoneType zone, final boolean repeatLast, final boolean noTriggers) { final ZoneType targetZone = repeatLast ? lastAddedZone : zone; - String zoneStr = targetZone != ZoneType.Battlefield ? "in " + targetZone.name().toLowerCase() : "on the battlefield"; + String zoneStr = targetZone != ZoneType.Battlefield ? "in " + targetZone.name().toLowerCase() + : noTriggers ? "on the battlefield" : "on the stack / in play"; final Player p = repeatLast ? lastAddedPlayer : game.getPlayer(getGui().oneOrNone("Put card " + zoneStr + " for which player?", @@ -2152,8 +2164,13 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont game.getAction().invoke(new Runnable() { @Override public void run() { - if (targetZone != ZoneType.Battlefield) { - game.getAction().moveTo(targetZone, forgeCard, null); + if (targetZone != ZoneType.Battlefield || noTriggers) { + if (forgeCard.isPermanent()) { + game.getAction().moveTo(targetZone, forgeCard, null); + } else { + getGui().message("The chosen card is not a permanent.\nIf you'd like to cast a non-permanent spell, or if you'd like to cast a permanent spell (and place it on stack), please use the Cast Spell/Play Land button.", "Error"); + return; + } } else { if (c.getRules().getType().isLand()) { // this is needed to ensure land abilities fire @@ -2193,6 +2210,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont lastAdded = f; lastAddedZone = targetZone; lastAddedPlayer = p; + lastTrigs = noTriggers; } }); }