- Converted Final Fortune's effect to a delayed trigger

This commit is contained in:
swordshine
2014-12-18 05:38:48 +00:00
parent 8048b216a9
commit 2f5b7e0744
12 changed files with 55 additions and 98 deletions

1
.gitattributes vendored
View File

@@ -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/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/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/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/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/Phase.java svneol=native#text/plain
forge-game/src/main/java/forge/game/phase/PhaseHandler.java -text forge-game/src/main/java/forge/game/phase/PhaseHandler.java -text

View File

@@ -45,7 +45,6 @@ import forge.game.card.CardPredicates;
import forge.game.combat.Combat; import forge.game.combat.Combat;
import forge.game.event.GameEvent; import forge.game.event.GameEvent;
import forge.game.event.GameEventGameOutcome; import forge.game.event.GameEventGameOutcome;
import forge.game.phase.EndOfTurn;
import forge.game.phase.Phase; import forge.game.phase.Phase;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
@@ -78,8 +77,8 @@ public class Game {
private List<Card> activePlanes = null; private List<Card> activePlanes = null;
public final Phase cleanup; public final Phase cleanup;
public final EndOfTurn endOfTurn;
public final Phase endOfCombat; public final Phase endOfCombat;
public final Phase endOfTurn;
public final Untap untap; public final Untap untap;
public final Upkeep upkeep; public final Upkeep upkeep;
public final MagicStack stack; public final MagicStack stack;
@@ -154,8 +153,8 @@ public class Game {
untap = new Untap(this); untap = new Untap(this);
upkeep = new Upkeep(this); upkeep = new Upkeep(this);
cleanup = new Phase(PhaseType.CLEANUP); cleanup = new Phase(PhaseType.CLEANUP);
endOfTurn = new EndOfTurn(this);
endOfCombat = new Phase(PhaseType.COMBAT_END); endOfCombat = new Phase(PhaseType.COMBAT_END);
endOfTurn = new Phase(PhaseType.END_OF_TURN);
view = new GameView(this); view = new GameView(this);
@@ -215,7 +214,7 @@ public class Game {
public final Phase getEndOfCombat() { public final Phase getEndOfCombat() {
return endOfCombat; return endOfCombat;
} }
public final EndOfTurn getEndOfTurn() { public final Phase getEndOfTurn() {
return endOfTurn; return endOfTurn;
} }
public final Phase getCleanup() { public final Phase getCleanup() {

View File

@@ -1,10 +1,13 @@
package forge.game.ability.effects; package forge.game.ability.effects;
import forge.game.ability.AbilityFactory;
import forge.game.ability.AbilityUtils; import forge.game.ability.AbilityUtils;
import forge.game.ability.SpellAbilityEffect; import forge.game.ability.SpellAbilityEffect;
import forge.game.phase.ExtraTurn; import forge.game.phase.ExtraTurn;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.trigger.Trigger;
import forge.game.trigger.TriggerHandler;
import java.util.List; import java.util.List;
@@ -44,8 +47,12 @@ public class AddTurnEffect extends SpellAbilityEffect {
if ((sa.getTargetRestrictions() == null) || p.canBeTargetedBy(sa)) { if ((sa.getTargetRestrictions() == null) || p.canBeTargetedBy(sa)) {
for (int i = 0; i < numTurns; i++) { for (int i = 0; i < numTurns; i++) {
ExtraTurn extra = p.getGame().getPhaseHandler().addExtraTurn(p); ExtraTurn extra = p.getGame().getPhaseHandler().addExtraTurn(p);
if (sa.hasParam("LoseAtEndStep")) { if (sa.hasParam("ExtraTurnDelayedTrigger")) {
extra.setLoseAtEndStep(true); 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")) { if (sa.hasParam("SkipUntap")) {
extra.setSkipUntap(true); extra.setSkipUntap(true);

View File

@@ -78,6 +78,8 @@ public class DelayedTriggerEffect extends SpellAbilityEffect {
if (mapParams.containsKey("DelayedTriggerDefinedPlayer")) { // on sb's next turn if (mapParams.containsKey("DelayedTriggerDefinedPlayer")) { // on sb's next turn
Player p = Iterables.getFirst(AbilityUtils.getDefinedPlayers(sa.getHostCard(), mapParams.get("DelayedTriggerDefinedPlayer"), sa), null); Player p = Iterables.getFirst(AbilityUtils.getDefinedPlayers(sa.getHostCard(), mapParams.get("DelayedTriggerDefinedPlayer"), sa), null);
trigHandler.registerPlayerDefinedDelayedTrigger(p, delTrig); trigHandler.registerPlayerDefinedDelayedTrigger(p, delTrig);
} else if (mapParams.containsKey("ThisTurn")) {
trigHandler.registerThisTurnDelayedTrigger(delTrig);
} else { } else {
trigHandler.registerDelayedTrigger(delTrig); trigHandler.registerDelayedTrigger(delTrig);
} }

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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;
/**
* <p>
* Handles "until end of turn" effects and "at end of turn" triggers.
* </p>
*
* @author Forge
* @version $Id$
*/
public class EndOfTurn extends Phase {
/** Constant <code>serialVersionUID=-3656715295379727275L</code>. */
private static final long serialVersionUID = -3656715295379727275L;
protected final Game game;
public EndOfTurn(final Game game) {
super(PhaseType.END_OF_TURN);
this.game = game;
}
/**
* <p>
* Handles all the hardcoded events that happen "at end of turn".
* </p>
*/
@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

View File

@@ -17,7 +17,12 @@
*/ */
package forge.game.phase; package forge.game.phase;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.trigger.Trigger;
/** /**
* <p> * <p>
@@ -31,7 +36,7 @@ import forge.game.player.Player;
public class ExtraTurn { public class ExtraTurn {
private Player player = null; private Player player = null;
private boolean loseAtEndStep = false; private List<Trigger> delTrig = Collections.synchronizedList(new ArrayList<Trigger>());
private boolean skipUntap = false; private boolean skipUntap = false;
private boolean cantSetSchemesInMotion = false; private boolean cantSetSchemesInMotion = false;
/** /**
@@ -57,17 +62,17 @@ public class ExtraTurn {
} }
/** /**
* @return the loseAtEndStep * @param deltrigger the Trigger to add
*/ */
public boolean isLoseAtEndStep() { public void addTrigger(Trigger deltrigger) {
return loseAtEndStep; this.delTrig.add(deltrigger);
} }
/** /**
* @param loseAtEndStep the loseAtEndStep to set * @return the delTrig
*/ */
public void setLoseAtEndStep(boolean loseAtEndStep) { public List<Trigger> getDelayedTriggers() {
this.loseAtEndStep = loseAtEndStep; return delTrig;
} }
/** /**

View File

@@ -38,6 +38,7 @@ import forge.game.player.PlayerController.BinaryChoiceType;
import forge.game.player.PlayerController.ManaPaymentPurpose; import forge.game.player.PlayerController.ManaPaymentPurpose;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.staticability.StaticAbility; import forge.game.staticability.StaticAbility;
import forge.game.trigger.Trigger;
import forge.game.trigger.TriggerType; import forge.game.trigger.TriggerType;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.util.CollectionSuppliers; import forge.util.CollectionSuppliers;
@@ -720,6 +721,8 @@ public class PhaseHandler implements java.io.Serializable {
private Player handleNextTurn() { private Player handleNextTurn() {
game.getStack().onNextTurn(); game.getStack().onNextTurn();
// reset mustAttackEntity
playerTurn.setMustAttackEntity(null);
for (final Player p1 : game.getPlayers()) { for (final Player p1 : game.getPlayers()) {
for (final ZoneType z : Player.ALL_ZONES) { for (final ZoneType z : Player.ALL_ZONES) {
@@ -735,11 +738,12 @@ public class PhaseHandler implements java.io.Serializable {
p.setLibrarySearched(0); p.setLibrarySearched(0);
p.setNumManaConversion(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("Skip the untap step of this turn.");
p.removeKeyword("Schemes can't be set in motion this turn."); p.removeKeyword("Schemes can't be set in motion this turn.");
} }
game.getTriggerHandler().clearThisTurnDelayedTrigger();
Player next = getNextActivePlayer(); Player next = getNextActivePlayer();
game.getTriggerHandler().handlePlayerDefinedDelTriggers(next); 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.")) { if (nextPlayer.hasKeyword("If you would begin an extra turn, skip that turn instead.")) {
return getNextActivePlayer(); return getNextActivePlayer();
} }
for (Trigger deltrig : extraTurn.getDelayedTriggers()) {
game.getTriggerHandler().registerThisTurnDelayedTrigger(deltrig);
}
} }
else { else {
nextPlayer.setExtraTurn(false); nextPlayer.setExtraTurn(false);
@@ -799,9 +806,6 @@ public class PhaseHandler implements java.io.Serializable {
} }
if (extraTurn != null) { if (extraTurn != null) {
if (extraTurn.isLoseAtEndStep()) {
nextPlayer.addKeyword("At the beginning of this turn's end step, you lose the game.");
}
if (extraTurn.isSkipUntap()) { if (extraTurn.isSkipUntap()) {
nextPlayer.addKeyword("Skip the untap step of this turn."); nextPlayer.addKeyword("Skip the untap step of this turn.");
} }

View File

@@ -48,6 +48,7 @@ public class TriggerHandler {
private final List<Trigger> activeTriggers = Collections.synchronizedList(new ArrayList<Trigger>()); private final List<Trigger> activeTriggers = Collections.synchronizedList(new ArrayList<Trigger>());
private final List<Trigger> delayedTriggers = Collections.synchronizedList(new ArrayList<Trigger>()); private final List<Trigger> delayedTriggers = Collections.synchronizedList(new ArrayList<Trigger>());
private final List<Trigger> thisTurnDelayedTriggers = Collections.synchronizedList(new ArrayList<Trigger>());
private final ListMultimap<Player, Trigger> playerDefinedDelayedTriggers = Multimaps.synchronizedListMultimap(ArrayListMultimap.<Player, Trigger>create()); private final ListMultimap<Player, Trigger> playerDefinedDelayedTriggers = Multimaps.synchronizedListMultimap(ArrayListMultimap.<Player, Trigger>create());
private final List<TriggerWaiting> waitingTriggers = Collections.synchronizedList(new ArrayList<TriggerWaiting>()); private final List<TriggerWaiting> waitingTriggers = Collections.synchronizedList(new ArrayList<TriggerWaiting>());
private final Game game; private final Game game;
@@ -86,6 +87,16 @@ public class TriggerHandler {
delayedTriggers.clear(); 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) { public final void clearDelayedTrigger(final Card card) {
final List<Trigger> deltrigs = new ArrayList<Trigger>(delayedTriggers); final List<Trigger> deltrigs = new ArrayList<Trigger>(delayedTriggers);

View File

@@ -3,7 +3,7 @@ ManaCost:2 U U
Types:Legendary Enchantment Artifact 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. 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 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: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:PlayMain1:TRUE
SVar:Picture:http://www.wizards.com/global/images/magic/general/bident_of_thassa.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/bident_of_thassa.jpg

View File

@@ -1,7 +1,9 @@
Name:Final Fortune Name:Final Fortune
ManaCost:R R ManaCost:R R
Types:Instant 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:RemAIDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/final_fortune.jpg 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. Oracle:Take an extra turn after this one. At the beginning of that turn's end step, you lose the game.

View File

@@ -1,7 +1,9 @@
Name:Last Chance Name:Last Chance
ManaCost:R R ManaCost:R R
Types:Sorcery 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:RemAIDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/last_chance.jpg 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. Oracle:Take an extra turn after this one. At the beginning of that turn's end step, you lose the game.

View File

@@ -1,7 +1,9 @@
Name:Warrior's Oath Name:Warrior's Oath
ManaCost:R R ManaCost:R R
Types:Sorcery 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:RemAIDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/warriors_oath.jpg 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. Oracle:Take an extra turn after this one. At the beginning of that turn's end step, you lose the game.