From 2f5b7e0744d480d605d1eb03fa418f1108104064 Mon Sep 17 00:00:00 2001 From: swordshine Date: Thu, 18 Dec 2014 05:38:48 +0000 Subject: [PATCH] - Converted Final Fortune's effect to a delayed trigger --- .gitattributes | 1 - forge-game/src/main/java/forge/game/Game.java | 7 +- .../game/ability/effects/AddTurnEffect.java | 11 ++- .../ability/effects/DelayedTriggerEffect.java | 2 + .../main/java/forge/game/phase/EndOfTurn.java | 76 ------------------- .../main/java/forge/game/phase/ExtraTurn.java | 19 +++-- .../java/forge/game/phase/PhaseHandler.java | 12 ++- .../forge/game/trigger/TriggerHandler.java | 11 +++ .../res/cardsfolder/b/bident_of_thassa.txt | 2 +- forge-gui/res/cardsfolder/f/final_fortune.txt | 4 +- forge-gui/res/cardsfolder/l/last_chance.txt | 4 +- forge-gui/res/cardsfolder/w/warriors_oath.txt | 4 +- 12 files changed, 55 insertions(+), 98 deletions(-) delete mode 100644 forge-game/src/main/java/forge/game/phase/EndOfTurn.java diff --git a/.gitattributes b/.gitattributes index c802b73986b..4a7c5ef0ec0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -563,7 +563,6 @@ forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java svneol=native#te forge-game/src/main/java/forge/game/mana/ManaPool.java svneol=native#text/plain forge-game/src/main/java/forge/game/mana/package-info.java svneol=native#text/plain forge-game/src/main/java/forge/game/package-info.java -text -forge-game/src/main/java/forge/game/phase/EndOfTurn.java svneol=native#text/plain forge-game/src/main/java/forge/game/phase/ExtraTurn.java -text forge-game/src/main/java/forge/game/phase/Phase.java svneol=native#text/plain forge-game/src/main/java/forge/game/phase/PhaseHandler.java -text diff --git a/forge-game/src/main/java/forge/game/Game.java b/forge-game/src/main/java/forge/game/Game.java index 9f1a6726c80..78c593956ca 100644 --- a/forge-game/src/main/java/forge/game/Game.java +++ b/forge-game/src/main/java/forge/game/Game.java @@ -45,7 +45,6 @@ import forge.game.card.CardPredicates; import forge.game.combat.Combat; import forge.game.event.GameEvent; import forge.game.event.GameEventGameOutcome; -import forge.game.phase.EndOfTurn; import forge.game.phase.Phase; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; @@ -78,8 +77,8 @@ public class Game { private List activePlanes = null; public final Phase cleanup; - public final EndOfTurn endOfTurn; public final Phase endOfCombat; + public final Phase endOfTurn; public final Untap untap; public final Upkeep upkeep; public final MagicStack stack; @@ -154,8 +153,8 @@ public class Game { untap = new Untap(this); upkeep = new Upkeep(this); cleanup = new Phase(PhaseType.CLEANUP); - endOfTurn = new EndOfTurn(this); endOfCombat = new Phase(PhaseType.COMBAT_END); + endOfTurn = new Phase(PhaseType.END_OF_TURN); view = new GameView(this); @@ -215,7 +214,7 @@ public class Game { public final Phase getEndOfCombat() { return endOfCombat; } - public final EndOfTurn getEndOfTurn() { + public final Phase getEndOfTurn() { return endOfTurn; } public final Phase getCleanup() { diff --git a/forge-game/src/main/java/forge/game/ability/effects/AddTurnEffect.java b/forge-game/src/main/java/forge/game/ability/effects/AddTurnEffect.java index 4981dc432d1..9cb354c4e28 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AddTurnEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AddTurnEffect.java @@ -1,10 +1,13 @@ package forge.game.ability.effects; +import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; import forge.game.phase.ExtraTurn; import forge.game.player.Player; import forge.game.spellability.SpellAbility; +import forge.game.trigger.Trigger; +import forge.game.trigger.TriggerHandler; import java.util.List; @@ -44,8 +47,12 @@ public class AddTurnEffect extends SpellAbilityEffect { if ((sa.getTargetRestrictions() == null) || p.canBeTargetedBy(sa)) { for (int i = 0; i < numTurns; i++) { ExtraTurn extra = p.getGame().getPhaseHandler().addExtraTurn(p); - if (sa.hasParam("LoseAtEndStep")) { - extra.setLoseAtEndStep(true); + if (sa.hasParam("ExtraTurnDelayedTrigger")) { + final Trigger delTrig = TriggerHandler.parseTrigger(sa.getSVar(sa.getParam("ExtraTurnDelayedTrigger")), sa.getHostCard(), true); + SpellAbility overridingSA = AbilityFactory.getAbility(sa.getSVar(sa.getParam("ExtraTurnDelayedTriggerExcute")), sa.getHostCard()); + overridingSA.setActivatingPlayer(sa.getActivatingPlayer()); + delTrig.setOverridingAbility(overridingSA); + extra.addTrigger(delTrig); } if (sa.hasParam("SkipUntap")) { extra.setSkipUntap(true); diff --git a/forge-game/src/main/java/forge/game/ability/effects/DelayedTriggerEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DelayedTriggerEffect.java index e2fa7aaca4a..dd1045345ab 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DelayedTriggerEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DelayedTriggerEffect.java @@ -78,6 +78,8 @@ public class DelayedTriggerEffect extends SpellAbilityEffect { if (mapParams.containsKey("DelayedTriggerDefinedPlayer")) { // on sb's next turn Player p = Iterables.getFirst(AbilityUtils.getDefinedPlayers(sa.getHostCard(), mapParams.get("DelayedTriggerDefinedPlayer"), sa), null); trigHandler.registerPlayerDefinedDelayedTrigger(p, delTrig); + } else if (mapParams.containsKey("ThisTurn")) { + trigHandler.registerThisTurnDelayedTrigger(delTrig); } else { trigHandler.registerDelayedTrigger(delTrig); } diff --git a/forge-game/src/main/java/forge/game/phase/EndOfTurn.java b/forge-game/src/main/java/forge/game/phase/EndOfTurn.java deleted file mode 100644 index d1455b0c588..00000000000 --- a/forge-game/src/main/java/forge/game/phase/EndOfTurn.java +++ /dev/null @@ -1,76 +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.phase; - -import forge.card.mana.ManaCost; -import forge.game.Game; -import forge.game.card.Card; -import forge.game.player.GameLossReason; -import forge.game.player.Player; -import forge.game.spellability.Ability; -import forge.game.spellability.SpellAbility; - - -/** - *

- * Handles "until end of turn" effects and "at end of turn" triggers. - *

- * - * @author Forge - * @version $Id$ - */ -public class EndOfTurn extends Phase { - /** Constant serialVersionUID=-3656715295379727275L. */ - private static final long serialVersionUID = -3656715295379727275L; - - protected final Game game; - public EndOfTurn(final Game game) { - super(PhaseType.END_OF_TURN); - this.game = game; - } - /** - *

- * Handles all the hardcoded events that happen "at end of turn". - *

- */ - @Override - public final void executeAt() { - // reset mustAttackEntity for me - game.getPhaseHandler().getPlayerTurn().setMustAttackEntity(null); - // TODO: convert this to a delayed trigger - Player activePlayer = game.getPhaseHandler().getPlayerTurn(); - if (activePlayer.hasKeyword("At the beginning of this turn's end step, you lose the game.")) { - final Card source = new Card(game.nextCardId()); - final SpellAbility change = new Ability(source, ManaCost.ZERO) { - @Override - public void resolve() { - this.getActivatingPlayer().loseConditionMet(GameLossReason.SpellEffect, ""); - } - }; - change.setStackDescription("At the beginning of this turn's end step, you lose the game."); - change.setDescription("At the beginning of this turn's end step, you lose the game."); - change.setActivatingPlayer(activePlayer); - - game.getStack().addSimultaneousStackEntry(change); - } - - this.execute(this.at); - - } // executeAt() - -} // end class EndOfTurn diff --git a/forge-game/src/main/java/forge/game/phase/ExtraTurn.java b/forge-game/src/main/java/forge/game/phase/ExtraTurn.java index d610ed1933a..156e788cf1d 100644 --- a/forge-game/src/main/java/forge/game/phase/ExtraTurn.java +++ b/forge-game/src/main/java/forge/game/phase/ExtraTurn.java @@ -17,7 +17,12 @@ */ package forge.game.phase; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + import forge.game.player.Player; +import forge.game.trigger.Trigger; /** *

@@ -31,7 +36,7 @@ import forge.game.player.Player; public class ExtraTurn { private Player player = null; - private boolean loseAtEndStep = false; + private List delTrig = Collections.synchronizedList(new ArrayList()); private boolean skipUntap = false; private boolean cantSetSchemesInMotion = false; /** @@ -57,17 +62,17 @@ public class ExtraTurn { } /** - * @return the loseAtEndStep + * @param deltrigger the Trigger to add */ - public boolean isLoseAtEndStep() { - return loseAtEndStep; + public void addTrigger(Trigger deltrigger) { + this.delTrig.add(deltrigger); } /** - * @param loseAtEndStep the loseAtEndStep to set + * @return the delTrig */ - public void setLoseAtEndStep(boolean loseAtEndStep) { - this.loseAtEndStep = loseAtEndStep; + public List getDelayedTriggers() { + return delTrig; } /** 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 a101289c63d..c30ce0f3595 100644 --- a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java +++ b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java @@ -38,6 +38,7 @@ import forge.game.player.PlayerController.BinaryChoiceType; import forge.game.player.PlayerController.ManaPaymentPurpose; import forge.game.spellability.SpellAbility; import forge.game.staticability.StaticAbility; +import forge.game.trigger.Trigger; import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; import forge.util.CollectionSuppliers; @@ -720,6 +721,8 @@ public class PhaseHandler implements java.io.Serializable { private Player handleNextTurn() { game.getStack().onNextTurn(); + // reset mustAttackEntity + playerTurn.setMustAttackEntity(null); for (final Player p1 : game.getPlayers()) { for (final ZoneType z : Player.ALL_ZONES) { @@ -735,11 +738,12 @@ public class PhaseHandler implements java.io.Serializable { p.setLibrarySearched(0); p.setNumManaConversion(0); - p.removeKeyword("At the beginning of this turn's end step, you lose the game."); p.removeKeyword("Skip the untap step of this turn."); p.removeKeyword("Schemes can't be set in motion this turn."); } + game.getTriggerHandler().clearThisTurnDelayedTrigger(); + Player next = getNextActivePlayer(); game.getTriggerHandler().handlePlayerDefinedDelTriggers(next); @@ -765,6 +769,9 @@ public class PhaseHandler implements java.io.Serializable { if (nextPlayer.hasKeyword("If you would begin an extra turn, skip that turn instead.")) { return getNextActivePlayer(); } + for (Trigger deltrig : extraTurn.getDelayedTriggers()) { + game.getTriggerHandler().registerThisTurnDelayedTrigger(deltrig); + } } else { nextPlayer.setExtraTurn(false); @@ -799,9 +806,6 @@ public class PhaseHandler implements java.io.Serializable { } if (extraTurn != null) { - if (extraTurn.isLoseAtEndStep()) { - nextPlayer.addKeyword("At the beginning of this turn's end step, you lose the game."); - } if (extraTurn.isSkipUntap()) { nextPlayer.addKeyword("Skip the untap step of this turn."); } diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java b/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java index ba0700f9f2a..0aacd59c5f1 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java @@ -48,6 +48,7 @@ public class TriggerHandler { private final List activeTriggers = Collections.synchronizedList(new ArrayList()); private final List delayedTriggers = Collections.synchronizedList(new ArrayList()); + private final List thisTurnDelayedTriggers = Collections.synchronizedList(new ArrayList()); private final ListMultimap playerDefinedDelayedTriggers = Multimaps.synchronizedListMultimap(ArrayListMultimap.create()); private final List waitingTriggers = Collections.synchronizedList(new ArrayList()); private final Game game; @@ -86,6 +87,16 @@ public class TriggerHandler { delayedTriggers.clear(); } + public final void registerThisTurnDelayedTrigger(final Trigger trig) { + thisTurnDelayedTriggers.add(trig); + delayedTriggers.add(trig); + } + + public final void clearThisTurnDelayedTrigger() { + delayedTriggers.removeAll(thisTurnDelayedTriggers); + thisTurnDelayedTriggers.clear(); + } + public final void clearDelayedTrigger(final Card card) { final List deltrigs = new ArrayList(delayedTriggers); diff --git a/forge-gui/res/cardsfolder/b/bident_of_thassa.txt b/forge-gui/res/cardsfolder/b/bident_of_thassa.txt index aa39a9a1102..48b99d72c8c 100644 --- a/forge-gui/res/cardsfolder/b/bident_of_thassa.txt +++ b/forge-gui/res/cardsfolder/b/bident_of_thassa.txt @@ -3,7 +3,7 @@ ManaCost:2 U U Types:Legendary Enchantment Artifact T:Mode$ DamageDone | ValidSource$ Creature.YouCtrl | ValidTarget$ Player | CombatDamage$ True | OptionalDecider$ You | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever a creature you control deals combat damage to an opponent, you may draw a card. SVar:TrigDraw:AB$ Draw | Cost$ 0 | NumCards$ 1 -A:AB$ Effect | Cost$ 1 U T | | StaticAbilities$ MustAttack | References$ MustAttack | SpellDescription$ Creatures your opponents control attack this turn if able. +A:AB$ Effect | Cost$ 1 U T | StaticAbilities$ MustAttack | References$ MustAttack | SpellDescription$ Creatures your opponents control attack this turn if able. SVar:MustAttack:Mode$ Continuous | EffectZone$ Command | Affected$ Creature.OppCtrl | AddHiddenKeyword$ CARDNAME attacks each turn if able. | Description$ Creatures your opponents control attack this turn if able. SVar:PlayMain1:TRUE SVar:Picture:http://www.wizards.com/global/images/magic/general/bident_of_thassa.jpg diff --git a/forge-gui/res/cardsfolder/f/final_fortune.txt b/forge-gui/res/cardsfolder/f/final_fortune.txt index 2c37fbb6a21..b0117e083e1 100644 --- a/forge-gui/res/cardsfolder/f/final_fortune.txt +++ b/forge-gui/res/cardsfolder/f/final_fortune.txt @@ -1,7 +1,9 @@ Name:Final Fortune ManaCost:R R Types:Instant -A:SP$ AddTurn | Cost$ R R | NumTurns$ 1 | LoseAtEndStep$ True | SpellDescription$ Take an extra turn after this one. At the beginning of that turn's end step, you lose the game. +A:SP$ AddTurn | Cost$ R R | NumTurns$ 1 | ExtraTurnDelayedTrigger$ DBDelTrig | ExtraTurnDelayedTriggerExcute$ TrigLose | References$ DBDelTrig,TrigLose | SpellDescription$ Take an extra turn after this one. At the beginning of that turn's end step, you lose the game. +SVar:DBDelTrig:ThisTurn$ True | Mode$ Phase | Phase$ End of Turn | TriggerDescription$ At the beginning of that turn's end step, you lose the game. +SVar:TrigLose:AB$ LosesGame | Cost$ 0 | Defined$ You SVar:RemAIDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/final_fortune.jpg Oracle:Take an extra turn after this one. At the beginning of that turn's end step, you lose the game. diff --git a/forge-gui/res/cardsfolder/l/last_chance.txt b/forge-gui/res/cardsfolder/l/last_chance.txt index 9d81264992b..457125fea3c 100644 --- a/forge-gui/res/cardsfolder/l/last_chance.txt +++ b/forge-gui/res/cardsfolder/l/last_chance.txt @@ -1,7 +1,9 @@ Name:Last Chance ManaCost:R R Types:Sorcery -A:SP$ AddTurn | Cost$ R R | NumTurns$ 1 | LoseAtEndStep$ True | SpellDescription$ Take an extra turn after this one. At the beginning of that turn's end step, you lose the game. +A:SP$ AddTurn | Cost$ R R | NumTurns$ 1 | ExtraTurnDelayedTrigger$ DBDelTrig | ExtraTurnDelayedTriggerExcute$ TrigLose | References$ DBDelTrig,TrigLose | SpellDescription$ Take an extra turn after this one. At the beginning of that turn's end step, you lose the game. +SVar:DBDelTrig:ThisTurn$ True | Mode$ Phase | Phase$ End of Turn | TriggerDescription$ At the beginning of that turn's end step, you lose the game. +SVar:TrigLose:AB$ LosesGame | Cost$ 0 | Defined$ You SVar:RemAIDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/last_chance.jpg Oracle:Take an extra turn after this one. At the beginning of that turn's end step, you lose the game. diff --git a/forge-gui/res/cardsfolder/w/warriors_oath.txt b/forge-gui/res/cardsfolder/w/warriors_oath.txt index eff8d415ced..ac1c3b51d5d 100644 --- a/forge-gui/res/cardsfolder/w/warriors_oath.txt +++ b/forge-gui/res/cardsfolder/w/warriors_oath.txt @@ -1,7 +1,9 @@ Name:Warrior's Oath ManaCost:R R Types:Sorcery -A:SP$ AddTurn | Cost$ R R | NumTurns$ 1 | LoseAtEndStep$ True | SpellDescription$ Take an extra turn after this one. At the beginning of that turn's end step, you lose the game. +A:SP$ AddTurn | Cost$ R R | NumTurns$ 1 | ExtraTurnDelayedTrigger$ DBDelTrig | ExtraTurnDelayedTriggerExcute$ TrigLose | References$ DBDelTrig,TrigLose | SpellDescription$ Take an extra turn after this one. At the beginning of that turn's end step, you lose the game. +SVar:DBDelTrig:ThisTurn$ True | Mode$ Phase | Phase$ End of Turn | Execute$ TrigLose | TriggerDescription$ At the beginning of that turn's end step, you lose the game. +SVar:TrigLose:AB$ LosesGame | Cost$ 0 | Defined$ You SVar:RemAIDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/warriors_oath.jpg Oracle:Take an extra turn after this one. At the beginning of that turn's end step, you lose the game.