Merge pull request #1724 from Northmoc/botcounters

BOT: Jetfire and related improvements
This commit is contained in:
Northmoc
2022-10-25 06:59:49 -04:00
committed by GitHub
33 changed files with 107 additions and 47 deletions

View File

@@ -5,6 +5,7 @@ import static forge.util.TextUtil.toManaString;
import java.util.List;
import java.util.Map;
import forge.util.Lang;
import org.apache.commons.lang3.StringUtils;
import forge.card.ColorSet;
@@ -264,9 +265,16 @@ public class ManaEffect extends SpellAbilityEffect {
@Override
protected String getStackDescription(SpellAbility sa) {
final StringBuilder sb = new StringBuilder();
final List<Player> tgtPlayers = getDefinedPlayersOrTargeted(sa);
String mana = !sa.hasParam("Amount") || StringUtils.isNumeric(sa.getParam("Amount"))
? GameActionUtil.generatedMana(sa) : "mana";
sb.append("Add ").append(toManaString(mana)).append(".");
String manaDesc = "";
if (mana.equals("mana") && sa.hasParam("Produced") && sa.hasParam("AmountDesc")) {
mana = sa.getParam("Produced");
manaDesc = sa.getParam("AmountDesc");
}
sb.append(Lang.joinHomogenous(tgtPlayers)).append(tgtPlayers.size() == 1 ? " adds " : " add ");
sb.append(toManaString(mana)).append(manaDesc).append(".");
if (sa.hasParam("RestrictValid")) {
sb.append(" ");
final String desc = sa.getDescription();

View File

@@ -289,13 +289,18 @@ public class Cost implements Serializable {
}
if (parse.startsWith("SubCounter<")) {
// SubCounter<NumCounters/CounterType>
// SubCounter<NumCounters/CounterType/{Type/Description/Zone}>
final String[] splitStr = abCostParse(parse, 5);
final String type = splitStr.length > 2 ? splitStr[2] : "CARDNAME";
final String description = splitStr.length > 3 ? splitStr[3] : null;
final ZoneType zone = splitStr.length > 4 ? ZoneType.smartValueOf(splitStr[4]) : ZoneType.Battlefield;
boolean oneOrMore = false;
if (splitStr[0].equals("X1+")) {
oneOrMore = true;
splitStr[0] = "X";
}
return new CostRemoveCounter(splitStr[0], CounterType.getType(splitStr[1]), type, description, zone);
return new CostRemoveCounter(splitStr[0], CounterType.getType(splitStr[1]), type, description, zone, oneOrMore);
}
if (parse.startsWith("AddCounter<")) {
@@ -401,7 +406,12 @@ public class Cost implements Serializable {
if (parse.startsWith("RemoveAnyCounter<")) {
final String[] splitStr = abCostParse(parse, 4);
final String description = splitStr.length > 3 ? splitStr[3] : null;
return new CostRemoveAnyCounter(splitStr[0], CounterType.getType(splitStr[1]), splitStr[2], description);
boolean oneOrMore = false;
if (splitStr[0].equals("X1+")) {
oneOrMore = true;
splitStr[0] = "X";
}
return new CostRemoveAnyCounter(splitStr[0], CounterType.getType(splitStr[1]), splitStr[2], description, oneOrMore);
}
if (parse.startsWith("Exile<")) {
@@ -916,7 +926,7 @@ public class Cost implements Serializable {
if (counters < 0) {
costParts.add(new CostPutCounter(String.valueOf(counters *-1), CounterType.get(CounterEnumType.LOYALTY), part.getType(), part.getTypeDescription()));
} else {
costParts.add(new CostRemoveCounter(String.valueOf(counters), CounterType.get(CounterEnumType.LOYALTY), part.getType(), part.getTypeDescription(), ZoneType.Battlefield));
costParts.add(new CostRemoveCounter(String.valueOf(counters), CounterType.get(CounterEnumType.LOYALTY), part.getType(), part.getTypeDescription(), ZoneType.Battlefield, false));
}
} else {
continue;

View File

@@ -41,10 +41,11 @@ public class CostRemoveAnyCounter extends CostPart {
*/
private static final long serialVersionUID = 1L;
// RemoveAnyCounter<Num/Type/{TypeDescription}>
// Power Conduit and Chisei, Heart of Oceans
// Both cards have "Remove a counter from a permanent you control"
// things like "Remove a counter from a permanent you control"
// or "Remove one or more +1/+1 counters from among artifacts you control"
public final CounterType counter;
public final Boolean oneOrMore;
/**
* Instantiates a new cost CostRemoveAnyCounter.
@@ -52,9 +53,10 @@ public class CostRemoveAnyCounter extends CostPart {
* @param amount
* the amount
*/
public CostRemoveAnyCounter(final String amount, final CounterType counter, final String type, final String description) {
public CostRemoveAnyCounter(final String amount, final CounterType counter, final String type, final String description, final boolean oneOrMore) {
super(amount, type, description);
this.counter = counter;
this.oneOrMore = oneOrMore;
}
@Override
@@ -99,12 +101,16 @@ public class CostRemoveAnyCounter extends CostPart {
public final String toString() {
final StringBuilder sb = new StringBuilder();
String counters = this.counter == null ? "counter" : this.counter.getName().toLowerCase() + " counter";
final String counters = this.counter == null ? "counter" : this.counter.getName().toLowerCase() + " counter";
final String desc = this.getTypeDescription() == null ? this.getType() : this.getTypeDescription();
sb.append("Remove ");
sb.append(Cost.convertAmountTypeToWords(this.convertAmount(), this.getAmount(), counters));
sb.append(this.getAmount().equals("1") ? "" : "s");
final String desc = this.getTypeDescription() == null ? this.getType() : this.getTypeDescription();
if (oneOrMore) {
sb.append("one or more ").append(counters).append("s");
} else {
sb.append(Cost.convertAmountTypeToWords(this.convertAmount(), this.getAmount(), counters));
sb.append(this.getAmount().equals("1") ? "" : "s");
}
sb.append(" from ").append(desc);
return sb.toString();

View File

@@ -35,18 +35,13 @@ import forge.game.zone.ZoneType;
public class CostRemoveCounter extends CostPart {
// SubCounter<Num/Counter/{Type/TypeDescription/Zone}>
// Here are the cards that have RemoveCounter<Type>
// Ion Storm, Noviken Sages, Ghave, Guru of Spores, Power Conduit (any
// Counter is tough),
// Quillspike, Rift Elemental, Sage of Fables, Spike Rogue
/**
* Serializables need a version ID.
*/
private static final long serialVersionUID = 1L;
public final CounterType counter;
public final ZoneType zone;
public final Boolean oneOrMore;
/**
* Instantiates a new cost remove counter.
@@ -61,11 +56,12 @@ public class CostRemoveCounter extends CostPart {
* the description
* @param zone the zone.
*/
public CostRemoveCounter(final String amount, final CounterType counter, final String type, final String description, ZoneType zone) {
public CostRemoveCounter(final String amount, final CounterType counter, final String type, final String description, final ZoneType zone, final boolean oneOrMore) {
super(amount, type, description);
this.counter = counter;
this.zone = zone;
this.oneOrMore = oneOrMore;
}
@Override
@@ -108,7 +104,12 @@ public class CostRemoveCounter extends CostPart {
} else {
sb.append("Remove ");
if (this.getAmount().equals("X")) {
sb.append("any number of counters");
if (oneOrMore) {
sb.append("one or more ");
} else {
sb.append("any number of ");
}
sb.append(this.counter.getName().toLowerCase()).append(" counters");
} else if (this.getAmount().equals("All")) {
sb.append("all ").append(this.counter.getName().toLowerCase()).append(" counters");
} else {