From e44b4b3cbcd131e7b8ed9aefaecc994a909440cc Mon Sep 17 00:00:00 2001 From: elcnesh Date: Sun, 28 Sep 2014 15:43:34 +0000 Subject: [PATCH] Multiple fixes. - Make determination of card viewing permissions much faster; - A general fix related to choosing a fixed amount of options from a list; - Improve display of card's names; - Reduce card flickering when changing phases. --- .gitattributes | 1 - .../src/main/java/forge/game/GameAction.java | 27 +++++--- .../main/java/forge/game/StaticEffects.java | 11 ++++ .../game/ability/effects/EndTurnEffect.java | 2 +- .../src/main/java/forge/game/card/Card.java | 39 +++++++---- .../java/forge/game/phase/PhaseHandler.java | 9 ++- .../game/staticability/StaticAbility.java | 4 -- .../StaticAbilityContinuous.java | 10 +++ .../staticability/StaticAbilityMayLookAt.java | 65 ------------------- .../src/main/java/forge/GuiDesktop.java | 8 +-- forge-gui-mobile/src/forge/GuiMobile.java | 5 +- .../res/cardsfolder/b/bane_alley_broker.txt | 2 +- .../res/cardsfolder/g/grimoire_thief.txt | 2 +- .../res/cardsfolder/g/gusthas_scepter.txt | 4 +- .../res/cardsfolder/j/jesters_scepter.txt | 10 +-- .../control/FControlGameEventHandler.java | 2 +- .../main/java/forge/interfaces/IGuiBase.java | 3 +- .../main/java/forge/util/gui/SGuiChoose.java | 2 +- .../main/java/forge/util/gui/SOptionPane.java | 2 +- .../src/main/java/forge/view/CardView.java | 23 +++++-- 20 files changed, 111 insertions(+), 120 deletions(-) delete mode 100644 forge-game/src/main/java/forge/game/staticability/StaticAbilityMayLookAt.java diff --git a/.gitattributes b/.gitattributes index bcf3aa0f207..e8cb2a24381 100644 --- a/.gitattributes +++ b/.gitattributes @@ -594,7 +594,6 @@ forge-game/src/main/java/forge/game/staticability/StaticAbilityCantBeCast.java s forge-game/src/main/java/forge/game/staticability/StaticAbilityCantTarget.java -text forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java svneol=native#text/plain forge-game/src/main/java/forge/game/staticability/StaticAbilityETBTapped.java -text -forge-game/src/main/java/forge/game/staticability/StaticAbilityMayLookAt.java -text forge-game/src/main/java/forge/game/staticability/StaticAbilityPreventDamage.java svneol=native#text/plain forge-game/src/main/java/forge/game/staticability/package-info.java svneol=native#text/plain forge-game/src/main/java/forge/game/trigger/Trigger.java svneol=native#text/plain diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index bbcc1503e7a..f75b87f8e7f 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -809,12 +809,17 @@ public class GameAction { *

* checkStateEffects. *

