From 411edf61765e661f1b357d0b7bbe05cfc6969b67 Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Sun, 31 May 2026 10:59:16 +0200 Subject: [PATCH] Fix Veil of Summer --- .../src/main/java/forge/game/card/Card.java | 23 +------- .../java/forge/game/card/CardFactoryUtil.java | 50 +---------------- .../java/forge/game/keyword/Protection.java | 54 +++++++++++++++---- .../main/java/forge/game/player/Player.java | 28 ++-------- .../forge/game/player/PlayerFactoryUtil.java | 23 ++++---- 5 files changed, 61 insertions(+), 117 deletions(-) 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 38fdb861402..20fcf3f35bf 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -1331,12 +1331,6 @@ public final void addUntilLeavesBattlefield(final Iterable cards) { public final void removeUntilLeavesBattlefield(final Card c) { untilLeavesBattlefield = view.removeCard(untilLeavesBattlefield, c, TrackableProperty.UntilLeavesBattlefield); } - public final void removeUntilLeavesBattlefield(final Iterable cards) { - untilLeavesBattlefield = view.removeCards(untilLeavesBattlefield, cards, TrackableProperty.UntilLeavesBattlefield); - } - public final void clearUntilLeavesBattlefield() { - untilLeavesBattlefield = view.clearCards(untilLeavesBattlefield, TrackableProperty.UntilLeavesBattlefield); - } public final CardCollectionView getExiledCards() { return CardCollection.getView(exiledCards); @@ -1356,12 +1350,6 @@ public final void addExiledCards(final Iterable cards) { public final void removeExiledCard(final Card c) { exiledCards = view.removeCard(exiledCards, c, TrackableProperty.ExiledCards); } - public final void removeExiledCards(final Iterable cards) { - exiledCards = view.removeCards(exiledCards, cards, TrackableProperty.ExiledCards); - } - public final void clearExiledCards() { - exiledCards = view.clearCards(exiledCards, TrackableProperty.ExiledCards); - } public final CardCollectionView getHauntedBy() { return CardCollection.getView(hauntedBy); @@ -2561,17 +2549,10 @@ private String keywordsToText(final Collection keywords) { sbLong.append("\r\n"); } else if (keyword.startsWith("Protection:")) { final String[] k = keyword.split(":"); - sbLong.append("Protection from "); if (k.length > 2) { - sbLong.append(k[2]); + sbLong.append("Protection from ").append(k[2]); } else { - if (MagicColor.Constant.ONLY_COLORS.contains(k[1])) { - // lower-case color - sbLong.append(k[1]); - } else { - // plural card types - sbLong.append(CardType.getPluralType(k[1])); - } + sbLong.append(inst.getTitle()); } sbLong.append("\r\n"); } else if (inst.getKeyword().equals(Keyword.COMPANION)) { 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 657d66f36ba..212067e4b62 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -541,52 +541,6 @@ private static ReplacementEffect createETBReplacement(final CardState card, Repl return re; } - public static String getProtectionValid(final String kw, final boolean damage) { - String validSource = ""; - - if (kw.startsWith("Protection:")) { - final String[] kws = kw.split(":"); - String characteristic = kws[1]; - if (characteristic.startsWith("Player")) { - validSource = "ControlledBy " + characteristic; - } else { - if (damage && (characteristic.endsWith("White") || characteristic.endsWith("Blue") - || characteristic.endsWith("Black") || characteristic.endsWith("Red") - || characteristic.endsWith("Green") || characteristic.endsWith("Colorless") - || characteristic.endsWith("MonoColor") || characteristic.endsWith("MultiColor") - || characteristic.endsWith("EnemyColor"))) { - characteristic += "Source"; - } - return characteristic; - } - } else if (kw.startsWith("Protection from ")) { - String protectType = kw.substring("Protection from ".length()); - if (protectType.equals("white")) { - validSource = "White" + (damage ? "Source" : ""); - } else if (protectType.equals("blue")) { - validSource = "Blue" + (damage ? "Source" : ""); - } else if (protectType.equals("black")) { - validSource = "Black" + (damage ? "Source" : ""); - } else if (protectType.equals("red")) { - validSource = "Red" + (damage ? "Source" : ""); - } else if (protectType.equals("green")) { - validSource = "Green" + (damage ? "Source" : ""); - } else if (protectType.equals("colorless")) { - validSource = "Colorless" + (damage ? "Source" : ""); - } else if (protectType.equals("each color")) { - validSource = "nonColorless" + (damage ? "Source" : ""); - } else if (protectType.equals("everything")) { - return ""; - } else { - throw new RuntimeException("unknown protection keyword: " + kw); - } - } - if (validSource.isEmpty()) { - return validSource; - } - return "Card." + validSource + ",Emblem." + validSource; - } - public static ReplacementEffect makeEtbCounter(final String kw, final CardState card, final boolean intrinsic) { String parse = kw; @@ -2590,7 +2544,7 @@ public static void addReplacementEffect(final KeywordInterface inst, final CardS } } else if (keyword.startsWith("Protection")) { - String validSource = getProtectionValid(keyword, true); + String validSource = Protection.getProtectionValid(keyword, true); String rep = "Event$ DamageDone | Prevent$ True | ActiveZones$ Battlefield | ValidTarget$ Card.Self"; if (!validSource.isEmpty()) { @@ -3964,7 +3918,7 @@ public static void addStaticAbility(final KeywordInterface inst, final CardState String effect = "Mode$ CantTransform | ValidCard$ Creature.Self | ExceptCause$ SpellAbility.Nightbound | Secondary$ True | Description$ This permanent can't be transformed except by its nightbound ability."; inst.addStaticAbility(StaticAbility.create(effect, state.getCard(), state, intrinsic)); } else if (keyword.startsWith("Protection")) { - String valid = getProtectionValid(keyword, false); + String valid = Protection.getProtectionValid(keyword, false); // Block String effect = "Mode$ CantBlockBy | ValidAttacker$ Creature.Self | Secondary$ True "; diff --git a/forge-game/src/main/java/forge/game/keyword/Protection.java b/forge-game/src/main/java/forge/game/keyword/Protection.java index cad79097fdd..795578b9498 100644 --- a/forge-game/src/main/java/forge/game/keyword/Protection.java +++ b/forge-game/src/main/java/forge/game/keyword/Protection.java @@ -1,19 +1,55 @@ package forge.game.keyword; -public class Protection extends KeywordInstance { - private String fromWhat = ""; +public class Protection extends KeywordWithType { @Override public String getTitle() { - return "Protection from " + fromWhat; + return "Protection from " + getTypeDescription(); } - @Override - protected void parse(String details) { - } + public static String getProtectionValid(final String kw, final boolean damage) { + String validSource = ""; - @Override - protected String formatReminderText(String reminderText) { - return String.format(reminderText, fromWhat); + if (kw.startsWith("Protection:")) { + final String[] kws = kw.split(":"); + String characteristic = kws[1]; + if (characteristic.startsWith("Player")) { + validSource = "ControlledBy " + characteristic; + } else { + if (damage && (characteristic.endsWith("White") || characteristic.endsWith("Blue") + || characteristic.endsWith("Black") || characteristic.endsWith("Red") + || characteristic.endsWith("Green") || characteristic.endsWith("Colorless") + || characteristic.endsWith("MonoColor") || characteristic.endsWith("MultiColor") + || characteristic.endsWith("EnemyColor"))) { + characteristic += "Source"; + } + return characteristic; + } + } else if (kw.startsWith("Protection from ")) { + String protectType = kw.substring("Protection from ".length()); + if (protectType.equals("white")) { + validSource = "White" + (damage ? "Source" : ""); + } else if (protectType.equals("blue")) { + validSource = "Blue" + (damage ? "Source" : ""); + } else if (protectType.equals("black")) { + validSource = "Black" + (damage ? "Source" : ""); + } else if (protectType.equals("red")) { + validSource = "Red" + (damage ? "Source" : ""); + } else if (protectType.equals("green")) { + validSource = "Green" + (damage ? "Source" : ""); + } else if (protectType.equals("colorless")) { + validSource = "Colorless" + (damage ? "Source" : ""); + } else if (protectType.equals("each color")) { + validSource = "nonColorless" + (damage ? "Source" : ""); + } else if (protectType.equals("everything")) { + return ""; + } else { + throw new RuntimeException("unknown protection keyword: " + kw); + } + } + if (validSource.isEmpty()) { + return validSource; + } + return "Card." + validSource + ",Emblem." + validSource; } } 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 a7858c48009..8283cfbc107 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -3608,37 +3608,15 @@ public void updateKeywordCardAbilityText() { headerAdded = true; kw.append(this.getName()).append(" has: \n"); } - kw.append(k).append("\n"); + kw.append(k.getTitle()).append("\n"); } if (!kw.toString().isEmpty()) { - keywordEffect.setText(trimKeywords(kw.toString())); + keywordEffect.setText(kw.toString()); } keywordEffect.updateAbilityTextForView(); this.updateZoneForView(com); } - public String trimKeywords(String keywordTexts) { - if (keywordTexts.contains("Protection:")) { - List lines = Arrays.asList(keywordTexts.split("\n")); - for (String line : lines) { - if (line.startsWith("Protection:")) { - List parts = Arrays.asList(line.split(":")); - if (parts.size() > 2) { - keywordTexts = TextUtil.fastReplace(keywordTexts, line, parts.get(2)); - } - } - } - } - keywordTexts = TextUtil.fastReplace(keywordTexts,":Card.named", " from "); - keywordTexts = TextUtil.fastReplace(keywordTexts, ":Card.Black:", " from "); - keywordTexts = TextUtil.fastReplace(keywordTexts, ":Card.Blue:", " from "); - keywordTexts = TextUtil.fastReplace(keywordTexts, ":Card.Red:", " from "); - keywordTexts = TextUtil.fastReplace(keywordTexts, ":Card.Green:", " from "); - keywordTexts = TextUtil.fastReplace(keywordTexts, ":Card.White:", " from "); - keywordTexts = TextUtil.fastReplace(keywordTexts, ":Card.MonoColor:", " from "); - keywordTexts = TextUtil.fastReplace(keywordTexts, ":Card.MultiColor:", " from "); - keywordTexts = TextUtil.fastReplace(keywordTexts, ":Card.Colorless:", " from "); - return keywordTexts; - } + public void checkKeywordCard() { if (keywordEffect == null) return; diff --git a/forge-game/src/main/java/forge/game/player/PlayerFactoryUtil.java b/forge-game/src/main/java/forge/game/player/PlayerFactoryUtil.java index 34933815924..79777b6b9d9 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/player/PlayerFactoryUtil.java @@ -1,8 +1,9 @@ package forge.game.player; import forge.game.card.Card; -import forge.game.card.CardFactoryUtil; +import forge.game.keyword.Hexproof; import forge.game.keyword.KeywordInterface; +import forge.game.keyword.Protection; import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementHandler; import forge.game.staticability.StaticAbility; @@ -12,20 +13,14 @@ public class PlayerFactoryUtil { public static void addStaticAbility(final KeywordInterface inst, final Player player) { String keyword = inst.getOriginal(); - if (keyword.startsWith("Hexproof")) { - final StringBuilder sbDesc = new StringBuilder("Hexproof"); + if (keyword.startsWith("Hexproof") && inst instanceof Hexproof hexproof) { final StringBuilder sbValid = new StringBuilder(); - - if (!keyword.equals("Hexproof")) { - final String[] k = keyword.split(":"); - - sbDesc.append(" from ").append(k[2]); - sbValid.append("| ValidSource$ ").append(k[1]); + if (!hexproof.getValidType().isEmpty()) { + sbValid.append("| ValidSource$ ").append(hexproof.getValidType()); } - String effect = "Mode$ CantTarget | ValidTarget$ Player.You | Secondary$ True " - + sbValid.toString() + " | Activator$ Opponent | EffectZone$ Command | Description$ " - + sbDesc.toString() + " (" + inst.getReminderText() + ")"; + + sbValid + " | Activator$ Opponent | EffectZone$ Command | Description$ " + + inst.getTitle() + " (" + inst.getReminderText() + ")"; final Card card = player.getKeywordCard(); inst.addStaticAbility(StaticAbility.create(effect, card, card.getCurrentState(), false)); @@ -36,7 +31,7 @@ public static void addStaticAbility(final KeywordInterface inst, final Player pl final Card card = player.getKeywordCard(); inst.addStaticAbility(StaticAbility.create(effect, card, card.getCurrentState(), false)); } else if (keyword.startsWith("Protection")) { - String valid = CardFactoryUtil.getProtectionValid(keyword, false); + String valid = Protection.getProtectionValid(keyword, false); String effect = "Mode$ CantTarget | ValidTarget$ Player.You | EffectZone$ Command | Secondary$ True "; if (!valid.isEmpty()) { effect += "| ValidSource$ " + valid; @@ -68,7 +63,7 @@ public static void addReplacementEffect(final KeywordInterface inst, Player play String effect = null; if (keyword.startsWith("Protection")) { - String validSource = CardFactoryUtil.getProtectionValid(keyword, true); + String validSource = Protection.getProtectionValid(keyword, true); effect = "Event$ DamageDone | Prevent$ True | ActiveZones$ Command | ValidTarget$ You"; if (!validSource.isEmpty()) {