From 18921e954a79407d31ebc7c57485c2081b029d89 Mon Sep 17 00:00:00 2001 From: Adam Pantel <> Date: Tue, 16 Feb 2021 17:42:36 -0500 Subject: [PATCH] Mirrored Lotus --- .../src/main/java/forge/game/card/Card.java | 2 +- .../main/java/forge/game/card/CardFactory.java | 8 ++++++++ .../java/forge/game/card/CardFactoryUtil.java | 17 +++++++++++++++++ .../src/main/java/forge/game/card/CardUtil.java | 2 +- .../main/java/forge/game/keyword/Keyword.java | 1 + forge-gui/res/cardsfolder/m/mirrored_lotus.txt | 6 ++++++ 6 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 forge-gui/res/cardsfolder/m/mirrored_lotus.txt 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 672f1e5de83..b0051a2acd8 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -1884,7 +1884,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { sbLong.append(" (").append(inst.getReminderText()).append(")"); sbLong.append("\r\n"); } - } else if (keyword.startsWith("Emerge")) { + } else if (keyword.startsWith("Emerge") || keyword.startsWith("Reflect")) { final String[] k = keyword.split(":"); sbLong.append(k[0]).append(" ").append(ManaCostParser.parse(k[1])); sbLong.append(" (").append(inst.getReminderText()).append(")"); 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 6a72a976534..d270e7c0bcd 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -565,6 +565,7 @@ public class CardFactory { final Map origSVars = host.getSVars(); final List types = Lists.newArrayList(); final List keywords = Lists.newArrayList(); + final List removeKeywords = Lists.newArrayList(); List creatureTypes = null; final CardCloneStates result = new CardCloneStates(in, sa); @@ -579,6 +580,10 @@ public class CardFactory { keywords.addAll(Arrays.asList(sa.getParam("AddKeywords").split(" & "))); } + if (sa.hasParam("RemoveKeywords")) { + removeKeywords.addAll(Arrays.asList(sa.getParam("RemoveKeywords").split(" & "))); + } + if (sa.hasParam("SetColor")) { shortColors = CardUtil.getShortColorsString(Arrays.asList(sa.getParam("SetColor").split(","))); } @@ -646,6 +651,9 @@ public class CardFactory { } state.addIntrinsicKeywords(keywords); + for (String kw : removeKeywords) { + state.removeIntrinsicKeyword(kw); + } if (sa.hasParam("SetPower")) { state.setBasePower(Integer.parseInt(sa.getParam("SetPower"))); 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 25c1ba72037..0b2d00eef7a 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -3659,6 +3659,23 @@ public class CardFactoryUtil { re.setOverridingAbility(saExile); inst.addReplacement(re); + } else if (keyword.startsWith("Reflect:")) { + final String[] k = keyword.split(":"); + + final String repeatStr = "DB$ RepeatEach | RepeatPlayers$ Opponent"; + final String payStr = "DB$ ImmediateTrigger | RememberObjects$ Player.IsRemembered | TriggerDescription$ Copy CARDNAME | " + + "UnlessPayer$ Player.IsRemembered | UnlessSwitched$ True | UnlessCost$ " + k[1]; + final String copyStr = "DB$ CopyPermanent | Defined$ Self | Controller$ Player.IsRemembered | RemoveKeywords$ Reflect"; + + SpellAbility repeatSA = AbilityFactory.getAbility(repeatStr, card); + AbilitySub paySA = (AbilitySub) AbilityFactory.getAbility(payStr, card); + AbilitySub copySA = (AbilitySub) AbilityFactory.getAbility(copyStr, card); + + repeatSA.setAdditionalAbility("RepeatSubAbility", paySA); + paySA.setAdditionalAbility("Execute", copySA); + + ReplacementEffect cardre = createETBReplacement(card, ReplacementLayer.Other, repeatSA, false, true, intrinsic, "Card.Self", ""); + inst.addReplacement(cardre); } else if (keyword.startsWith("Riot")) { final String choose = "DB$ GenericChoice | AILogic$ Riot | SpellDescription$ Riot"; diff --git a/forge-game/src/main/java/forge/game/card/CardUtil.java b/forge-game/src/main/java/forge/game/card/CardUtil.java index b682a63ffd7..ddd6408bda2 100644 --- a/forge-game/src/main/java/forge/game/card/CardUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardUtil.java @@ -58,7 +58,7 @@ public final class CardUtil { "Fortify", "Transfigure", "Champion", "Evoke", "Prowl", "IfReach", "Reinforce", "Unearth", "Level up", "Miracle", "Overload", "Scavenge", "Encore", "Bestow", "Outlast", "Dash", "Surge", "Emerge", "Hexproof:", - "etbCounter").build(); + "etbCounter", "Reflect").build(); /** List of keyword endings of keywords that could be modified by text changes. */ public static final ImmutableList modifiableKeywordEndings = ImmutableList.builder().add( "walk", "cycling", "offering").build(); diff --git a/forge-game/src/main/java/forge/game/keyword/Keyword.java b/forge-game/src/main/java/forge/game/keyword/Keyword.java index 54219bed08b..3c7103f00e3 100644 --- a/forge-game/src/main/java/forge/game/keyword/Keyword.java +++ b/forge-game/src/main/java/forge/game/keyword/Keyword.java @@ -120,6 +120,7 @@ public enum Keyword { REACH("Reach", SimpleKeyword.class, true, "This creature can block creatures with flying."), REBOUND("Rebound", SimpleKeyword.class, true, "If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost."), RECOVER("Recover", KeywordWithCost.class, false, "When a creature is put into your graveyard from the battlefield, you may pay %s. If you do, return this card from your graveyard to your hand. Otherwise, exile this card."), + REFLECT("Reflect", KeywordWithCost.class, false, "As this enters the battlefield, each opponent may pay %s. When they do, they create a token copy of this except it lacks this ability."), REINFORCE("Reinforce", KeywordWithCostAndAmount.class, false, "%s, Discard this card: Put {%d:+1/+1 counter} on target creature."), RENOWN("Renown", KeywordWithAmount.class, false, "When this creature deals combat damage to a player, if it isn't renowned, put {%d:+1/+1 counter} on it and it becomes renowned."), REPLICATE("Replicate", KeywordWithCost.class, false, "As an additional cost to cast this spell, you may pay %s any number of times. If you do, copy it that many times. You may choose new targets for the copies."), diff --git a/forge-gui/res/cardsfolder/m/mirrored_lotus.txt b/forge-gui/res/cardsfolder/m/mirrored_lotus.txt new file mode 100644 index 00000000000..04c03f9db83 --- /dev/null +++ b/forge-gui/res/cardsfolder/m/mirrored_lotus.txt @@ -0,0 +1,6 @@ +Name:Mirrored Lotus +ManaCost:0 +Types:Artifact +K:Reflect:0 +A:AB$ Mana | Cost$ T Exile<1/CARDNAME> | Produced$ Any | Amount$ 3 | AILogic$ BlackLotus | SpellDescription$ Add three mana of any one color. +Oracle:Reflect {0} (As this enters the battlefield, each opponent may pay {0}. When they do, they create a token copy of this except it lacks this ability.)\n{T}, Exile Mirrored Lotus: Add three mana of any one color.