+ * + * @param runEvents + * {@code true} to have this method run + * {@link GameEventCardStatsChanged} events. + * @return a set of affected cards. */ - public final void checkStateEffects() { + public final Set checkStateEffects(final boolean runEvents) { // sol(10/29) added for Phase updates, state effects shouldn't be // checked during Spell Resolution (except when persist-returning if (game.getStack().isResolving()) { - return; + return Collections.emptySet(); } // final JFrame frame = Singletons.getView().getFrame(); @@ -823,7 +828,7 @@ public class GameAction { // } if (game.isGameOver()) { - return; + return Collections.emptySet(); } // Max: I don't know where to put this! - but since it's a state based action, it must be in check state effects @@ -835,8 +840,8 @@ public class GameAction { final boolean refreeze = game.getStack().isFrozen(); game.getStack().setFrozen(true); - // do this twice, sometimes creatures/permanents will survive when they - // shouldn't + // do this multiple times, sometimes creatures/permanents will survive + // when they shouldn't final Set allAffectedCards = Sets.newHashSet(); for (int q = 0; q < 9; q++) { final Set affectedCards = this.checkStaticAbilities(false); @@ -923,18 +928,22 @@ public class GameAction { if (!checkAgain) { break; // do not continue the loop } - } // for q=0;q<2 + } // for q=0;q<9 - game.fireEvent(new GameEventCardStatsChanged(allAffectedCards)); + if (runEvents) { + game.fireEvent(new GameEventCardStatsChanged(allAffectedCards)); + } checkGameOverCondition(); if (game.getAge() != GameStage.Play) - return; + return Collections.emptySet(); game.getTriggerHandler().resetActiveTriggers(); if (!refreeze) { game.getStack().unfreezeStack(); } + + return allAffectedCards; } // checkStateEffects() /** @@ -1561,7 +1570,7 @@ public class GameAction { } runOpeningHandActions(first); - checkStateEffects(); // why? + checkStateEffects(true); // why? // Run Trigger beginning of the game final HashMap runParams = new HashMap(); diff --git a/forge-game/src/main/java/forge/game/StaticEffects.java b/forge-game/src/main/java/forge/game/StaticEffects.java index 8ad8b16435c..55f9ca5ccaf 100644 --- a/forge-game/src/main/java/forge/game/StaticEffects.java +++ b/forge-game/src/main/java/forge/game/StaticEffects.java @@ -86,6 +86,7 @@ public class StaticEffects implements IGameStateObject { final List affectedCards = se.getAffectedCards(); final ArrayList affectedPlayers = se.getAffectedPlayers(); final Map params = se.getParams(); + final Player controller = se.getSource().getController(); String changeColorWordsTo = null; @@ -97,6 +98,7 @@ public class StaticEffects implements IGameStateObject { boolean setPT = false; String[] addHiddenKeywords = null; String addColors = null; + boolean removeMayLookAt = false; if (params.containsKey("ChangeColorWordsTo")) { changeColorWordsTo = params.get("ChangeColorWordsTo"); @@ -159,6 +161,10 @@ public class StaticEffects implements IGameStateObject { } } + if (params.containsKey("MayLookAt")) { + removeMayLookAt = true; + } + if (params.containsKey("IgnoreEffectCost")) { for (final SpellAbility s : se.getSource().getSpellAbilities()) { if (s instanceof AbilityStatic && s.isTemporary()) { @@ -249,6 +255,11 @@ public class StaticEffects implements IGameStateObject { affectedCard.removeColor(addColors, affectedCard, !se.isOverwriteColors(), se.getTimestamp(affectedCard)); } + + // remove may look at + if (removeMayLookAt) { + affectedCard.setMayLookAt(controller, false); + } } se.clearTimestamps(); return affectedCards; diff --git a/forge-game/src/main/java/forge/game/ability/effects/EndTurnEffect.java b/forge-game/src/main/java/forge/game/ability/effects/EndTurnEffect.java index 9c9c1d46337..ee4c7e5eb51 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/EndTurnEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/EndTurnEffect.java @@ -33,7 +33,7 @@ public class EndTurnEffect extends SpellAbilityEffect { // 3) State-based actions are checked. No player gets priority, and no // triggered abilities are put onto the stack. - game.getAction().checkStateEffects(); + game.getAction().checkStateEffects(true); // 4) The current phase and/or step ends. The game skips straight to the // cleanup step. The cleanup step happens in its entirety. diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 427d82a24f0..11b9a7b3af8 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -210,6 +210,7 @@ public class Card extends GameEntity implements Comparable, IIdentifiable private Player controller = null; private long controllerTimestamp = 0; private TreeMap tempControllers = new TreeMap(); + private final Set mayLookAt = Sets.newHashSet(); private String originalText = "", text = ""; private String echoCost = ""; @@ -3256,6 +3257,14 @@ public class Card extends GameEntity implements Comparable, IIdentifiable this.owner = player; } + public final void setMayLookAt(final Player player, final boolean mayLookAt) { + if (mayLookAt) { + this.mayLookAt.add(player); + } else { + this.mayLookAt.remove(player); + } + } + /** *

* Getter for the field equippedBy. @@ -4013,7 +4022,7 @@ public class Card extends GameEntity implements Comparable, IIdentifiable * left and right values of a {@link Pair}, respectively. A value of -1 * means that particular property has not been set. */ - private final Pair getLatestPT() { + private final synchronized Pair getLatestPT() { // Find latest set power long maxPowerTimestamp = -2; int latestPower = -1; @@ -6336,9 +6345,13 @@ public class Card extends GameEntity implements Comparable, IIdentifiable final SpellAbility root = sa.getRootAbility(); if (root != null && (root.getPaidList("MovedToGrave") != null) && !root.getPaidList("MovedToGrave").isEmpty()) { - List list = root.getPaidList("MovedToGrave"); - for (Card card : list) { - if (this.getName().equals(card.getName())) { + final List list = root.getPaidList("MovedToGrave"); + for (final Card card : list) { + String name = card.getName(); + if (StringUtils.isEmpty(name)) { + name = card.getPaperCard().getName(); + } + if (this.getName().equals(name)) { return true; } } @@ -8933,15 +8946,9 @@ public class Card extends GameEntity implements Comparable, IIdentifiable return true; } - //one last check to see if card can be shown - final Game game = this.getGame(); - for (Card host : game.getCardsIn(ZoneType.Battlefield)) { - final ArrayList staticAbilities = host.getStaticAbilities(); - for (final StaticAbility stAb : staticAbilities) { - if (stAb.applyAbility("MayLookAt", this, viewer)) { - return true; - } - } + // special viewing permissions for viewer + if (this.mayLookAt.contains(viewer)) { + return true; } //if viewer is controlled by another player, also check if card can be shown to that player @@ -8959,6 +8966,12 @@ public class Card extends GameEntity implements Comparable, IIdentifiable if (viewer.hasKeyword("CanSeeOpponentsFaceDownCards")) { return true; } + + // special viewing permissions for viewer + if (this.mayLookAt.contains(viewer)) { + return true; + } + //if viewer is controlled by another player, also check if face can be shown to that player if (viewer.isMindSlaved() && canCardFaceBeShownTo(viewer.getMindSlaveMaster())) { return true; diff --git a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java index 7f4503c4772..2f2273285cc 100644 --- a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java +++ b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java @@ -19,6 +19,7 @@ package forge.game.phase; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; +import com.google.common.collect.Sets; import forge.card.mana.ManaCost; import forge.game.*; @@ -384,7 +385,7 @@ public class PhaseHandler implements java.io.Serializable, IGameStateObject { givePriorityToPlayer = false; // Rule 514.3a - state-based actions - game.getAction().checkStateEffects(); + game.getAction().checkStateEffects(true); break; default: @@ -1001,17 +1002,19 @@ public class PhaseHandler implements java.io.Serializable, IGameStateObject { int loopCount = 0; do { - + final Set allAffectedCards = Sets.newHashSet(); boolean addedAnythingToStack = false; do { // Rule 704.3 Whenever a player would get priority, the game checks ... for state-based actions, - game.getAction().checkStateEffects(); + allAffectedCards.addAll(game.getAction().checkStateEffects(false)); if (game.isGameOver()) return; // state-based effects check could lead to game over addedAnythingToStack = game.getStack().addAllTriggeredAbilitiesToStack(); } while(addedAnythingToStack); + game.fireEvent(new GameEventCardStatsChanged(allAffectedCards)); + if (playerTurn.hasLost() && pPlayerPriority.equals(playerTurn) && pFirstPriority.equals(playerTurn)) { // If the active player has lost, and they have priority, set the next player to have priority System.out.println("Active player is no longer in the game..."); diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbility.java b/forge-game/src/main/java/forge/game/staticability/StaticAbility.java index 1647e6967e6..d3ab554f28f 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbility.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbility.java @@ -288,10 +288,6 @@ public class StaticAbility extends CardTraitBase { return StaticAbilityCantBeCast.applyCantPlayLandAbility(this, card, player); } - if (mode.equals("MayLookAt")) { - return StaticAbilityMayLookAt.applyMayLookAtAbility(this, card, player); - } - return false; } diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java index 8df21f2ec27..b1d7dfb555d 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java @@ -69,6 +69,7 @@ public class StaticAbilityContinuous { public static List applyContinuousAbility(final StaticAbility stAb, List affectedCards) { final Map params = stAb.getMapParams(); final Card hostCard = stAb.getHostCard(); + final Player controller = hostCard.getController(); final StaticEffect se = new StaticEffect(hostCard); final ArrayList affectedPlayers = StaticAbilityContinuous.getAffectedPlayers(stAb); @@ -109,6 +110,7 @@ public class StaticAbilityContinuous { boolean removeCardTypes = false; boolean removeSubTypes = false; boolean removeCreatureTypes = false; + boolean controllerMayLookAt = false; //Global rules changes if (params.containsKey("GlobalRule")) { @@ -326,6 +328,10 @@ public class StaticAbilityContinuous { } } + if (params.containsKey("MayLookAt")) { + controllerMayLookAt = true; + } + if (params.containsKey("IgnoreEffectCost")) { String cost = params.get("IgnoreEffectCost"); buildIgnorEffectAbility(stAb, cost, affectedPlayers, affectedCards); @@ -551,6 +557,10 @@ public class StaticAbilityContinuous { rE.setTemporarilySuppressed(true); } } + + if (controllerMayLookAt) { + affectedCard.setMayLookAt(controller, true); + } } return affectedCards; diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityMayLookAt.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityMayLookAt.java deleted file mode 100644 index 1c610bd29b3..00000000000 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityMayLookAt.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.game.staticability; - -import forge.game.card.Card; -import forge.game.player.Player; -import forge.game.zone.ZoneType; - -import java.util.Map; - -/** - * The Class StaticAbility_CantBeCast. - */ -public class StaticAbilityMayLookAt { - - /** - * TODO Write javadoc for this method. - * - * @param stAb - * a StaticAbility - * @param card - * the card - * @param activator - * the player - * @return true, if successful - */ - public static boolean applyMayLookAtAbility(final StaticAbility stAb, final Card card, final Player player) { - final Map params = stAb.getMapParams(); - final Card hostCard = stAb.getHostCard(); - - if (params.containsKey("Affected") - && !card.isValid(params.get("Affected").split(","), hostCard.getController(), hostCard)) { - return false; - } - - if (params.containsKey("Player") && player != null - && !player.isValid(params.get("Player"), hostCard.getController(), hostCard)) { - return false; - } - - if (params.containsKey("AffectedZone")) { - ZoneType zone = card.getGame().getZoneOf(card).getZoneType(); - if (!ZoneType.listValueOf(params.get("AffectedZone")).contains(zone)) { - return false; - } - } - - return true; - } -} diff --git a/forge-gui-desktop/src/main/java/forge/GuiDesktop.java b/forge-gui-desktop/src/main/java/forge/GuiDesktop.java index c93caa295fd..1fb102d4174 100644 --- a/forge-gui-desktop/src/main/java/forge/GuiDesktop.java +++ b/forge-gui-desktop/src/main/java/forge/GuiDesktop.java @@ -10,11 +10,13 @@ import java.lang.reflect.InvocationTargetException; import java.net.URI; import java.util.Collection; import java.util.List; + import javax.swing.ImageIcon; import javax.swing.JFileChooser; import javax.swing.SwingUtilities; import org.apache.commons.lang3.StringUtils; + import com.google.common.base.Function; import forge.assets.FSkinProp; @@ -145,11 +147,7 @@ public class GuiDesktop implements IGuiBase { } @Override - public T showInputDialog(String message, String title, FSkinProp icon, T initialInput, T[] inputOptions) { - if (initialInput instanceof GameObject || (inputOptions != null && inputOptions.length > 0 && inputOptions[0] instanceof GameObject)) { - System.err.println("Warning: GameObject passed to GUI! Printing stack trace."); - Thread.dumpStack(); - } + public String showInputDialog(String message, String title, FSkinProp icon, String initialInput, String[] inputOptions) { return FOptionPane.showInputDialog(message, title, icon == null ? null : FSkin.getImage(icon), initialInput, inputOptions); } diff --git a/forge-gui-mobile/src/forge/GuiMobile.java b/forge-gui-mobile/src/forge/GuiMobile.java index e8a2d4f9fb3..2107dcfae39 100644 --- a/forge-gui-mobile/src/forge/GuiMobile.java +++ b/forge-gui-mobile/src/forge/GuiMobile.java @@ -3,6 +3,7 @@ package forge; import java.io.File; import java.util.Collection; import java.util.List; + import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Application.ApplicationType; import com.badlogic.gdx.graphics.Texture; @@ -153,8 +154,8 @@ public class GuiMobile implements IGuiBase { } @Override - public T showInputDialog(final String message, final String title, final FSkinProp icon, final T initialInput, final T[] inputOptions) { - return new WaitCallback() { + public String showInputDialog(final String message, final String title, final FSkinProp icon, final String initialInput, final String[] inputOptions) { + return new WaitCallback() { @Override public void run() { FOptionPane.showInputDialog(message, title, icon == null ? null : FSkin.getImages().get(icon), initialInput, inputOptions, this); diff --git a/forge-gui/res/cardsfolder/b/bane_alley_broker.txt b/forge-gui/res/cardsfolder/b/bane_alley_broker.txt index 00f57aa8d93..baea848bd9c 100644 --- a/forge-gui/res/cardsfolder/b/bane_alley_broker.txt +++ b/forge-gui/res/cardsfolder/b/bane_alley_broker.txt @@ -4,7 +4,7 @@ Types:Creature Human Rogue PT:0/3 A:AB$ Draw | Cost$ T | NumCards$ 1 | SubAbility$ DBExile | SpellDescription$ Draw a card, then exile a card from your hand face down. SVar:DBExile:DB$ ChangeZone | Origin$ Hand | Destination$ Exile | ChangeType$ Card | ChangeNum$ 1 | ExileFaceDown$ True | Mandatory$ True | RememberChanged$ True -S:Mode$ MayLookAt | Affected$ Card.IsRemembered | Player$ You | AffectedZone$ Exile | Description$ You may look at cards exiled with CARDNAME. +S:Mode$ Continuous | Affected$ Card.IsRemembered | AffectedZone$ Exile | MayLookAt$ True | Description$ You may look at cards exiled with CARDNAME. A:AB$ ChooseCard | Cost$ U B T | Defined$ You | Amount$ 1 | Mandatory$ True | AILogic$ AtLeast1 | ChoiceTitle$ Choose a card to put into your hand | Choices$ Card.IsRemembered | ChoiceZone$ Exile | SubAbility$ MoveChosen | SpellDescription$ Return a card exiled with CARDNAME to its owner's hand. SVar:MoveChosen:DB$ ChangeZone | Origin$ Exile | Destination$ Hand | Defined$ ChosenCard T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget diff --git a/forge-gui/res/cardsfolder/g/grimoire_thief.txt b/forge-gui/res/cardsfolder/g/grimoire_thief.txt index db0f149e5b7..55cb321d64d 100644 --- a/forge-gui/res/cardsfolder/g/grimoire_thief.txt +++ b/forge-gui/res/cardsfolder/g/grimoire_thief.txt @@ -4,7 +4,7 @@ Types:Creature Merfolk Rogue PT:2/2 T:Mode$ Taps | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ Whenever CARDNAME becomes tapped, exile the top three cards of target opponent's library face down. SVar:TrigExile:AB$ Mill | Cost$ 0 | ValidTgts$ Opponent | NumCards$ 3 | Destination$ Exile | ExileFaceDown$ True | RememberMilled$ True -S:Mode$ MayLookAt | Affected$ Card.IsRemembered | Player$ You | AffectedZone$ Exile | Description$ You may look at cards exiled with CARDNAME. +S:Mode$ Continuous | Affected$ Card.IsRemembered | AffectedZone$ Exile | MayLookAt$ True | Description$ You may look at cards exiled with CARDNAME. A:AB$ SetState | Cost$ U Sac<1/CARDNAME> | Defined$ Remembered | Mode$ TurnFace | SubAbility$ DBCounter | SpellDescription$ Turn all cards exiled with CARDNAME face up. Counter all spells with those names. SVar:DBCounter:DB$ Counter | AllType$ Spell | AllValid$ Card.sharesNameWith Remembered | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True diff --git a/forge-gui/res/cardsfolder/g/gusthas_scepter.txt b/forge-gui/res/cardsfolder/g/gusthas_scepter.txt index cb3cbefecff..61c79807a4d 100644 --- a/forge-gui/res/cardsfolder/g/gusthas_scepter.txt +++ b/forge-gui/res/cardsfolder/g/gusthas_scepter.txt @@ -1,8 +1,8 @@ Name:Gustha's Scepter ManaCost:0 Types:Artifact -A:AB$ ChangeZone | Cost$ T | ChangeType$ Card | ChangeNum$ 1 | Origin$ Hand | Destination$ Exile | ExileFaceDown$ True | RememberChanged$ True | Mandatory$ True | SpellDescription$ Exile a card from your hand face down. You may look at it for as long as it remains exiled. -S:Mode$ MayLookAt | Affected$ Card.IsRemembered | Player$ You | AffectedZone$ Exile +A:AB$ ChangeZone | Cost$ T | ChangeType$ Card | ChangeNum$ 1 | Origin$ Hand | Destination$ Exile | ExileFaceDown$ True | RememberChanged$ True | Mandatory$ True | SubAbility$ DBMayLookAt | SpellDescription$ Exile a card from your hand face down. You may look at it for as long as it remains exiled. +SVar:DBMayLookAt:DB$ Pump | Defined$ Remembered | PumpZone$ Exile | KW$ You may look at this card. | Permanent$ True A:AB$ ChooseCard | Cost$ T | Defined$ You | Amount$ 1 | Mandatory$ True | AILogic$ AtLeast1 | ChoiceTitle$ Choose a card you own to put into your hand | Choices$ Card.IsRemembered+YouOwn | ChoiceZone$ Exile | SubAbility$ MoveChosen | SpellDescription$ Return a card you own exiled with CARDNAME to your hand. SVar:MoveChosen:DB$ ChangeZone | Origin$ Exile | Destination$ Hand | Defined$ ChosenCard T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget diff --git a/forge-gui/res/cardsfolder/j/jesters_scepter.txt b/forge-gui/res/cardsfolder/j/jesters_scepter.txt index e6456753fdb..fbf6e0cf5a1 100644 --- a/forge-gui/res/cardsfolder/j/jesters_scepter.txt +++ b/forge-gui/res/cardsfolder/j/jesters_scepter.txt @@ -1,9 +1,11 @@ Name:Jester's Scepter ManaCost:3 Types:Artifact -T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME enters the battlefield, exile the top five cards of target player's library face down. -SVar:TrigExile:AB$ Mill | Cost$ 0 | ValidTgts$ Player | NumCards$ 5 | Destination$ Exile | ExileFaceDown$ True | RememberMilled$ True -S:Mode$ MayLookAt | Affected$ Card.IsRemembered | Player$ You | AffectedZone$ Exile | Description$ You may look at cards exiled with CARDNAME. +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME enters the battlefield, exile the top five cards of target player's library face down. You may look at those cards for as long as they remain exiled. +SVar:TrigExile:AB$ Mill | Cost$ 0 | ValidTgts$ Player | NumCards$ 5 | Destination$ Exile | ExileFaceDown$ True | RememberMilled$ True | SubAbility$ DBMayLookAt +SVar:DBMayLookAt:DB$ Effect | Name$ Jester's Scepter Effect | StaticAbilities$ SMayLookAt | Triggers$ TForget | SVars$ DBForget | RememberObjects$ Remembered | Duration$ Permanent +SVar:SMayLookAt:Mode$ Continuous | Affected$ Card.IsRemembered | AffectedZone$ Exile | EffectZone$ Command | MayLookAt$ True | Duration$ Permanent +SVar:TForget:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ DBCleanup | Static$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget @@ -12,4 +14,4 @@ A:AB$ Counter | Cost$ 2 T ExiledMoveToGrave<1/Card.IsRemembered/card exiled with SVar:X:Targeted$Valid Card.sharesNameWith MovedToGrave SVar:RemAIDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/jesters_scepter.jpg -Oracle:When Jester's Scepter enters the battlefield, exile the top five cards of target player's library face down. You may look at those cards for as long as they remain exiled.\n{2}, {T}, Put a card exiled with Jester's Scepter into its owner's graveyard: Counter target spell if it has the same name as that card. +Oracle:When Jester's Scepter enters the battlefield, exile the top five cards of target player's library face down. You may look at those cards for as long as they remain exiled.\n{2}, {T}, Put a card exiled with Jester's Scepter into its owner's graveyard: Counter target spell if it has the same name as that card. \ No newline at end of file diff --git a/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java b/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java index 11f99a7fa46..22122a393d5 100644 --- a/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java +++ b/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java @@ -102,7 +102,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base { return null; } - public void updateCombat() { + private void updateCombat() { if (!isMainHandler || combatUpdPlanned.getAndSet(true)) { return; } FThreads.invokeInEdtNowOrLater(gameView.getGui(), new Runnable() { diff --git a/forge-gui/src/main/java/forge/interfaces/IGuiBase.java b/forge-gui/src/main/java/forge/interfaces/IGuiBase.java index 301a06e573b..a05a9e8e53a 100644 --- a/forge-gui/src/main/java/forge/interfaces/IGuiBase.java +++ b/forge-gui/src/main/java/forge/interfaces/IGuiBase.java @@ -3,6 +3,7 @@ package forge.interfaces; import java.io.File; import java.util.Collection; import java.util.List; + import com.google.common.base.Function; import forge.LobbyPlayer; @@ -29,7 +30,7 @@ public interface IGuiBase { void showImageDialog(ISkinImage image, String message, String title); int showOptionDialog(String message, String title, FSkinProp icon, String[] options, int defaultOption); int showCardOptionDialog(CardView card, String message, String title, FSkinProp icon, String[] options, int defaultOption); - T showInputDialog(String message, String title, FSkinProp icon, T initialInput, T[] inputOptions); + String showInputDialog(String message, String title, FSkinProp icon, String initialInput, String[] inputOptions); List getChoices(final String message, final int min, final int max, final Collection choices, final T selected, final Function display); List order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax, final List sourceChoices, final List destChoices, final CardView referenceCard, final boolean sideboardingMode); diff --git a/forge-gui/src/main/java/forge/util/gui/SGuiChoose.java b/forge-gui/src/main/java/forge/util/gui/SGuiChoose.java index 462ae03238e..e086f4b6d46 100644 --- a/forge-gui/src/main/java/forge/util/gui/SGuiChoose.java +++ b/forge-gui/src/main/java/forge/util/gui/SGuiChoose.java @@ -192,7 +192,7 @@ public class SGuiChoose { } public static List many(final IGuiBase gui, final String title, final String topCaption, int cnt, final List sourceChoices, final CardView referenceCard) { - return order(gui, title, topCaption, cnt, cnt, sourceChoices, null, referenceCard, false); + return many(gui, title, topCaption, cnt, cnt, sourceChoices, referenceCard); } public static List many(final IGuiBase gui, final String title, final String topCaption, int min, int max, final List sourceChoices, final CardView referenceCard) { diff --git a/forge-gui/src/main/java/forge/util/gui/SOptionPane.java b/forge-gui/src/main/java/forge/util/gui/SOptionPane.java index 442c984f289..c690c947f84 100644 --- a/forge-gui/src/main/java/forge/util/gui/SOptionPane.java +++ b/forge-gui/src/main/java/forge/util/gui/SOptionPane.java @@ -76,7 +76,7 @@ public class SOptionPane { return showInputDialog(gui, message, title, icon, initialInput, null); } - public static T showInputDialog(IGuiBase gui, String message, String title, FSkinProp icon, T initialInput, T[] inputOptions) { + public static String showInputDialog(IGuiBase gui, String message, String title, FSkinProp icon, String initialInput, String[] inputOptions) { return gui.showInputDialog(message, title, icon, initialInput, inputOptions); } diff --git a/forge-gui/src/main/java/forge/view/CardView.java b/forge-gui/src/main/java/forge/view/CardView.java index eeae117d4da..7e68202fcf0 100644 --- a/forge-gui/src/main/java/forge/view/CardView.java +++ b/forge-gui/src/main/java/forge/view/CardView.java @@ -726,7 +726,23 @@ public class CardView extends GameEntityView { @Override public String toString() { - return this.getOriginal().toString(); + if (StringUtils.isEmpty(this.getOriginal().getName())) { + if (this.getId() <= 0) { + return "(Unknown card)"; + } else if (this.hasAltState()) { + return "Face-down card (" + this.getAlternate().getName() + ")"; + } + } + + return this.getOriginal().getName() + " (" + this.getId() + ")"; + } + + public String determineName(final CardStateView state) { + if (state == original) { + return this.toString(); + } + + return this.getAlternate().getName() + " (" + this.getId() + ")"; } public class CardStateView { @@ -767,10 +783,7 @@ public class CardView extends GameEntityView { @Override public String toString() { - if (StringUtils.isEmpty(this.getName()) && this.getCard().getId() <= 0) { - return "(Unknown card)"; - } - return this.getName() + " (" + this.getCard().getId() + ")"; + return this.getCard().determineName(this); } public CardView getCard() {