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:
Maxmtg
2013-04-05 22:01:32 +00:00
parent b97349fe29
commit 0be4ad70da
6 changed files with 56 additions and 54 deletions

View File

@@ -51,24 +51,12 @@ public class Cost {
return this.costParts;
}
private boolean sacCost = false;
private boolean tapCost = false;
private boolean untapCost = false;
public final boolean getSacCost() {
return this.sacCost;
}
public final boolean hasTapCost() {
return this.tapCost;
}
public final boolean hasUntapCost() {
return this.untapCost;
}
/**
* <p>
* hasNoManaCost.
@@ -140,6 +128,7 @@ public class Cost {
this.name = card != null ? card.getName() : "";
boolean xCantBe0 = false;
boolean untapCost = false;
StringBuilder manaParts = new StringBuilder();
String[] parts = TextUtil.splitWithParenthesis(parse, ' ', '<', '>');
@@ -149,30 +138,38 @@ public class Cost {
if ( part.equals("T") || part.equals("Tap") )
this.tapCost = true;
if ( part.equals("Q") || part.equals("Untap") )
this.untapCost = true;
untapCost = true;
}
CostPartMana parsedMana = null;
for(String part : parts) {
if( "XCantBe0".equals(part) )
xCantBe0 = true;
else {
CostPart cp = parseCostPart(part, tapCost, untapCost);
if ( null != cp )
this.costParts.add(cp);
if ( cp instanceof CostPartMana ) {
parsedMana = (CostPartMana) cp;
} else {
this.costParts.add(cp);
}
else
manaParts.append(part).append(" ");
}
}
if (manaParts.length() > 0) {
this.costParts.add(0, new CostPartMana(new ManaCost(new ManaCostParser(manaParts.toString())), xCantBe0));
if ( parsedMana == null && manaParts.length() > 0) {
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
for (int iCp = 0; iCp < costParts.size(); 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
// 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) {
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<")) {
final String[] splitStr = abCostParse(parse, 3);
final String description = splitStr.length > 2 ? splitStr[2] : null;
@@ -342,8 +346,7 @@ public class Cost {
final int startPos = 1 + parse.indexOf("<");
final int endPos = parse.indexOf(">", startPos);
String str = parse.substring(startPos, endPos);
final String[] splitStr = str.split("/", numParse);
final String[] splitStr = TextUtil.split(str, '/', numParse);
return splitStr;
}
@@ -372,7 +375,7 @@ public class Cost {
// Spells with a cost of 0 should be affected too
final ManaCostBeingPaid changedCost = new ManaCostBeingPaid("0");
changedCost.applySpellCostChange(sa);
this.costParts.add(new CostPartMana(changedCost.toManaCost(), false));
this.costParts.add(new CostPartMana(changedCost.toManaCost(), null, false));
}
}

View File

@@ -40,6 +40,7 @@ public class CostPartMana extends CostPart {
private final ManaCost cost;
private ManaCost adjustedCost;
private boolean xCantBe0 = false;
private final String restriction;
/**
* Instantiates a new cost mana.
@@ -50,9 +51,10 @@ public class CostPartMana extends CostPart {
* the amount
* @param xCantBe0 TODO
*/
public CostPartMana(final ManaCost cost, boolean xCantBe0) {
public CostPartMana(final ManaCost cost, String restriction, boolean xCantBe0) {
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) {
return new PaymentDecision(0);
}
/**
* TODO: Write javadoc for this method.
* @return
*/
public String getRestiction() {
// TODO Auto-generated method stub
return restriction;
}
}

View File

@@ -180,7 +180,7 @@ public class CostPayment {
final List<CostPart> parts = this.cost.getCostParts();
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>();

View File

@@ -135,9 +135,11 @@ public class CostUtil {
ManaCostBeingPaid oldManaCost = new ManaCostBeingPaid(((CostPartMana) part).getMana());
boolean xCanBe0 = ((CostPartMana) part).canXbe0() && costPart2.canXbe0();
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().add(0, new CostPartMana(oldManaCost.toManaCost(), !xCanBe0));
cost2.getCostParts().add(0, new CostPartMana(oldManaCost.toManaCost(), r, !xCanBe0));
} else {
cost2.getCostParts().add(part);
}

View File

@@ -70,22 +70,6 @@ public class SpellPermanent extends Spell {
this(sourceCard, new Cost(sourceCard, sourceCard.getManaCost(), false), null);
} // 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.
*
@@ -98,7 +82,7 @@ public class SpellPermanent extends Spell {
* @param setDesc
* 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);
if (sourceCard.isCreature()) {
@@ -110,9 +94,8 @@ public class SpellPermanent extends Spell {
this.setStackDescription(sourceCard.getName());
}
if (setDesc) {
this.setDescription(this.getStackDescription());
}
this.setDescription(this.getStackDescription());
if (this.getManaCost().countX() > 0) {
if (!this.getSourceCard().getSVar("X").equals("")) {

View File

@@ -41,34 +41,37 @@ public class TextUtil {
}
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) {
return splitWithParenthesis(input, delimiter, '\0', '\0', skipEmpty);
public static String[] split(CharSequence input, char delimiter, int limit) {
return splitWithParenthesis(input, delimiter, limit, '\0', '\0', true);
}
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
* 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>();
int nPar = 0;
int len = input.length();
int start = 0;
int idx = 1;
for (int iC = 0; iC < len; iC++ ) {
char c = input.charAt(iC);
if( openPar > 0 && c == openPar ) nPar++;
if( closePar > 0 && c == closePar ) { nPar = nPar > 0 ? nPar - 1 : 0; }
if( c == delimiter && nPar == 0) {
if( iC > start || !skipEmpty )
if( c == delimiter && nPar == 0 && idx < maxEntries) {
if( iC > start || !skipEmpty ) {
result.add(input.subSequence(start, iC).toString());
idx++;
}
start = iC + 1;
}
}