From 50ca7b68e02f9ac1679a65f3d30c8e8dbb93a0c8 Mon Sep 17 00:00:00 2001 From: Sloth Date: Mon, 8 Apr 2013 20:12:14 +0000 Subject: [PATCH] - Rewrote Epic ability. --- res/cardsfolder/u/undying_flames.txt | 2 +- .../card/ability/effects/EffectEffect.java | 2 +- .../card/cardfactory/CardFactoryUtil.java | 78 +++++-------------- src/main/java/forge/game/GameState.java | 12 ++- src/main/java/forge/game/player/Player.java | 3 + 5 files changed, 36 insertions(+), 61 deletions(-) diff --git a/res/cardsfolder/u/undying_flames.txt b/res/cardsfolder/u/undying_flames.txt index 08954252ba8..e9aad0baa19 100644 --- a/res/cardsfolder/u/undying_flames.txt +++ b/res/cardsfolder/u/undying_flames.txt @@ -4,7 +4,7 @@ Types:Sorcery K:Epic A:SP$ Pump | Cost$ 4 R R | SubAbility$ FlamingExile | ValidTgts$ Creature,Player | TgtPrompt$ Select target creature or player | StackDescription$ None | SpellDescription$ Exile cards from the top of your library until you exile a nonland card. Undying Flames deals damage to target creature or player equal to that card's converted mana cost. SVar:FlamingExile:DB$ DigUntil | Valid$ Card.nonLand | ValidDescription$ nonland | FoundDestination$ Exile | RevealedDestination$ Exile | RememberFound$ True | SubAbility$ UndyingDamage -SVar:UndyingDamage:DB$ DealDamage | Defined$ Targeted | NumDmg$ X | SubAbility$ DBCleanup +SVar:UndyingDamage:DB$ DealDamage | Defined$ Targeted | NumDmg$ X | References$ X | SubAbility$ DBCleanup SVar:DBCleanup:DB$Cleanup | ClearRemembered$ True SVar:X:Remembered$CardManaCost SVar:RemAIDeck:True diff --git a/src/main/java/forge/card/ability/effects/EffectEffect.java b/src/main/java/forge/card/ability/effects/EffectEffect.java index f969bbb00a5..4b79f3507e4 100644 --- a/src/main/java/forge/card/ability/effects/EffectEffect.java +++ b/src/main/java/forge/card/ability/effects/EffectEffect.java @@ -87,7 +87,7 @@ public class EffectEffect extends SpellAbilityEffect { } // Unique Effects shouldn't be duplicated - if (sa.hasParam("Unique") && Singletons.getModel().getGame().isCardInPlay(name)) { + if (sa.hasParam("Unique") && Singletons.getModel().getGame().isCardInCommand(name)) { return; } diff --git a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java index 0035a294aed..7cc043bf92c 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java @@ -65,14 +65,11 @@ import forge.card.trigger.TriggerHandler; import forge.card.trigger.TriggerType; import forge.control.input.InputSelectCards; import forge.control.input.InputSelectCardsFromList; -import forge.game.GameState; -import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCost; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; import forge.game.player.AIPlayer; -import forge.game.player.HumanPlayer; import forge.game.player.Player; import forge.game.zone.PlayerZone; import forge.game.zone.Zone; @@ -2652,10 +2649,7 @@ public class CardFactoryUtil { } if (card.hasKeyword("Epic")) { - final SpellAbility newSA = makeEpic(card); - - card.clearSpellAbility(); - card.addSpellAbility(newSA); + makeEpic(card); } if (card.hasKeyword("Soulbond")) { @@ -2881,58 +2875,26 @@ public class CardFactoryUtil { * @param card * @return */ - private static SpellAbility makeEpic(final Card card) { + private static void makeEpic(final Card card) { + + // Add the Epic effect as a subAbility + String dbStr = "DB$ Effect | Triggers$ EpicTrigger | SVars$ EpicCopy | StaticAbilities$ EpicCantBeCast | Duration$ Permanent | Unique$ True"; + + final AbilitySub newSA = (AbilitySub) AbilityFactory.getAbility(dbStr.toString(), card); + + card.setSVar("EpicCantBeCast", "Mode$ CantBeCast | ValidCard$ Card | Caster$ You | Description$ For the rest of the game, you can't cast spells."); + card.setSVar("EpicTrigger", "Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ EpicCopy | TriggerDescription$ " + + "At the beginning of each of your upkeeps, copy " + card.toString() + " except for its epic ability."); + card.setSVar("EpicCopy", "DB$ CopySpellAbility | Defined$ EffectSource"); + final SpellAbility origSA = card.getSpellAbilities().get(0); - - final SpellAbility newSA = new Spell(card, origSA.getPayCosts(), origSA.getTarget()) { - private static final long serialVersionUID = -7934420043356101045L; - - @Override - public void resolve() { - final GameState game = Singletons.getModel().getGame(); - - String name = card.toString() + " Epic"; - if (card.getController().getCardsIn(ZoneType.Battlefield, name).isEmpty()) { - // Create Epic emblem - final Card eff = new Card(); - eff.setName(card.toString() + " Epic"); - eff.addType("Effect"); // Or Emblem - eff.setToken(true); // Set token to true, so when leaving - // play it gets nuked - eff.setOwner(card.getController()); - eff.setColor(card.getColor()); - eff.setImmutable(true); - eff.setEffectSource(card); - - eff.addStaticAbility("Mode$ CantBeCast | ValidCard$ Card | Caster$ You " - + "| Description$ For the rest of the game, you can't cast spells."); - - eff.setSVar("EpicCopy", "AB$ CopySpellAbility | Cost$ 0 | Defined$ EffectSource"); - - final Trigger copyTrigger = forge.card.trigger.TriggerHandler.parseTrigger( - "Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ EpicCopy | TriggerDescription$ " - + "At the beginning of each of your upkeeps, copy " + card.toString() - + " except for its epic ability.", eff, false); - - eff.addTrigger(copyTrigger); - - game.getTriggerHandler().suppressMode(TriggerType.ChangesZone); - game.getAction().moveToPlay(eff); - game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone); - } - - if (card.getController().isHuman()) { - ((HumanPlayer)card.getController()).playSpellAbilityNoStack(origSA); - } else { - ComputerUtil.playNoStack((AIPlayer) card.getController(), origSA, game); - } - } - }; - newSA.setDescription(origSA.getDescription()); - - origSA.setPayCosts(null); - origSA.setManaCost(ManaCost.ZERO); - return newSA; + + SpellAbility child = origSA; + while (child.getSubAbility() != null) { + child = child.getSubAbility(); + } + child.setSubAbility(newSA); + newSA.setParent(child); } /** diff --git a/src/main/java/forge/game/GameState.java b/src/main/java/forge/game/GameState.java index d7d2ccc2348..971c944a469 100644 --- a/src/main/java/forge/game/GameState.java +++ b/src/main/java/forge/game/GameState.java @@ -24,10 +24,12 @@ import java.util.List; import java.util.Map; import java.util.TreeMap; +import com.google.common.collect.Iterables; import com.google.common.eventbus.EventBus; import forge.Card; import forge.CardLists; +import forge.CardPredicates; import forge.ColorChanger; import forge.GameLog; import forge.Singletons; @@ -362,7 +364,6 @@ public class GameState { return getCardsIn(ZoneType.Exile).contains(c); } - public boolean isCardInPlay(final String cardName) { for (final Player p : getPlayers()) { if (p.isCardInPlay(cardName)) { @@ -372,6 +373,15 @@ public class GameState { return false; } + public boolean isCardInCommand(final String cardName) { + for (final Player p : getPlayers()) { + if (p.isCardInCommand(cardName)) { + return true; + } + } + return false; + } + public List getColoredCardsInPlay(final String color) { final List cards = new ArrayList(); for (Player p : getPlayers()) { diff --git a/src/main/java/forge/game/player/Player.java b/src/main/java/forge/game/player/Player.java index acbe897b877..486890f3940 100644 --- a/src/main/java/forge/game/player/Player.java +++ b/src/main/java/forge/game/player/Player.java @@ -2734,6 +2734,9 @@ public abstract class Player extends GameEntity implements Comparable { return Iterables.any(getZone(ZoneType.Battlefield), CardPredicates.nameEquals(cardName)); } + public boolean isCardInCommand(final String cardName) { + return Iterables.any(getZone(ZoneType.Command), CardPredicates.nameEquals(cardName)); + } public List getColoredCardsInPlay(final String color) { return CardLists.filter(getCardsIn(ZoneType.Battlefield), new Predicate() {