From 10f1859d0c4da2c1258a97a6fdd4b86384238115 Mon Sep 17 00:00:00 2001 From: Hellfish Date: Mon, 13 Feb 2012 10:07:00 +0000 Subject: [PATCH] *Added AF_EndTurn. canPlayAI always returns false because I couldn't think of a good,general way to decide it's usefulness. *Added Sundial of the Infinite Time Stop --- .gitattributes | 2 + res/cardsfolder/m/martyrs_of_korlis.txt | 2 + res/cardsfolder/s/sundial_of_the_infinite.txt | 10 ++ res/cardsfolder/t/time_stop.txt | 11 ++ res/cardsfolder/v/vengeful_rebirth.txt | 3 + src/main/java/forge/PhaseHandler.java | 5 + .../card/abilityfactory/AbilityFactory.java | 10 ++ .../abilityfactory/AbilityFactoryTurns.java | 124 ++++++++++++++++++ 8 files changed, 167 insertions(+) create mode 100644 res/cardsfolder/s/sundial_of_the_infinite.txt create mode 100644 res/cardsfolder/t/time_stop.txt diff --git a/.gitattributes b/.gitattributes index d946fef5049..5361017e848 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8651,6 +8651,7 @@ res/cardsfolder/s/sunder.txt svneol=native#text/plain res/cardsfolder/s/sunder_from_within.txt svneol=native#text/plain res/cardsfolder/s/sundering_titan.txt -text res/cardsfolder/s/sundering_vitae.txt -text +res/cardsfolder/s/sundial_of_the_infinite.txt -text res/cardsfolder/s/sunfire_balm.txt svneol=native#text/plain res/cardsfolder/s/sunflare_shaman.txt svneol=native#text/plain res/cardsfolder/s/sunglasses_of_urza.txt svneol=native#text/plain @@ -9109,6 +9110,7 @@ res/cardsfolder/t/time_of_need.txt svneol=native#text/plain res/cardsfolder/t/time_reversal.txt svneol=native#text/plain res/cardsfolder/t/time_sieve.txt svneol=native#text/plain res/cardsfolder/t/time_spiral.txt svneol=native#text/plain +res/cardsfolder/t/time_stop.txt -text res/cardsfolder/t/time_stretch.txt svneol=native#text/plain res/cardsfolder/t/time_vault.txt svneol=native#text/plain res/cardsfolder/t/time_walk.txt svneol=native#text/plain diff --git a/res/cardsfolder/m/martyrs_of_korlis.txt b/res/cardsfolder/m/martyrs_of_korlis.txt index 79a05a90022..d9032e4bebd 100644 --- a/res/cardsfolder/m/martyrs_of_korlis.txt +++ b/res/cardsfolder/m/martyrs_of_korlis.txt @@ -9,4 +9,6 @@ SVar:DmgMartyrsofKorlisSelf:AB$DealDamage | Cost$ 0 | Defined$ Self | DamageSour SVar:DmgMartyrsofKorlisSelfCombat:AB$DealDamage | Cost$ 0 | CombatDamage$ True | Defined$ Self | DamageSource$ ReplacedSource | NumDmg$ MartyrsofKorlisX SVar:MartyrsofKorlisX:ReplaceCount$DamageAmount SVar:Picture:http://www.wizards.com/global/images/magic/general/martyrs_of_korlis.jpg +Oracle:As long as Martyrs of Korlis is untapped, all damage that would be dealt to you by artifacts is dealt to Martyrs of Korlis instead. +SetInfo:ATQ|Uncommon|http://magiccards.info/scans/en/aq/99.jpg End \ No newline at end of file diff --git a/res/cardsfolder/s/sundial_of_the_infinite.txt b/res/cardsfolder/s/sundial_of_the_infinite.txt new file mode 100644 index 00000000000..a570067b9cc --- /dev/null +++ b/res/cardsfolder/s/sundial_of_the_infinite.txt @@ -0,0 +1,10 @@ +Name:Sundial of the Infinite +ManaCost:2 +Types:Artifact +Text:no text +A:AB$EndTurn | Cost$ 1 T | PlayerTurn$ True | SpellDescription$ End the turn. Activate this ability only during your turn. (Exile all spells and abilities on the stack. Discard down to your maximum hand size. Damage wears off, and "this turn" and "until end of turn" effects end.) +SVar:RemAIDeck:True +SVar:Picture:http://www.wizards.com/global/images/magic/general/sundial_of_the_infinite.jpg +Oracle:{1}, {T}: End the turn. Activate this ability only during your turn. (Exile all spells and abilities on the stack. Discard down to your maximum hand size. Damage wears off, and "this turn" and "until end of turn" effects end.) +SetInfo:M12|Rare|http://magiccards.info/scans/en/m12/218.jpg +End \ No newline at end of file diff --git a/res/cardsfolder/t/time_stop.txt b/res/cardsfolder/t/time_stop.txt new file mode 100644 index 00000000000..08cfb9b68e2 --- /dev/null +++ b/res/cardsfolder/t/time_stop.txt @@ -0,0 +1,11 @@ +Name:Time Stop +ManaCost:4 U U +Types:Instant +Text:no text +A:SP$EndTurn | Cost$ 4 U U | SpellDescription$ End the turn. (Exile all spells and abilities on the stack, including this card. The player whose turn it is discards down to his or her maximum hand size. Damage wears off, and "this turn" and "until end of turn" effects end.) +SVar:RemAIDeck:True +SVar:Picture:http://www.wizards.com/global/images/magic/general/time_stop.jpg +Oracle:End the turn. (Exile all spells and abilities on the stack, including this card. The player whose turn it is discards down to his or her maximum hand size. Damage wears off, and "this turn" and "until end of turn" effects end.) +SetInfo:CHK|Rare|http://magiccards.info/scans/en/chk/97.jpg +SetInfo:10E|Rare|http://magiccards.info/scans/en/10e/117.jpg +End \ No newline at end of file diff --git a/res/cardsfolder/v/vengeful_rebirth.txt b/res/cardsfolder/v/vengeful_rebirth.txt index 3a4464e1db8..274f1c5b4f4 100644 --- a/res/cardsfolder/v/vengeful_rebirth.txt +++ b/res/cardsfolder/v/vengeful_rebirth.txt @@ -9,4 +9,7 @@ SVar:DBVengefulRebirthCleanup:DB$ Cleanup | ClearRemembered$ True SVar:VengefulRebirthX:Remembered$CardManaCost SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/vengeful_rebirth.jpg +Oracle:Return target card from your graveyard to your hand. If you return a nonland card to your hand this way, Vengeful Rebirth deals damage equal to that card's converted mana cost to target creature or player.\nExile Vengeful Rebirth. +SetInfo:ARB|Uncommon|http://magiccards.info/scans/en/arb/62.jpg +SetInfo:COM|Uncommon|http://magiccards.info/scans/en/cmd/233.jpg End \ No newline at end of file diff --git a/src/main/java/forge/PhaseHandler.java b/src/main/java/forge/PhaseHandler.java index 0ea7ecad4e3..08cd8b4dfa1 100644 --- a/src/main/java/forge/PhaseHandler.java +++ b/src/main/java/forge/PhaseHandler.java @@ -1029,6 +1029,11 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { public final void setDevPhaseState(final String phaseID) { this.phaseIndex = this.findIndex(phaseID); } + + public final void setPhaseState(final String phaseID) { + this.phaseIndex = this.findIndex(phaseID); + this.handleBeginPhase(); + } /** * diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactory.java b/src/main/java/forge/card/abilityfactory/AbilityFactory.java index ac6df904e8f..8e495a6a9b6 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactory.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactory.java @@ -760,6 +760,16 @@ public class AbilityFactory { spellAbility = AbilityFactoryEffect.createDrawbackEffect(this); } } + + else if (this.api.equals("EndTurn")) { + if(this.isAb) { + spellAbility = AbilityFactoryTurns.createAbilityEndTurn(this); + } else if (this.isSp) { + spellAbility = AbilityFactoryTurns.createSpellEndTurn(this); + } else if (this.isDb) { + spellAbility = AbilityFactoryTurns.createDrawbackEndTurn(this); + } + } else if (this.api.equals("ExchangeLife")) { if (this.isAb) { diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryTurns.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryTurns.java index b1efcebafb2..2988e229cbc 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryTurns.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryTurns.java @@ -21,6 +21,8 @@ import java.util.ArrayList; import java.util.HashMap; import forge.AllZone; +import forge.Card; +import forge.Constant; import forge.Player; import forge.card.spellability.AbilityActivated; import forge.card.spellability.AbilitySub; @@ -286,5 +288,127 @@ public class AbilityFactoryTurns { } } } + + // ************************************************************************* + // ************************* END TURN ************************************** + // ************************************************************************* + + public static SpellAbility createAbilityEndTurn(final AbilityFactory af) { + SpellAbility ret = new AbilityActivated(af.getHostCard(),af.getAbCost(),af.getAbTgt()) { + + private static final long serialVersionUID = 72570867940224012L; + + @Override + public String getStackDescription() { + return "End the turn."; + } + + @Override + public boolean canPlayAI() { + return false; + } + + @Override + public boolean doTrigger(boolean mandatory) { + if(mandatory) { + return true; + } + + return false; + } + + @Override + public void resolve() { + endTurnResolve(af,this); + } + + }; + + return ret; + } + + public static SpellAbility createSpellEndTurn(final AbilityFactory af) { + SpellAbility ret = new Spell(af.getHostCard(),af.getAbCost(),af.getAbTgt()) { + + private static final long serialVersionUID = -2553413143747617709L; + + @Override + public String getStackDescription() { + return "End the turn."; + } + + @Override + public boolean canPlayAI() { + return false; + } + + @Override + public void resolve() { + endTurnResolve(af,this); + } + + }; + + return ret; + } + + public static SpellAbility createDrawbackEndTurn(final AbilityFactory af) { + final SpellAbility dbEndTurn = new AbilitySub(af.getHostCard(), af.getAbTgt()) { + private static final long serialVersionUID = -562517287448810951L; + + @Override + public String getStackDescription() { + return "End the turn."; + } + + @Override + public void resolve() { + AbilityFactoryTurns.endTurnResolve(af, this); + } + + @Override + public boolean chkAIDrawback() { + return false; + } + + @Override + public boolean doTrigger(final boolean mandatory) { + if(mandatory) { + return true; + } + + return false; + } + + }; + return dbEndTurn; + } + + private static void endTurnResolve(final AbilityFactory af, final SpellAbility sa) { + + //Steps taken from gatherer's rulings on Time Stop. + //1) All spells and abilities on the stack are exiled. This includes Time Stop, though it will continue to resolve. It also includes spells and abilities that can't be countered. + for(Card c : AllZone.getStackZone().getCards()) { + AllZone.getGameAction().exile(c); + } + AllZone.getStack().getStack().clear(); + + //2) All attacking and blocking creatures are removed from combat. + AllZone.getCombat().resetAttackers(); + AllZone.getCombat().resetBlockers(); + + //3) State-based actions are checked. No player gets priority, and no triggered abilities are put onto the stack. + AllZone.getGameAction().checkStateEffects(); + + //4) The current phase and/or step ends. The game skips straight to the cleanup step. The cleanup step happens in its entirety. + AllZone.getPhaseHandler().setPhaseState(Constant.Phase.CLEANUP); + + //Update observers + AllZone.getStack().updateObservers(); + AllZone.getComputerPlayer().updateObservers(); + AllZone.getHumanPlayer().updateObservers(); + AllZone.getComputerPlayer().updateLabelObservers(); + AllZone.getHumanPlayer().updateLabelObservers(); + } } // end class AbilityFactory_Turns