Refactor rules text generation for P/T boost effects. Fixes #8421

This commit is contained in:
Alex W. Jackson 2021-11-10 06:40:11 -05:00 committed by GitHub
parent 8470a2e8e6
commit bb2546badd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 64 additions and 230 deletions

View file

@ -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");
}
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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) {