diff --git a/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java b/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java index 0334decc633..1664188ede4 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java @@ -72,7 +72,7 @@ public class CopyPermanentAi extends SpellAbilityAi { } } - if (sa.hasParam("Embalm") || sa.hasParam("Eternalize")) { + if (sa.isEmbalm() || sa.isEternalize()) { // E.g. Vizier of Many Faces: check to make sure it makes sense to make the token now if (ComputerUtilCard.checkNeedsToPlayReqs(sa.getHostCard(), sa) != AiPlayDecision.WillPlay) { return false; diff --git a/forge-game/src/main/java/forge/game/CardTraitBase.java b/forge-game/src/main/java/forge/game/CardTraitBase.java index c5070d29e54..b69cc37e362 100644 --- a/forge-game/src/main/java/forge/game/CardTraitBase.java +++ b/forge-game/src/main/java/forge/game/CardTraitBase.java @@ -156,6 +156,13 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView, this.keyword = kw; } + public boolean isEmbalm() { + return isKeyword(Keyword.EMBALM); + } + public boolean isEternalize() { + return isKeyword(Keyword.ETERNALIZE); + } + /** *

* isSecondary. diff --git a/forge-game/src/main/java/forge/game/ForgeScript.java b/forge-game/src/main/java/forge/game/ForgeScript.java index 72e977fce8f..689e0c2fff2 100644 --- a/forge-game/src/main/java/forge/game/ForgeScript.java +++ b/forge-game/src/main/java/forge/game/ForgeScript.java @@ -225,6 +225,10 @@ public class ForgeScript { return sa.isDash(); } else if (property.equals("Disturb")) { return sa.isDisturb(); + } else if (property.equals("Embalm")) { + return sa.isEmbalm(); + } else if (property.equals("Eternalize")) { + return sa.isEternalize(); } else if (property.equals("Flashback")) { return sa.isFlashback(); } else if (property.equals("Jumpstart")) { diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index c058bf58d39..fb880a8cb0b 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -6303,12 +6303,12 @@ public class Card extends GameEntity implements Comparable, IHasSVars { public final boolean isEmbalmed() { SpellAbility sa = getTokenSpawningAbility(); - return sa != null && sa.hasParam("Embalm"); + return sa != null && sa.isEmbalm(); } public final boolean isEternalized() { SpellAbility sa = getTokenSpawningAbility(); - return sa != null && sa.hasParam("Eternalize"); + return sa != null && sa.isEternalize(); } public final int getExertedThisTurn() { diff --git a/forge-game/src/main/java/forge/game/card/CardFactory.java b/forge-game/src/main/java/forge/game/card/CardFactory.java index cc5e9275ede..d9f9fbb7e5d 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -571,6 +571,12 @@ public class CardFactory { for (Map.Entry e : result.entrySet()) { final CardState originalState = out.getState(e.getKey()); final CardState state = e.getValue(); + + // has Embalm Condition for extra changes of Vizier of Many Faces + if (sa.hasParam("Embalm") && !out.isEmbalmed()) { + continue; + } + // update the names for the states if (sa.hasParam("KeepName")) { state.setName(originalState.getName()); @@ -638,7 +644,6 @@ public class CardFactory { state.setBaseLoyalty(String.valueOf(AbilityUtils.calculateAmount(host, sa.getParam("SetLoyalty"), sa))); } - // Planning a Vizier of Many Faces rework; always might come in handy if (sa.hasParam("RemoveCost")) { state.setManaCost(ManaCost.NO_COST); } @@ -706,34 +711,20 @@ public class CardFactory { } // Special Rules for Embalm and Eternalize - if (sa.hasParam("Embalm") && out.isEmbalmed()) { - state.addType("Zombie"); - state.setColor(MagicColor.WHITE); - state.setManaCost(ManaCost.NO_COST); - - if (sa.isIntrinsic()) { - String name = TextUtil.fastReplace( - TextUtil.fastReplace(host.getName(), ",", ""), - " ", "_").toLowerCase(); - String set = host.getSetCode().toLowerCase(); - state.setImageKey(ImageKeys.getTokenKey("embalm_" + name + "_" + set)); - } + if (sa.isEmbalm() && sa.isIntrinsic()) { + String name = TextUtil.fastReplace( + TextUtil.fastReplace(host.getName(), ",", ""), + " ", "_").toLowerCase(); + String set = host.getSetCode().toLowerCase(); + state.setImageKey(ImageKeys.getTokenKey("embalm_" + name + "_" + set)); } - if (sa.hasParam("Eternalize") && out.isEternalized()) { - state.addType("Zombie"); - state.setColor(MagicColor.BLACK); - state.setManaCost(ManaCost.NO_COST); - state.setBasePower(4); - state.setBaseToughness(4); - - if (sa.isIntrinsic()) { - String name = TextUtil.fastReplace( - TextUtil.fastReplace(host.getName(), ",", ""), - " ", "_").toLowerCase(); - String set = host.getSetCode().toLowerCase(); - state.setImageKey(ImageKeys.getTokenKey("eternalize_" + name + "_" + set)); - } + if (sa.isEternalize() && sa.isIntrinsic()) { + String name = TextUtil.fastReplace( + TextUtil.fastReplace(host.getName(), ",", ""), + " ", "_").toLowerCase(); + String set = host.getSetCode().toLowerCase(); + state.setImageKey(ImageKeys.getTokenKey("eternalize_" + name + "_" + set)); } if (sa.hasParam("GainTextOf") && originalState != null) { @@ -748,35 +739,28 @@ public class CardFactory { continue; } - if (sa.hasParam("SetPower") || sa.hasParam("Eternalize")) { - if (sta.hasParam("SetPower")) - state.removeStaticAbility(sta); + if (sa.hasParam("SetPower") && sta.hasParam("SetPower")) + state.removeStaticAbility(sta); + + if (sa.hasParam("SetToughness") && sta.hasParam("SetToughness")) + state.removeStaticAbility(sta); + + // currently only Changeling and similar should be affected by that + // other cards using AddType$ ChosenType should not + if (sa.hasParam("SetCreatureTypes") && sta.hasParam("AddAllCreatureTypes")) { + state.removeStaticAbility(sta); } - if (sa.hasParam("SetToughness") || sa.hasParam("Eternalize")) { - if (sta.hasParam("SetToughness")) - state.removeStaticAbility(sta); - } - if (sa.hasParam("SetCreatureTypes")) { - // currently only Changeling and similar should be affected by that - // other cards using AddType$ ChosenType should not - if (sta.hasParam("AddAllCreatureTypes")) { - state.removeStaticAbility(sta); - } - } - if (sa.hasParam("SetColor") || sa.hasParam("Embalm") || sa.hasParam("Eternalize")) { - if (sta.hasParam("SetColor")) { - state.removeStaticAbility(sta); - } + if ((sa.hasParam("SetColor") || sa.hasParam("SetColorByManaCost")) && sta.hasParam("SetColor")) { + state.removeStaticAbility(sta); } } // remove some keywords if (sa.hasParam("SetCreatureTypes")) { - state.removeIntrinsicKeyword("Changeling"); + state.removeIntrinsicKeyword(Keyword.CHANGELING); } - if (sa.hasParam("SetColor") || sa.hasParam("Embalm") || sa.hasParam("Eternalize") - || sa.hasParam("SetColorByManaCost")) { - state.removeIntrinsicKeyword("Devoid"); + if (sa.hasParam("SetColor") || sa.hasParam("SetColorByManaCost")) { + state.removeIntrinsicKeyword(Keyword.DEVOID); } } return result; diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 8dfcf682885..c6bef1a4494 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -2832,7 +2832,8 @@ public class CardFactoryUtil { String costStr = kw[1]; String effect = "AB$ CopyPermanent | Cost$ " + costStr + " ExileFromGrave<1/CARDNAME> " + - "| ActivationZone$ Graveyard | SorcerySpeed$ True | Embalm$ True " + + "| ActivationZone$ Graveyard | SorcerySpeed$ True " + + "| RemoveCost$ True | SetColor$ White | AddTypes$ Zombie" + "| PrecostDesc$ Embalm | CostDesc$ " + ManaCostParser.parse(costStr) + " | Defined$ Self " + "| StackDescription$ Embalm - CARDNAME "+ "| SpellDescription$ (" + inst.getReminderText() + ")" ; @@ -2968,7 +2969,8 @@ public class CardFactoryUtil { StringBuilder sb = new StringBuilder(); sb.append("AB$ CopyPermanent | Cost$ ").append(costStr).append(" ExileFromGrave<1/CARDNAME>") - .append(" | Defined$ Self | ActivationZone$ Graveyard | SorcerySpeed$ True | Eternalize$ True"); + .append(" | Defined$ Self | ActivationZone$ Graveyard | SorcerySpeed$ True") + .append(" | RemoveCost$ True | SetColor$ Black | AddTypes$ Zombie | SetPower$ 4 | SetToughness$ 4"); sb.append(" | PrecostDesc$ Eternalize"); if (!cost.isOnlyManaCost()) { //Something other than a mana cost @@ -2976,7 +2978,7 @@ public class CardFactoryUtil { } else { sb.append(" "); } - // don't use SimpleString there because it does has "and" between cost i dont want that + // don't use SimpleString there because it does has "and" between cost i don't want that costStr = cost.toString(); // but now it has ": " at the end i want to remove sb.append("| CostDesc$ ").append(costStr, 0, costStr.length() - 2); diff --git a/forge-game/src/main/java/forge/game/card/CardState.java b/forge-game/src/main/java/forge/game/card/CardState.java index 8d5a9b62d8b..0b865aad0ba 100644 --- a/forge-game/src/main/java/forge/game/card/CardState.java +++ b/forge-game/src/main/java/forge/game/card/CardState.java @@ -312,6 +312,9 @@ public class CardState extends GameObject implements IHasSVars { public final boolean removeIntrinsicKeyword(final KeywordInterface s) { return intrinsicKeywords.remove(s); } + public final boolean removeIntrinsicKeyword(final Keyword k) { + return intrinsicKeywords.removeAll(k); + } public final FCollectionView getSpellAbilities() { FCollection newCol = new FCollection<>(manaAbilities); diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerSpellAbilityCastOrCopy.java b/forge-game/src/main/java/forge/game/trigger/TriggerSpellAbilityCastOrCopy.java index b192005507f..06205ae5454 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerSpellAbilityCastOrCopy.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerSpellAbilityCastOrCopy.java @@ -190,12 +190,6 @@ public class TriggerSpellAbilityCastOrCopy extends Trigger { } } - if (hasParam("EternalizeOrEmbalm")) { - if (!spellAbility.hasParam("Eternalize") && !spellAbility.hasParam("Embalm")) { - return false; - } - } - // use numTargets instead? if (hasParam("IsSingleTarget")) { Set targets = Sets.newHashSet(); diff --git a/forge-gui/res/cardsfolder/v/vizier_of_many_faces.txt b/forge-gui/res/cardsfolder/v/vizier_of_many_faces.txt index 43d2a8b03be..ad3810780c0 100644 --- a/forge-gui/res/cardsfolder/v/vizier_of_many_faces.txt +++ b/forge-gui/res/cardsfolder/v/vizier_of_many_faces.txt @@ -3,7 +3,7 @@ ManaCost:2 U U Types:Creature Shapeshifter Cleric PT:0/0 K:ETBReplacement:Copy:DBCopy:Optional -SVar:DBCopy:DB$ Clone | Choices$ Creature.Other | Embalm$ True | SpellDescription$ You may have CARDNAME enter the battlefield as a copy of any creature on the battlefield, except if CARDNAME was embalmed, the token has no mana cost, it's white, and it's a Zombie in addition to its other types. +SVar:DBCopy:DB$ Clone | Choices$ Creature.Other | Embalm$ True | RemoveCost$ True | SetColor$ White | AddTypes$ Zombie | SpellDescription$ You may have CARDNAME enter the battlefield as a copy of any creature on the battlefield, except if CARDNAME was embalmed, the token has no mana cost, it's white, and it's a Zombie in addition to its other types. K:Embalm:3 U U SVar:NeedsToPlay:Creature DeckHas:Ability$Token diff --git a/forge-gui/res/cardsfolder/v/vizier_of_the_anointed.txt b/forge-gui/res/cardsfolder/v/vizier_of_the_anointed.txt index a2f576bbe9c..bed96e0ea26 100644 --- a/forge-gui/res/cardsfolder/v/vizier_of_the_anointed.txt +++ b/forge-gui/res/cardsfolder/v/vizier_of_the_anointed.txt @@ -4,7 +4,7 @@ Types:Creature Human Cleric PT:2/4 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ VizierSearch | TriggerDescription$ When CARDNAME enters the battlefield, you may search your library for a creature card with eternalize or embalm, put that card into your graveyard, then shuffle. SVar:VizierSearch:DB$ ChangeZone | Origin$ Library | Destination$ Graveyard | ChangeNum$ 1 | ChangeType$ Creature.withEmbalm+YouCtrl,Creature.withEternalize+YouCtrl -T:Mode$ AbilityCast | ValidCard$ Creature.YouOwn | ValidActivatingPlayer$ You | EternalizeOrEmbalm$ True | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever you activate an eternalize or embalm ability, draw a card. +T:Mode$ AbilityCast | ValidCard$ Creature.YouOwn | ValidActivatingPlayer$ You | ValidSA$ Activated.Eternalize,Activated.Embalm | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever you activate an eternalize or embalm ability, draw a card. SVar:TrigDraw:DB$ Draw | NumCards$ 1 AI:RemoveDeck:Random DeckNeeds:Keyword$Eternalize|Embalm