- Introduce PhaseIn and PhaseOut triggers

- Added Teferi's Imp (as an example of both)
This commit is contained in:
Sol
2014-02-06 03:01:21 +00:00
parent 028e4bc196
commit a11e7bbcb8
6 changed files with 107 additions and 1 deletions

3
.gitattributes vendored
View File

@@ -590,6 +590,8 @@ forge-game/src/main/java/forge/game/trigger/TriggerLosesGame.java -text
forge-game/src/main/java/forge/game/trigger/TriggerNewGame.java -text forge-game/src/main/java/forge/game/trigger/TriggerNewGame.java -text
forge-game/src/main/java/forge/game/trigger/TriggerPayCumulativeUpkeep.java -text forge-game/src/main/java/forge/game/trigger/TriggerPayCumulativeUpkeep.java -text
forge-game/src/main/java/forge/game/trigger/TriggerPhase.java svneol=native#text/plain forge-game/src/main/java/forge/game/trigger/TriggerPhase.java svneol=native#text/plain
forge-game/src/main/java/forge/game/trigger/TriggerPhaseIn.java -text
forge-game/src/main/java/forge/game/trigger/TriggerPhaseOut.java -text
forge-game/src/main/java/forge/game/trigger/TriggerPlanarDice.java -text forge-game/src/main/java/forge/game/trigger/TriggerPlanarDice.java -text
forge-game/src/main/java/forge/game/trigger/TriggerPlaneswalkedFrom.java -text forge-game/src/main/java/forge/game/trigger/TriggerPlaneswalkedFrom.java -text
forge-game/src/main/java/forge/game/trigger/TriggerPlaneswalkedTo.java -text forge-game/src/main/java/forge/game/trigger/TriggerPlaneswalkedTo.java -text
@@ -12328,6 +12330,7 @@ forge-gui/res/cardsfolder/t/teferis_care.txt -text
forge-gui/res/cardsfolder/t/teferis_curse.txt -text forge-gui/res/cardsfolder/t/teferis_curse.txt -text
forge-gui/res/cardsfolder/t/teferis_drake.txt -text forge-gui/res/cardsfolder/t/teferis_drake.txt -text
forge-gui/res/cardsfolder/t/teferis_honor_guard.txt -text forge-gui/res/cardsfolder/t/teferis_honor_guard.txt -text
forge-gui/res/cardsfolder/t/teferis_imp.txt -text
forge-gui/res/cardsfolder/t/teferis_isle.txt -text forge-gui/res/cardsfolder/t/teferis_isle.txt -text
forge-gui/res/cardsfolder/t/teferis_moat.txt -text forge-gui/res/cardsfolder/t/teferis_moat.txt -text
forge-gui/res/cardsfolder/t/teferis_puzzle_box.txt svneol=native#text/plain forge-gui/res/cardsfolder/t/teferis_puzzle_box.txt svneol=native#text/plain

View File

@@ -4879,7 +4879,7 @@ public class Card extends GameEntity implements Comparable<Card> {
final boolean phasingIn = this.isPhasedOut(); final boolean phasingIn = this.isPhasedOut();
if (!this.switchPhaseState()) { if (!this.switchPhaseState()) {
// Switch Phase State returns False if the Permanent can't Phase Out // Switch Phase State bails early if the Permanent can't Phase Out
return; return;
} }
@@ -4913,6 +4913,15 @@ public class Card extends GameEntity implements Comparable<Card> {
return false; return false;
} }
final Map<String, Object> runParams = new TreeMap<String, Object>();
runParams.put("Card", this);
if (!this.isPhasedOut()) {
// If this is currently PhasedIn, it's about to phase out.
// Run trigger before it does because triggers don't work with phased out objects
getGame().getTriggerHandler().runTrigger(TriggerType.PhaseOut, runParams, false);
}
this.phasedOut = !this.phasedOut; this.phasedOut = !this.phasedOut;
final Combat combat = this.getGame().getPhaseHandler().getCombat(); final Combat combat = this.getGame().getPhaseHandler().getCombat();
if (combat != null && this.phasedOut) { if (combat != null && this.phasedOut) {
@@ -4934,6 +4943,12 @@ public class Card extends GameEntity implements Comparable<Card> {
getGame().getAction().exile(this); getGame().getAction().exile(this);
getGame().getTriggerHandler().clearSuppression(TriggerType.ChangesZone); getGame().getTriggerHandler().clearSuppression(TriggerType.ChangesZone);
} }
if (!this.phasedOut) {
// Just phased in, time to run the phased in trigger
getGame().getTriggerHandler().runTrigger(TriggerType.PhaseIn, runParams, false);
}
return true; return true;
} }

