From bb2546baddff4270e834c1ae8b3c99b183e4a878 Mon Sep 17 00:00:00 2001 From: "Alex W. Jackson" Date: Wed, 10 Nov 2021 06:40:11 -0500 Subject: [PATCH] Refactor rules text generation for P/T boost effects. Fixes #8421 --- .../org/mage/test/utils/BoostCountTest.java | 19 ++++++++ .../common/continuous/BoostAllEffect.java | 37 +-------------- .../continuous/BoostControlledEffect.java | 44 ++---------------- .../continuous/BoostEnchantedEffect.java | 45 +------------------ .../continuous/BoostEquippedEffect.java | 31 +------------ .../common/continuous/BoostSourceEffect.java | 41 +---------------- .../common/continuous/BoostTargetEffect.java | 36 +-------------- Mage/src/main/java/mage/util/CardUtil.java | 41 +++++++++++++---- 8 files changed, 64 insertions(+), 230 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/utils/BoostCountTest.java b/Mage.Tests/src/test/java/org/mage/test/utils/BoostCountTest.java index 6121fb2bad..bd5b313c6d 100644 --- a/Mage.Tests/src/test/java/org/mage/test/utils/BoostCountTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/utils/BoostCountTest.java @@ -1,5 +1,9 @@ package org.mage.test.utils; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.GetXValue; +import mage.abilities.dynamicvalue.common.SignInversionDynamicValue; +import mage.abilities.dynamicvalue.common.StaticValue; import mage.util.CardUtil; import org.junit.Assert; import org.junit.Test; @@ -21,4 +25,19 @@ public class BoostCountTest { Assert.assertEquals(CardUtil.getBoostCountAsStr(-1, 1), "-1/+1"); Assert.assertEquals(CardUtil.getBoostCountAsStr(1, -1), "+1/-1"); } + + @Test + public void test_DynamicBoostCountSigns() { + DynamicValue zero = StaticValue.get(0); + DynamicValue plusX = GetXValue.instance; + DynamicValue minusX = new SignInversionDynamicValue(plusX); + + Assert.assertEquals(CardUtil.getBoostCountAsStr(plusX, zero), "+X/+0"); + Assert.assertEquals(CardUtil.getBoostCountAsStr(zero, plusX), "+0/+X"); + Assert.assertEquals(CardUtil.getBoostCountAsStr(plusX, plusX), "+X/+X"); + Assert.assertEquals(CardUtil.getBoostCountAsStr(minusX, zero), "-X/-0"); + Assert.assertEquals(CardUtil.getBoostCountAsStr(zero, minusX), "-0/-X"); + Assert.assertEquals(CardUtil.getBoostCountAsStr(minusX, plusX), "-X/+X"); + Assert.assertEquals(CardUtil.getBoostCountAsStr(plusX, minusX), "+X/-X"); + } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostAllEffect.java index bf1261f926..1ba895ef6e 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostAllEffect.java @@ -14,6 +14,7 @@ import mage.constants.SubLayer; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.util.CardUtil; /** * @@ -150,41 +151,7 @@ public class BoostAllEffect extends ContinuousEffectImpl { sb.append("other "); } sb.append(filter.getMessage()).append(" get "); - String p = power.toString(); - if (!p.startsWith("-")) { - sb.append('+'); - } - sb.append(p).append('/'); - String t = toughness.toString(); - if (!t.startsWith("-")) { - if (p.startsWith("-")) { - sb.append('-'); - } else { - sb.append('+'); - } - } - sb.append(t); - if (duration == Duration.EndOfTurn) { - sb.append(" until end of turn"); - } - String message = null; - String fixedPart = null; - if (t.contains("X")) { - message = toughness.getMessage(); - fixedPart = ", where X is "; - } else if (p.contains("X")) { - message = power.getMessage(); - fixedPart = ", where X is "; - } else if (!power.getMessage().isEmpty()) { - message = power.getMessage(); - fixedPart = " for each "; - } else if (!toughness.getMessage().isEmpty()) { - message = toughness.getMessage(); - fixedPart = " for each "; - } - if (message != null && !message.isEmpty() && fixedPart != null) { - sb.append(fixedPart).append(message); - } + sb.append(CardUtil.getBoostText(power, toughness, duration)); staticText = sb.toString(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostControlledEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostControlledEffect.java index 8466445ba7..994d6dadf2 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostControlledEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostControlledEffect.java @@ -13,6 +13,7 @@ import mage.filter.StaticFilters; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.util.CardUtil; import java.util.Iterator; @@ -129,47 +130,8 @@ public class BoostControlledEffect extends ContinuousEffectImpl { if (excludeSource) { sb.append("other "); } - sb.append(filter.getMessage()); - sb.append(" you control get "); - - String p = power.toString(); - if (!p.startsWith("-")) { - sb.append('+'); - } - sb.append(p).append('/'); - String t = toughness.toString(); - if (!t.startsWith("-")) { - if (p.startsWith("-")) { - sb.append('-'); - } else { - sb.append('+'); - } - } - sb.append(t); - - sb.append((duration == Duration.EndOfTurn ? " until end of turn" : "")); - - // where X - String message = null; - if (t.equals("X")) { - message = toughness.getMessage(); - } else if (p.equals("X")) { - message = power.getMessage(); - } - if (message != null && !message.isEmpty()) { - sb.append(", where X is ").append(message); - } - - // for each - if (message == null) { - message = toughness.getMessage(); - if (message.isEmpty()) { - message = power.getMessage(); - } - if (!message.isEmpty()) { - sb.append(" for each " + message); - } - } + sb.append(filter.getMessage()).append(" you control get "); + sb.append(CardUtil.getBoostText(power, toughness, duration)); staticText = sb.toString(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEnchantedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEnchantedEffect.java index 8dcdd7f70a..d64751de07 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEnchantedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEnchantedEffect.java @@ -12,6 +12,7 @@ import mage.constants.SubLayer; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; /** * @@ -39,7 +40,7 @@ public class BoostEnchantedEffect extends ContinuousEffectImpl { super(duration, Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, isCanKill(toughness) ? Outcome.UnboostCreature : Outcome.BoostCreature); this.power = power; this.toughness = toughness; - setText(); + this.staticText = "enchanted creature gets " + CardUtil.getBoostText(power, toughness, duration); } public BoostEnchantedEffect(final BoostEnchantedEffect effect) { @@ -96,46 +97,4 @@ public class BoostEnchantedEffect extends ContinuousEffectImpl { public void setLockedIn(boolean lockedIn) { this.lockedIn = lockedIn; } - - private void setText() { - StringBuilder sb = new StringBuilder(); - sb.append("enchanted creature gets "); - String p = power.toString(); - if (!p.startsWith("-")) { - sb.append('+'); - } - sb.append(p).append('/'); - String t = toughness.toString(); - if (!t.startsWith("-")) { - if (p.startsWith("-")) { - sb.append('-'); - } else { - sb.append('+'); - } - } - sb.append(t); - if (duration != Duration.WhileOnBattlefield) { - sb.append(' ').append(duration.toString()); - } - String message = null; - String fixedPart = null; - if (t.contains("X")) { - message = toughness.getMessage(); - fixedPart = ", where X is "; - } else if (p.contains("X")) { - message = power.getMessage(); - fixedPart = ", where X is "; - } else if (!power.getMessage().isEmpty()) { - message = power.getMessage(); - fixedPart = " for each "; - } else if (!toughness.getMessage().isEmpty()) { - message = toughness.getMessage(); - fixedPart = " for each "; - } - if (message != null && !message.isEmpty() && fixedPart != null) { - sb.append(fixedPart).append(message); - } - staticText = sb.toString(); - } - } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEquippedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEquippedEffect.java index 506e4867a1..a06917ea8b 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEquippedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEquippedEffect.java @@ -12,6 +12,7 @@ import mage.abilities.effects.ContinuousEffectImpl; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; /** * @author BetaSteward_at_googlemail.com @@ -41,7 +42,7 @@ public class BoostEquippedEffect extends ContinuousEffectImpl { if (duration == Duration.EndOfTurn) { fixedTarget = true; } - setText(); + this.staticText = "equipped creature gets " + CardUtil.getBoostText(power, toughness, duration); } public BoostEquippedEffect(final BoostEquippedEffect effect) { @@ -86,32 +87,4 @@ public class BoostEquippedEffect extends ContinuousEffectImpl { return true; } - - private void setText() { - StringBuilder sb = new StringBuilder(); - sb.append("equipped creature gets "); - String p = power.toString(); - if (!p.startsWith("-")) { - sb.append('+'); - } - sb.append(p).append('/'); - String t = toughness.toString(); - if (!t.startsWith("-")) { - if (p.startsWith("-")) { - sb.append('-'); - } else { - sb.append('+'); - } - } - sb.append(t); - if (duration != Duration.WhileOnBattlefield) { - sb.append(' ').append(duration.toString()); - } - String message = power.getMessage(); - if (!message.isEmpty()) { - sb.append(" for each "); - } - sb.append(message); - staticText = sb.toString(); - } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostSourceEffect.java index bf389e9343..ef7c6eef92 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostSourceEffect.java @@ -11,6 +11,7 @@ import mage.constants.Outcome; import mage.constants.SubLayer; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.util.CardUtil; import org.apache.log4j.Logger; /** @@ -40,7 +41,7 @@ public class BoostSourceEffect extends ContinuousEffectImpl implements SourceEff this.power = power; this.toughness = toughness; this.lockedIn = lockedIn; - setText(); + this.staticText = "{this} gets " + CardUtil.getBoostText(power, toughness, duration); } public BoostSourceEffect(final BoostSourceEffect effect) { @@ -86,42 +87,4 @@ public class BoostSourceEffect extends ContinuousEffectImpl implements SourceEff } return false; } - - private void setText() { - StringBuilder sb = new StringBuilder(); - sb.append("{this} gets "); - String p = power.toString(); - if (!p.startsWith("-")) { - sb.append('+'); - } - sb.append(p).append('/'); - String t = toughness.toString(); - if (!t.startsWith("-")) { - sb.append('+'); - } - sb.append(t); - if (duration != Duration.WhileOnBattlefield) { - sb.append(' ').append(duration.toString()); - } - String message = null; - String fixedPart = null; - if (t.contains("X")) { - message = toughness.getMessage(); - fixedPart = ", where X is "; - } else if (p.contains("X")) { - message = power.getMessage(); - fixedPart = ", where X is "; - } else if (!power.getMessage().isEmpty()) { - message = power.getMessage(); - fixedPart = " for each "; - } else if (!toughness.getMessage().isEmpty()) { - message = toughness.getMessage(); - fixedPart = " for each "; - } - if (message != null && !message.isEmpty() && fixedPart != null) { - sb.append(fixedPart).append(message); - } - staticText = sb.toString(); - } - } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostTargetEffect.java index 3f772aa552..269a8b169b 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostTargetEffect.java @@ -111,41 +111,7 @@ public class BoostTargetEffect extends ContinuousEffectImpl { } sb.append(target.getTargetName()).append(" gets "); } - String p = power.toString(); - if (!p.startsWith("-")) { - sb.append('+'); - } - sb.append(p).append('/'); - String t = toughness.toString(); - if (!t.startsWith("-")) { - if (t.equals("0") && p.startsWith("-")) { - sb.append('-'); - } else { - sb.append('+'); - } - } - sb.append(t); - if (duration != Duration.WhileOnBattlefield) { - sb.append(' ').append(duration.toString()); - } - String message = null; - String fixedPart = null; - if (t.contains("X")) { - message = toughness.getMessage(); - fixedPart = ", where X is "; - } else if (p.contains("X")) { - message = power.getMessage(); - fixedPart = ", where X is "; - } else if (!power.getMessage().isEmpty()) { - message = power.getMessage(); - fixedPart = " for each "; - } else if (!toughness.getMessage().isEmpty()) { - message = toughness.getMessage(); - fixedPart = " for each "; - } - if (message != null && !message.isEmpty() && fixedPart != null) { - sb.append(fixedPart).append(message); - } + sb.append(CardUtil.getBoostText(power, toughness, duration)); return sb.toString(); } } diff --git a/Mage/src/main/java/mage/util/CardUtil.java b/Mage/src/main/java/mage/util/CardUtil.java index 91a5022419..983b461a30 100644 --- a/Mage/src/main/java/mage/util/CardUtil.java +++ b/Mage/src/main/java/mage/util/CardUtil.java @@ -10,6 +10,8 @@ import mage.abilities.SpellAbility; import mage.abilities.condition.Condition; import mage.abilities.costs.VariableCost; import mage.abilities.costs.mana.*; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.common.asthought.CanPlayCardControllerEffect; @@ -852,20 +854,43 @@ public final class CardUtil { } } - public static String getBoostCountAsStr(int power, int toughness) { + public static String getBoostCountAsStr(DynamicValue power, DynamicValue toughness) { // sign fix for zero values // -1/+0 must be -1/-0 // +0/-1 must be -0/-1 - String signedP = String.format("%1$+d", power); - String signedT = String.format("%1$+d", toughness); - if (signedP.equals("+0") && signedT.startsWith("-")) { - signedP = "-0"; + String p = power.toString(); + String t = toughness.toString(); + if (!p.startsWith("-")) { + p = (t.startsWith("-") && p.equals("0") ? "-" : "+") + p; } - if (signedT.equals("+0") && signedP.startsWith("-")) { - signedT = "-0"; + if (!t.startsWith("-")) { + t = (p.startsWith("-") && t.equals("0") ? "-" : "+") + t; } + return p + "/" + t; + } - return signedP + "/" + signedT; + public static String getBoostCountAsStr(int power, int toughness) { + return getBoostCountAsStr(StaticValue.get(power), StaticValue.get(toughness)); + } + + public static String getBoostText(DynamicValue power, DynamicValue toughness, Duration duration) { + String boostCount = getBoostCountAsStr(power, toughness); + StringBuilder sb = new StringBuilder(boostCount); + // don't include "for the rest of the game" for emblems, etc. + if (duration != Duration.EndOfGame) { + String d = duration.toString(); + if (!d.isEmpty()) { + sb.append(" ").append(d); + } + } + String message = power.getMessage(); + if (message.isEmpty()) { + message = toughness.getMessage(); + } + if (!message.isEmpty()) { + sb.append(boostCount.contains("X") ? ", where X is " : " for each ").append(message); + } + return sb.toString(); } public static boolean isSpliceAbility(Ability ability, Game game) {