- 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

View File

@@ -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<Card> 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() {

View File

@@ -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);

View File

@@ -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);
}

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;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import forge.game.player.Player;
import forge.game.trigger.Trigger;
/**
* <p>
@@ -31,7 +36,7 @@ import forge.game.player.Player;
public class ExtraTurn {
private Player player = null;
private boolean loseAtEndStep = false;
private List<Trigger> delTrig = Collections.synchronizedList(new ArrayList<Trigger>());
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<Trigger> getDelayedTriggers() {
return delTrig;
}
/**

View File

@@ -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.");
}

View File

@@ -48,6 +48,7 @@ public class TriggerHandler {
private final List<Trigger> activeTriggers = 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 List<TriggerWaiting> waitingTriggers = Collections.synchronizedList(new ArrayList<TriggerWaiting>());
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<Trigger> deltrigs = new ArrayList<Trigger>(delayedTriggers);