View File

@@ -0,0 +1,34 @@
package forge.game.trigger;
import forge.game.card.Card;
import forge.game.spellability.SpellAbility;
import java.util.Map;
public class TriggerPhaseIn extends Trigger {
public TriggerPhaseIn(final Map<String, String> params, final Card host, final boolean intrinsic) {
super(params, host, intrinsic);
}
/** {@inheritDoc} */
@Override
public final boolean performTest(final java.util.Map<String, Object> runParams2) {
final Card phaser = (Card) runParams2.get("Card");
if (this.mapParams.containsKey("ValidCard")) {
if (!phaser.isValid(this.mapParams.get("ValidCard").split(","), this.getHostCard().getController(),
this.getHostCard())) {
return false;
}
}
return true;
}
/** {@inheritDoc} */
@Override
public final void setTriggeringObjects(final SpellAbility sa) {
sa.setTriggeringObject("Card", this.getRunParams().get("Card"));
}
}

View File

@@ -0,0 +1,40 @@
package forge.game.trigger;
import forge.game.card.Card;
import forge.game.spellability.SpellAbility;
import java.util.Map;
public class TriggerPhaseOut extends Trigger {
public TriggerPhaseOut(final Map<String, String> params, final Card host, final boolean intrinsic) {
super(params, host, intrinsic);
}
/** {@inheritDoc} */
@Override
public final boolean performTest(final java.util.Map<String, Object> runParams2) {
final Card phaser = (Card) runParams2.get("Card");
if (this.mapParams.containsKey("ValidCard")) {
if (this.mapParams.get("ValidCard").equals("Card.Self")) {
// Since Phased out cards aren't visible in .isValid, use a special check here.
// NOTE: All Phase Out Triggers should use ValidCard$ Card.Self
if (phaser != this.getHostCard()) {
return false;
}
} else if (!phaser.isValid(this.mapParams.get("ValidCard").split(","), this.getHostCard().getController(),
this.getHostCard())) {
return false;
}
}
return true;
}
/** {@inheritDoc} */
@Override
public final void setTriggeringObjects(final SpellAbility sa) {
sa.setTriggeringObject("Card", this.getRunParams().get("Card"));
}
}

View File

@@ -46,6 +46,8 @@ public enum TriggerType {
NewGame(TriggerNewGame.class), NewGame(TriggerNewGame.class),
PayCumulativeUpkeep(TriggerPayCumulativeUpkeep.class), PayCumulativeUpkeep(TriggerPayCumulativeUpkeep.class),
Phase(TriggerPhase.class), Phase(TriggerPhase.class),
PhaseIn(TriggerPhaseIn.class),
PhaseOut(TriggerPhaseOut.class),
PlanarDice(TriggerPlanarDice.class), PlanarDice(TriggerPlanarDice.class),
PlaneswalkedFrom(TriggerPlaneswalkedFrom.class), PlaneswalkedFrom(TriggerPlaneswalkedFrom.class),
PlaneswalkedTo(TriggerPlaneswalkedTo.class), PlaneswalkedTo(TriggerPlaneswalkedTo.class),

View File

@@ -0,0 +1,12 @@
Name:Teferi's Imp
ManaCost:2 U
Types:Creature Imp
PT:1/1
K:Flying
K:Phasing
T:Mode$ PhaseOut | ValidCard$ Card.Self | Execute$ TrigDiscard | TriggerDescription$ Whenever CARDNAME phases out, discard a card.
SVar:TrigDiscard:DB$ Discard | Defined$ You | Mode$ TgtChoose | NumCards$ 1
T:Mode$ PhaseIn | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ Whenever CARDNAME phases in, draw a card.
SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1
SVar:Picture:http://www.wizards.com/global/images/magic/general/teferis_imp.jpg
Oracle:Flying\nPhasing (This phases in or out before you untap during each of your untap steps. While it's phased out, it's treated as though it doesn't exist.)\nWhenever Teferi's Imp phases out, discard a card.\nWhenever Teferi's Imp phases in, draw a card.