From f9f2b65e45867eec4d7fd0b71263505f540292af Mon Sep 17 00:00:00 2001 From: swordshine Date: Fri, 26 Jun 2020 13:42:14 +0800 Subject: [PATCH 1/3] Add Sanctuary Blade --- .../src/main/java/forge/game/card/Card.java | 5 ++ .../game/replacement/ReplaceAttached.java | 51 +++++++++++++++++++ .../game/replacement/ReplacementType.java | 1 + .../res/cardsfolder/s/sanctuary_blade.txt | 8 +++ 4 files changed, 65 insertions(+) create mode 100644 forge-game/src/main/java/forge/game/replacement/ReplaceAttached.java create mode 100644 forge-gui/res/cardsfolder/s/sanctuary_blade.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 03247423175..d5b8815ecf1 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -3019,6 +3019,11 @@ public class Card extends GameEntity implements Comparable { // Play the Equip sound getGame().fireEvent(new GameEventCardAttachment(this, oldTarget, entity)); + // Run replacement effects + final Map repParams = AbilityKey.mapFromAffected(this); + repParams.put(AbilityKey.AttachTarget, entity); + getGame().getReplacementHandler().run(ReplacementType.Attached, repParams); + // run trigger final Map runParams = AbilityKey.newMap(); runParams.put(AbilityKey.AttachSource, this); diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceAttached.java b/forge-game/src/main/java/forge/game/replacement/ReplaceAttached.java new file mode 100644 index 00000000000..6bdf445fbed --- /dev/null +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceAttached.java @@ -0,0 +1,51 @@ +package forge.game.replacement; + +import forge.game.ability.AbilityKey; +import forge.game.card.Card; +import forge.game.spellability.SpellAbility; + +import java.util.Map; + +/** + * TODO: Write javadoc for this type. + * + */ +public class ReplaceAttached extends ReplacementEffect { + + /** + * + * TODO: Write javadoc for Constructor. + * @param mapParams   HashMap + * @param host   Card + */ + public ReplaceAttached(final Map mapParams, final Card host, final boolean intrinsic) { + super(mapParams, host, intrinsic); + } + + /* (non-Javadoc) + * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap) + */ + @Override + public boolean canReplace(Map runParams) { + if (hasParam("ValidCard")) { + if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), this.getHostCard())) { + return false; + } + } + if (hasParam("ValidTarget")) { + if (!matchesValid(runParams.get(AbilityKey.AttachTarget), getParam("ValidTarget").split(","), this.getHostCard())) { + return false; + } + } + return true; + } + + /* (non-Javadoc) + * @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility) + */ + @Override + public void setReplacingObjects(Map runParams, SpellAbility sa) { + sa.setReplacingObject(AbilityKey.Card, runParams.get(AbilityKey.Affected)); + } + +} diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementType.java b/forge-game/src/main/java/forge/game/replacement/ReplacementType.java index 5fbcce04d8a..c13b3f172d0 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementType.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementType.java @@ -12,6 +12,7 @@ import java.util.Map; */ public enum ReplacementType { AddCounter(ReplaceAddCounter.class), + Attached(ReplaceAttached.class), Counter(ReplaceCounter.class), CreateToken(ReplaceToken.class), DamageDone(ReplaceDamage.class), diff --git a/forge-gui/res/cardsfolder/s/sanctuary_blade.txt b/forge-gui/res/cardsfolder/s/sanctuary_blade.txt new file mode 100644 index 00000000000..064157f8b3d --- /dev/null +++ b/forge-gui/res/cardsfolder/s/sanctuary_blade.txt @@ -0,0 +1,8 @@ +Name:Sanctuary Blade +ManaCost:2 +Types:Artifact Equipment +R:Event$ Attached | ValidCard$ Card.Self | ValidTarget$ Creature | ReplaceWith$ ChooseColor | ActiveZones$ Battlefield | Description$ As CARDNAME becomes attached to a creature, choose a color. +SVar:ChooseColor:DB$ ChooseColor | Defined$ You +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 2 | AddKeyword$ Protection:Card.ChosenColor:Protection from ChosenColor | Description$ Equipped creature gets +2/+0 and has protection from the last chosen color. +K:Equip:3 +Oracle:As Sanctuary Blade becomes attached to a creature, choose a color.\nEquipped creature gets +2/+0 and has protection from the last chosen color.\nEquip {3} From 5fc1f923097e83ab111c04a1636699e9e856dac7 Mon Sep 17 00:00:00 2001 From: swordshine Date: Fri, 26 Jun 2020 14:39:51 +0800 Subject: [PATCH 2/3] Update Charmed Pendant to be compatible with ChangeText effects --- .../java/forge/game/ability/AbilityUtils.java | 2 ++ .../game/ability/effects/ManaEffect.java | 20 +++++++++++++++++++ .../res/cardsfolder/c/charmed_pendant.txt | 11 +--------- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index 331a181c550..239175f7a3d 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -286,6 +286,8 @@ public class AbilityUtils { list = sa.getRootAbility().getPaidList("ExiledCards"); } else if (defined.startsWith("Exiled")) { list = sa.getRootAbility().getPaidList("Exiled"); + } else if (defined.startsWith("Milled")) { + list = sa.getRootAbility().getPaidList("Milled"); } else if (defined.startsWith("TappedCards")) { list = sa.getRootAbility().getPaidList("TappedCards"); } else if (defined.startsWith("Tapped")) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java index b55bcc90385..8558f46272b 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java @@ -195,6 +195,26 @@ public class ManaEffect extends SpellAbilityEffect { } if (colors == 0) return; abMana.setExpressChoice(ColorSet.fromMask(colors)); + } else if (type.startsWith("EachColoredManaSymbol")) { + final String res = type.split("_")[1]; + final CardCollection list = AbilityUtils.getDefinedCards(card, res, sa); + StringBuilder sb = new StringBuilder(); + for (Card c : list) { + String mana = c.getManaCost().toString(); + for (int i = 0; i < mana.length(); i++) { + char symbol = mana.charAt(i); + switch (symbol) { + case 'W': + case 'U': + case 'B': + case 'R': + case 'G': + sb.append(symbol).append(' '); + break; + } + } + } + abMana.setExpressChoice(sb.toString().trim()); } if (abMana.getExpressChoice().isEmpty()) { diff --git a/forge-gui/res/cardsfolder/c/charmed_pendant.txt b/forge-gui/res/cardsfolder/c/charmed_pendant.txt index 96a96485ba6..062c963d7a8 100644 --- a/forge-gui/res/cardsfolder/c/charmed_pendant.txt +++ b/forge-gui/res/cardsfolder/c/charmed_pendant.txt @@ -1,14 +1,5 @@ Name:Charmed Pendant ManaCost:4 Types:Artifact -A:AB$ Mana | Cost$ T Mill<1> | Produced$ W | Amount$ ManaW | References$ ManaW | InstantSpeed$ True | SubAbility$ DBManaU | SpellDescription$ For each colored mana symbol in the milled card's mana cost, add one mana of that color. Activate this ability only any time you could cast an instant. -SVar:DBManaU:DB$ Mana | Produced$ U | Amount$ ManaU | References$ ManaU | SubAbility$ DBManaB -SVar:DBManaB:DB$ Mana | Produced$ B | Amount$ ManaB | References$ ManaB | SubAbility$ DBManaR -SVar:DBManaR:DB$ Mana | Produced$ R | Amount$ ManaR | References$ ManaR | SubAbility$ DBManaG -SVar:DBManaG:DB$ Mana | Produced$ G | Amount$ ManaG | References$ ManaG -SVar:ManaW:Milled$ChromaSource.W -SVar:ManaU:Milled$ChromaSource.U -SVar:ManaB:Milled$ChromaSource.B -SVar:ManaR:Milled$ChromaSource.R -SVar:ManaG:Milled$ChromaSource.G +A:AB$ Mana | Cost$ T Mill<1> | Produced$ Special EachColoredManaSymbol_Milled | InstantSpeed$ True | SpellDescription$ For each colored mana symbol in the milled card's mana cost, add one mana of that color. Activate this ability only any time you could cast an instant. Oracle:{T}, Mill a card: For each colored mana symbol in the milled card's mana cost, add one mana of that color. Activate this ability only any time you could cast an instant. From 01183c454b69d3c757a400dd27c01ed142af75f8 Mon Sep 17 00:00:00 2001 From: swordshine Date: Fri, 26 Jun 2020 16:46:14 +0800 Subject: [PATCH 3/3] Update ReplacementMill --- .../main/java/forge/game/player/Player.java | 29 ++++++++++--------- .../forge/game/replacement/ReplaceMill.java | 5 ---- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index 80007185ec7..eca33a3afec 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -1670,21 +1670,22 @@ public class Player extends GameEntity implements Comparable { // Replacement effects final Map repRunParams = AbilityKey.mapFromAffected(this); repRunParams.put(AbilityKey.Number, n); - repRunParams.put(AbilityKey.Destination, destination); - - switch (getGame().getReplacementHandler().run(ReplacementType.Mill, repRunParams)) { - case NotReplaced: - break; - case Updated: - // check if this is still the affected player - if (this.equals(repRunParams.get(AbilityKey.Affected))) { - n = (int) repRunParams.get(AbilityKey.Number); - } else { - return milled; + + if (destination == ZoneType.Graveyard && !bottom) { + switch (getGame().getReplacementHandler().run(ReplacementType.Mill, repRunParams)) { + case NotReplaced: + break; + case Updated: + // check if this is still the affected player + if (this.equals(repRunParams.get(AbilityKey.Affected))) { + n = (int) repRunParams.get(AbilityKey.Number); + } else { + return milled; + } + break; + default: + return milled; } - break; - default: - return milled; } final int max = Math.min(n, lib.size()); diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceMill.java b/forge-game/src/main/java/forge/game/replacement/ReplaceMill.java index 608081f6204..e2aa8cf2009 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceMill.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceMill.java @@ -20,8 +20,6 @@ package forge.game.replacement; import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.spellability.SpellAbility; -import forge.game.zone.ZoneType; - import java.util.Map; /** @@ -46,9 +44,6 @@ public class ReplaceMill extends ReplacementEffect { @Override public boolean canReplace(Map runParams) { - if (ZoneType.Graveyard != ((ZoneType) runParams.get(AbilityKey.Destination))) { - return false; - } if (hasParam("ValidPlayer")) { if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), getHostCard())) { return false;