mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
Infrastructure for Myr Superion (part 1) - added alt syntax for mana cost: Mana<3 U W\Creature> - backslash is intentional
This commit is contained in:
@@ -51,24 +51,12 @@ public class Cost {
|
|||||||
return this.costParts;
|
return this.costParts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean sacCost = false;
|
|
||||||
private boolean tapCost = false;
|
private boolean tapCost = false;
|
||||||
private boolean untapCost = false;
|
|
||||||
|
|
||||||
|
|
||||||
public final boolean getSacCost() {
|
|
||||||
return this.sacCost;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public final boolean hasTapCost() {
|
public final boolean hasTapCost() {
|
||||||
return this.tapCost;
|
return this.tapCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean hasUntapCost() {
|
|
||||||
return this.untapCost;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* hasNoManaCost.
|
* hasNoManaCost.
|
||||||
@@ -140,6 +128,7 @@ public class Cost {
|
|||||||
this.name = card != null ? card.getName() : "";
|
this.name = card != null ? card.getName() : "";
|
||||||
|
|
||||||
boolean xCantBe0 = false;
|
boolean xCantBe0 = false;
|
||||||
|
boolean untapCost = false;
|
||||||
|
|
||||||
StringBuilder manaParts = new StringBuilder();
|
StringBuilder manaParts = new StringBuilder();
|
||||||
String[] parts = TextUtil.splitWithParenthesis(parse, ' ', '<', '>');
|
String[] parts = TextUtil.splitWithParenthesis(parse, ' ', '<', '>');
|
||||||
@@ -149,30 +138,38 @@ public class Cost {
|
|||||||
if ( part.equals("T") || part.equals("Tap") )
|
if ( part.equals("T") || part.equals("Tap") )
|
||||||
this.tapCost = true;
|
this.tapCost = true;
|
||||||
if ( part.equals("Q") || part.equals("Untap") )
|
if ( part.equals("Q") || part.equals("Untap") )
|
||||||
this.untapCost = true;
|
untapCost = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CostPartMana parsedMana = null;
|
||||||
for(String part : parts) {
|
for(String part : parts) {
|
||||||
if( "XCantBe0".equals(part) )
|
if( "XCantBe0".equals(part) )
|
||||||
xCantBe0 = true;
|
xCantBe0 = true;
|
||||||
else {
|
else {
|
||||||
CostPart cp = parseCostPart(part, tapCost, untapCost);
|
CostPart cp = parseCostPart(part, tapCost, untapCost);
|
||||||
if ( null != cp )
|
if ( null != cp )
|
||||||
this.costParts.add(cp);
|
if ( cp instanceof CostPartMana ) {
|
||||||
|
parsedMana = (CostPartMana) cp;
|
||||||
|
} else {
|
||||||
|
this.costParts.add(cp);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
manaParts.append(part).append(" ");
|
manaParts.append(part).append(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (manaParts.length() > 0) {
|
if ( parsedMana == null && manaParts.length() > 0) {
|
||||||
this.costParts.add(0, new CostPartMana(new ManaCost(new ManaCostParser(manaParts.toString())), xCantBe0));
|
parsedMana = new CostPartMana(new ManaCost(new ManaCostParser(manaParts.toString())), null, xCantBe0);
|
||||||
}
|
}
|
||||||
|
if ( parsedMana != null ) {
|
||||||
|
this.costParts.add(0, parsedMana);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// inspect parts to set Sac, {T} and {Q} flags
|
// inspect parts to set Sac, {T} and {Q} flags
|
||||||
for (int iCp = 0; iCp < costParts.size(); iCp++) {
|
for (int iCp = 0; iCp < costParts.size(); iCp++) {
|
||||||
CostPart cp = costParts.get(iCp);
|
CostPart cp = costParts.get(iCp);
|
||||||
if( cp instanceof CostSacrifice ) sacCost = true;
|
|
||||||
|
|
||||||
// my guess why Q/T are to be first and are followed by mana parts
|
// my guess why Q/T are to be first and are followed by mana parts
|
||||||
// is because Q/T are undoable and mana is interactive, so it well be easy to rollback if player refuses to pay
|
// is because Q/T are undoable and mana is interactive, so it well be easy to rollback if player refuses to pay
|
||||||
@@ -189,6 +186,13 @@ public class Cost {
|
|||||||
|
|
||||||
private static CostPart parseCostPart(String parse, boolean tapCost, boolean untapCost) {
|
private static CostPart parseCostPart(String parse, boolean tapCost, boolean untapCost) {
|
||||||
|
|
||||||
|
if(parse.startsWith("Mana<")) {
|
||||||
|
final String[] splitStr = TextUtil.split(abCostParse(parse, 1)[0], '\\');
|
||||||
|
final String restriction = splitStr.length > 1 ? splitStr[1] : null;
|
||||||
|
final boolean xCantBe0 = splitStr.length > 1 && splitStr[1].equals("XCantBe0");
|
||||||
|
return new CostPartMana(new ManaCost(new ManaCostParser(splitStr[0])), xCantBe0 ? null : restriction, xCantBe0);
|
||||||
|
}
|
||||||
|
|
||||||
if(parse.startsWith("tapXType<")) {
|
if(parse.startsWith("tapXType<")) {
|
||||||
final String[] splitStr = abCostParse(parse, 3);
|
final String[] splitStr = abCostParse(parse, 3);
|
||||||
final String description = splitStr.length > 2 ? splitStr[2] : null;
|
final String description = splitStr.length > 2 ? splitStr[2] : null;
|
||||||
@@ -342,8 +346,7 @@ public class Cost {
|
|||||||
final int startPos = 1 + parse.indexOf("<");
|
final int startPos = 1 + parse.indexOf("<");
|
||||||
final int endPos = parse.indexOf(">", startPos);
|
final int endPos = parse.indexOf(">", startPos);
|
||||||
String str = parse.substring(startPos, endPos);
|
String str = parse.substring(startPos, endPos);
|
||||||
|
final String[] splitStr = TextUtil.split(str, '/', numParse);
|
||||||
final String[] splitStr = str.split("/", numParse);
|
|
||||||
return splitStr;
|
return splitStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,7 +375,7 @@ public class Cost {
|
|||||||
// Spells with a cost of 0 should be affected too
|
// Spells with a cost of 0 should be affected too
|
||||||
final ManaCostBeingPaid changedCost = new ManaCostBeingPaid("0");
|
final ManaCostBeingPaid changedCost = new ManaCostBeingPaid("0");
|
||||||
changedCost.applySpellCostChange(sa);
|
changedCost.applySpellCostChange(sa);
|
||||||
this.costParts.add(new CostPartMana(changedCost.toManaCost(), false));
|
this.costParts.add(new CostPartMana(changedCost.toManaCost(), null, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ public class CostPartMana extends CostPart {
|
|||||||
private final ManaCost cost;
|
private final ManaCost cost;
|
||||||
private ManaCost adjustedCost;
|
private ManaCost adjustedCost;
|
||||||
private boolean xCantBe0 = false;
|
private boolean xCantBe0 = false;
|
||||||
|
private final String restriction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new cost mana.
|
* Instantiates a new cost mana.
|
||||||
@@ -50,9 +51,10 @@ public class CostPartMana extends CostPart {
|
|||||||
* the amount
|
* the amount
|
||||||
* @param xCantBe0 TODO
|
* @param xCantBe0 TODO
|
||||||
*/
|
*/
|
||||||
public CostPartMana(final ManaCost cost, boolean xCantBe0) {
|
public CostPartMana(final ManaCost cost, String restriction, boolean xCantBe0) {
|
||||||
this.cost = cost;
|
this.cost = cost;
|
||||||
this.xCantBe0 = xCantBe0; // TODO: Add 0 to parameter's name.
|
this.xCantBe0 = xCantBe0;
|
||||||
|
this.restriction = restriction;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -172,4 +174,13 @@ public class CostPartMana extends CostPart {
|
|||||||
public PaymentDecision decideAIPayment(AIPlayer ai, SpellAbility ability, Card source) {
|
public PaymentDecision decideAIPayment(AIPlayer ai, SpellAbility ability, Card source) {
|
||||||
return new PaymentDecision(0);
|
return new PaymentDecision(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Write javadoc for this method.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getRestiction() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return restriction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ public class CostPayment {
|
|||||||
final List<CostPart> parts = this.cost.getCostParts();
|
final List<CostPart> parts = this.cost.getCostParts();
|
||||||
|
|
||||||
if (this.getCost().getCostMana() == null) {
|
if (this.getCost().getCostMana() == null) {
|
||||||
parts.add(new CostPartMana(ManaCost.ZERO, false));
|
parts.add(new CostPartMana(ManaCost.ZERO, null, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Class<? extends CostPart>, PaymentDecision> decisions = new HashMap<Class<? extends CostPart>, PaymentDecision>();
|
Map<Class<? extends CostPart>, PaymentDecision> decisions = new HashMap<Class<? extends CostPart>, PaymentDecision>();
|
||||||
|
|||||||
@@ -135,9 +135,11 @@ public class CostUtil {
|
|||||||
ManaCostBeingPaid oldManaCost = new ManaCostBeingPaid(((CostPartMana) part).getMana());
|
ManaCostBeingPaid oldManaCost = new ManaCostBeingPaid(((CostPartMana) part).getMana());
|
||||||
boolean xCanBe0 = ((CostPartMana) part).canXbe0() && costPart2.canXbe0();
|
boolean xCanBe0 = ((CostPartMana) part).canXbe0() && costPart2.canXbe0();
|
||||||
oldManaCost.combineManaCost(costPart2.getMana());
|
oldManaCost.combineManaCost(costPart2.getMana());
|
||||||
|
String r2 = costPart2.getRestiction();
|
||||||
|
String r1 = ((CostPartMana) part).getRestiction();
|
||||||
|
String r = r1 == null ? r2 : ( r2 == null ? r1 : r1+"."+r2);
|
||||||
cost2.getCostParts().remove(costPart2);
|
cost2.getCostParts().remove(costPart2);
|
||||||
cost2.getCostParts().add(0, new CostPartMana(oldManaCost.toManaCost(), !xCanBe0));
|
cost2.getCostParts().add(0, new CostPartMana(oldManaCost.toManaCost(), r, !xCanBe0));
|
||||||
} else {
|
} else {
|
||||||
cost2.getCostParts().add(part);
|
cost2.getCostParts().add(part);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,22 +70,6 @@ public class SpellPermanent extends Spell {
|
|||||||
this(sourceCard, new Cost(sourceCard, sourceCard.getManaCost(), false), null);
|
this(sourceCard, new Cost(sourceCard, sourceCard.getManaCost(), false), null);
|
||||||
} // Spell_Permanent()
|
} // Spell_Permanent()
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Constructor for Spell_Permanent.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param sourceCard
|
|
||||||
* a {@link forge.Card} object.
|
|
||||||
* @param cost
|
|
||||||
* a {@link forge.card.cost.Cost} object.
|
|
||||||
* @param tgt
|
|
||||||
* a {@link forge.card.spellability.Target} object.
|
|
||||||
*/
|
|
||||||
public SpellPermanent(final Card sourceCard, final Cost cost, final Target tgt) {
|
|
||||||
this(sourceCard, cost, tgt, true);
|
|
||||||
} // Spell_Permanent()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new spell_ permanent.
|
* Instantiates a new spell_ permanent.
|
||||||
*
|
*
|
||||||
@@ -98,7 +82,7 @@ public class SpellPermanent extends Spell {
|
|||||||
* @param setDesc
|
* @param setDesc
|
||||||
* the set desc
|
* the set desc
|
||||||
*/
|
*/
|
||||||
public SpellPermanent(final Card sourceCard, final Cost cost, final Target tgt, final boolean setDesc) {
|
public SpellPermanent(final Card sourceCard, final Cost cost, final Target tgt) {
|
||||||
super(sourceCard, cost, tgt);
|
super(sourceCard, cost, tgt);
|
||||||
|
|
||||||
if (sourceCard.isCreature()) {
|
if (sourceCard.isCreature()) {
|
||||||
@@ -110,9 +94,8 @@ public class SpellPermanent extends Spell {
|
|||||||
this.setStackDescription(sourceCard.getName());
|
this.setStackDescription(sourceCard.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setDesc) {
|
|
||||||
this.setDescription(this.getStackDescription());
|
this.setDescription(this.getStackDescription());
|
||||||
}
|
|
||||||
|
|
||||||
if (this.getManaCost().countX() > 0) {
|
if (this.getManaCost().countX() > 0) {
|
||||||
if (!this.getSourceCard().getSVar("X").equals("")) {
|
if (!this.getSourceCard().getSVar("X").equals("")) {
|
||||||
|
|||||||
@@ -41,34 +41,37 @@ public class TextUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String[] split(CharSequence input, char delimiter) {
|
public static String[] split(CharSequence input, char delimiter) {
|
||||||
return splitWithParenthesis(input, delimiter, '\0', '\0', true);
|
return splitWithParenthesis(input, delimiter, Integer.MAX_VALUE, '\0', '\0', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] split(CharSequence input, char delimiter, boolean skipEmpty) {
|
public static String[] split(CharSequence input, char delimiter, int limit) {
|
||||||
return splitWithParenthesis(input, delimiter, '\0', '\0', skipEmpty);
|
return splitWithParenthesis(input, delimiter, limit, '\0', '\0', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] splitWithParenthesis(CharSequence input, char delimiter, char openPar, char closePar) {
|
public static String[] splitWithParenthesis(CharSequence input, char delimiter, char openPar, char closePar) {
|
||||||
return splitWithParenthesis(input, delimiter, openPar, closePar, true);
|
return splitWithParenthesis(input, delimiter, Integer.MAX_VALUE, openPar, closePar, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Split string separated by a single char delimiter, can take parenthesis in account
|
* Split string separated by a single char delimiter, can take parenthesis in account
|
||||||
* It's faster than String.split, and allows parenthesis
|
* It's faster than String.split, and allows parenthesis
|
||||||
*/
|
*/
|
||||||
public static String[] splitWithParenthesis(CharSequence input, char delimiter, char openPar, char closePar, boolean skipEmpty) {
|
public static String[] splitWithParenthesis(CharSequence input, char delimiter, int maxEntries, char openPar, char closePar, boolean skipEmpty) {
|
||||||
List<String> result = new ArrayList<String>();
|
List<String> result = new ArrayList<String>();
|
||||||
int nPar = 0;
|
int nPar = 0;
|
||||||
int len = input.length();
|
int len = input.length();
|
||||||
int start = 0;
|
int start = 0;
|
||||||
|
int idx = 1;
|
||||||
for (int iC = 0; iC < len; iC++ ) {
|
for (int iC = 0; iC < len; iC++ ) {
|
||||||
char c = input.charAt(iC);
|
char c = input.charAt(iC);
|
||||||
if( openPar > 0 && c == openPar ) nPar++;
|
if( openPar > 0 && c == openPar ) nPar++;
|
||||||
if( closePar > 0 && c == closePar ) { nPar = nPar > 0 ? nPar - 1 : 0; }
|
if( closePar > 0 && c == closePar ) { nPar = nPar > 0 ? nPar - 1 : 0; }
|
||||||
|
|
||||||
if( c == delimiter && nPar == 0) {
|
if( c == delimiter && nPar == 0 && idx < maxEntries) {
|
||||||
if( iC > start || !skipEmpty )
|
if( iC > start || !skipEmpty ) {
|
||||||
result.add(input.subSequence(start, iC).toString());
|
result.add(input.subSequence(start, iC).toString());
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
start = iC + 1;
|
start = iC + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user