diff --git a/forge-game/src/main/java/forge/game/Game.java b/forge-game/src/main/java/forge/game/Game.java index 14ad8377db4..690e50e26d6 100644 --- a/forge-game/src/main/java/forge/game/Game.java +++ b/forge-game/src/main/java/forge/game/Game.java @@ -522,7 +522,7 @@ public class Game { * The Direction in which the turn order of this Game currently proceeds. */ public final Direction getTurnOrder() { - if (phaseHandler.getPlayerTurn() != null && phaseHandler.getPlayerTurn().getAmountOfKeyword("The turn order is reversed.") % 2 == 1) { + if (phaseHandler.getPlayerTurn() != null && phaseHandler.getPlayerTurn().isTurnOrderReversed()) { return turnOrder.getOtherDirection(); } return turnOrder; diff --git a/forge-game/src/main/java/forge/game/ability/effects/AddPhaseEffect.java b/forge-game/src/main/java/forge/game/ability/effects/AddPhaseEffect.java index 90b758d5cb4..435fdac18d6 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AddPhaseEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AddPhaseEffect.java @@ -25,7 +25,7 @@ public class AddPhaseEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { final Card host = sa.getHostCard(); final Player activator = sa.getActivatingPlayer(); - boolean isTopsy = activator.getAmountOfKeyword("The phases of your turn are reversed.") % 2 == 1; + boolean isTopsy = activator.isPhasesReversed(); PhaseHandler phaseHandler = activator.getGame().getPhaseHandler(); PhaseType currentPhase = phaseHandler.getPhase(); diff --git a/forge-game/src/main/java/forge/game/ability/effects/FlipCoinEffect.java b/forge-game/src/main/java/forge/game/ability/effects/FlipCoinEffect.java index ec583979abf..33c24565b5a 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/FlipCoinEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/FlipCoinEffect.java @@ -303,6 +303,6 @@ public class FlipCoinEffect extends SpellAbilityEffect { public static int getFlipMultiplier(final Player flipper) { String str = "If you would flip a coin, instead flip two coins and ignore one."; - return 1 << flipper.getKeywords().getAmount(str); + return 1 << flipper.getAmountOfKeyword(str); } } 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 109d3f08d0b..206d0c1690b 100644 --- a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java +++ b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java @@ -142,7 +142,7 @@ public class PhaseHandler implements java.io.Serializable { private void advanceToNextPhase() { PhaseType oldPhase = phase; - boolean isTopsy = playerTurn.getAmountOfKeyword("The phases of your turn are reversed.") % 2 == 1; + boolean isTopsy = playerTurn.isPhasesReversed(); boolean turnEnded = false; game.getStack().clearUndoStack(); //can't undo action from previous phase @@ -1165,7 +1165,7 @@ public class PhaseHandler implements java.io.Serializable { return devAdvanceToPhase(targetPhase, null); } public final boolean devAdvanceToPhase(PhaseType targetPhase, Runnable resolver) { - boolean isTopsy = playerTurn.getAmountOfKeyword("The phases of your turn are reversed.") % 2 == 1; + boolean isTopsy = playerTurn.isPhasesReversed(); while (phase.isBefore(targetPhase, isTopsy)) { if (checkStateBasedEffects()) { return false; diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index f87eeddf695..18dc336d243 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -2232,7 +2232,7 @@ public class Player extends GameEntity implements Comparable { numManaConversion = l; } public final boolean hasManaConversion() { - return numManaConversion < keywords.getAmount("You may spend mana as though" + return numManaConversion < getAmountOfKeyword("You may spend mana as though" + " it were mana of any type to cast a spell this turn."); } public final void incNumManaConversion() { @@ -2547,6 +2547,13 @@ public class Player extends GameEntity implements Comparable { return keywords.getAmount(k); } + public boolean isTurnOrderReversed() { + return StaticAbilityTurnPhaseReversed.isTurnReversed(this); + } + public boolean isPhasesReversed() { + return StaticAbilityTurnPhaseReversed.isPhaseReversed(this); + } + public void onCleanupPhase() { for (Card c : getCardsIn(ZoneType.Hand)) { c.setDrawnThisTurn(false); diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityTurnPhaseReversed.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityTurnPhaseReversed.java new file mode 100644 index 00000000000..02f1fd252ab --- /dev/null +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityTurnPhaseReversed.java @@ -0,0 +1,43 @@ +package forge.game.staticability; + +import forge.game.Game; +import forge.game.card.Card; +import forge.game.player.Player; +import forge.game.zone.ZoneType; + +public class StaticAbilityTurnPhaseReversed { + static String TURN_MODE = "TurnReversed"; + static String PHASE_MODE = "PhaseReversed"; + + public static boolean isTurnReversed(Player player) { + return anyTurnPhaseReversed(player, TURN_MODE); + } + public static boolean isPhaseReversed(Player player) { + return anyTurnPhaseReversed(player, PHASE_MODE); + } + + protected static boolean anyTurnPhaseReversed(Player player, final String mode) + { + boolean result = false; + final Game game = player.getGame(); + for (final Card ca : game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) { + for (final StaticAbility stAb : ca.getStaticAbilities()) { + if (!stAb.checkConditions(mode)) { + continue; + } + if (applyTurnPhaseReversed(stAb, player)) { + result = !result; + } + } + } + return result; + } + + protected static boolean applyTurnPhaseReversed(StaticAbility stAb, Player player) { + if (!stAb.matchesValidParam("ValidPlayer", player)) { + return false; + } + + return true; + } +} diff --git a/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulationTest.java b/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulationTest.java index 9757f7df9ab..9b7a0ff01c7 100644 --- a/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulationTest.java +++ b/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulationTest.java @@ -75,7 +75,7 @@ public class GameSimulationTest extends SimulationTest { game.getAction().checkStateEffects(true); game.getAction().checkStateEffects(true); - AssertJUnit.assertEquals(1, sliver.getAmountOfKeyword("Flanking")); + AssertJUnit.assertEquals(1, sliver.getAmountOfKeyword(Keyword.FLANKING)); AssertJUnit.assertEquals(2, sliver.getNetPower()); AssertJUnit.assertEquals(2, sliver.getNetToughness()); @@ -87,7 +87,7 @@ public class GameSimulationTest extends SimulationTest { AssertJUnit.assertTrue(score > 0); Game simGame = sim.getSimulatedGameState(); Card sliverCopy = findCardWithName(simGame, sliverCardName); - AssertJUnit.assertEquals(1, sliverCopy.getAmountOfKeyword("Flanking")); + AssertJUnit.assertEquals(1, sliverCopy.getAmountOfKeyword(Keyword.FLANKING)); AssertJUnit.assertEquals(2, sliver.getNetPower()); AssertJUnit.assertEquals(2, sliver.getNetToughness()); } @@ -103,15 +103,15 @@ public class GameSimulationTest extends SimulationTest { game.getPhaseHandler().devModeSet(PhaseType.MAIN1, p); game.getAction().checkStateEffects(true); AssertJUnit.assertTrue(lion.isMonstrous()); - AssertJUnit.assertEquals(1, lion.getAmountOfKeyword("Hexproof")); - AssertJUnit.assertEquals(1, lion.getAmountOfKeyword("Indestructible")); + AssertJUnit.assertEquals(1, lion.getAmountOfKeyword(Keyword.HEXPROOF)); + AssertJUnit.assertEquals(1, lion.getAmountOfKeyword(Keyword.INDESTRUCTIBLE)); GameSimulator sim = createSimulator(game, p); Game simGame = sim.getSimulatedGameState(); Card lionCopy = findCardWithName(simGame, lionCardName); AssertJUnit.assertTrue(lionCopy.isMonstrous()); - AssertJUnit.assertEquals(1, lionCopy.getAmountOfKeyword("Hexproof")); - AssertJUnit.assertEquals(1, lionCopy.getAmountOfKeyword("Indestructible")); + AssertJUnit.assertEquals(1, lionCopy.getAmountOfKeyword(Keyword.HEXPROOF)); + AssertJUnit.assertEquals(1, lionCopy.getAmountOfKeyword(Keyword.INDESTRUCTIBLE)); } @Test @@ -125,12 +125,12 @@ public class GameSimulationTest extends SimulationTest { cloak.attachToEntity(bear, null); game.getPhaseHandler().devModeSet(PhaseType.MAIN1, p); game.getAction().checkStateEffects(true); - AssertJUnit.assertEquals(1, bear.getAmountOfKeyword("Shroud")); + AssertJUnit.assertEquals(1, bear.getAmountOfKeyword(Keyword.SHROUD)); GameSimulator sim = createSimulator(game, p); Game simGame = sim.getSimulatedGameState(); Card bearCopy = findCardWithName(simGame, bearCardName); - AssertJUnit.assertEquals(1, bearCopy.getAmountOfKeyword("Shroud")); + AssertJUnit.assertEquals(1, bearCopy.getAmountOfKeyword(Keyword.SHROUD)); } @Test @@ -144,12 +144,12 @@ public class GameSimulationTest extends SimulationTest { lifelink.attachToEntity(bear, null); game.getPhaseHandler().devModeSet(PhaseType.MAIN1, p); game.getAction().checkStateEffects(true); - AssertJUnit.assertEquals(1, bear.getAmountOfKeyword("Lifelink")); + AssertJUnit.assertEquals(1, bear.getAmountOfKeyword(Keyword.LIFELINK)); GameSimulator sim = createSimulator(game, p); Game simGame = sim.getSimulatedGameState(); Card bearCopy = findCardWithName(simGame, bearCardName); - AssertJUnit.assertEquals(1, bearCopy.getAmountOfKeyword("Lifelink")); + AssertJUnit.assertEquals(1, bearCopy.getAmountOfKeyword(Keyword.LIFELINK)); } @Test diff --git a/forge-gui/res/cardsfolder/t/topsy_turvy.txt b/forge-gui/res/cardsfolder/t/topsy_turvy.txt index 4597cc6183c..30ca65417e0 100644 --- a/forge-gui/res/cardsfolder/t/topsy_turvy.txt +++ b/forge-gui/res/cardsfolder/t/topsy_turvy.txt @@ -1,7 +1,7 @@ Name:Topsy Turvy ManaCost:2 U Types:Enchantment -S:Mode$ Continuous | Affected$ Player | AddKeyword$ The phases of your turn are reversed. | Description$ The phases of each player's turn are reversed. (The phases are, in reverse order, ending, postcombat main, combat, precombat main, and beginning.) -S:Mode$ Continuous | Affected$ Player | AddKeyword$ The turn order is reversed. | CheckSVar$ X | SVarCompare$ GT2 | Description$ As long as there are more than two players in the game, the turn order is reversed. +S:Mode$ PhaseReversed | ValidPlayer$ Player | Description$ The phases of each player's turn are reversed. (The phases are, in reverse order, ending, postcombat main, combat, precombat main, and beginning.) +S:Mode$ TurnReversed | ValidPlayer$ Player | CheckSVar$ X | SVarCompare$ GT2 | Description$ As long as there are more than two players in the game, the turn order is reversed. SVar:X:PlayerCountPlayers$Amount Oracle:The phases of each player's turn are reversed. (The phases are, in reverse order, ending, postcombat main, combat, precombat main, and beginning.)\nAs long as there are more than two players in the game, the turn order is reversed.