From fd7d9155f2413316032fa650ea93eaad95d4d44f Mon Sep 17 00:00:00 2001 From: Sol Date: Sat, 22 Sep 2012 00:21:42 +0000 Subject: [PATCH] - Suspend can now use Cost objects - X Can't be 0 added for human (although we need a better way to display it) - Added Aeon Chronicler --- .gitattributes | 1 + res/cardsfolder/a/aeon_chronicler.txt | 16 ++++++ .../card/cardfactory/CardFactoryUtil.java | 19 ++++--- src/main/java/forge/card/cost/Cost.java | 10 +++- src/main/java/forge/card/cost/CostMana.java | 49 +++++++++++++------ .../java/forge/card/cost/CostPayment.java | 2 +- 6 files changed, 71 insertions(+), 26 deletions(-) create mode 100644 res/cardsfolder/a/aeon_chronicler.txt diff --git a/.gitattributes b/.gitattributes index b5845588c90..0fee810b037 100644 --- a/.gitattributes +++ b/.gitattributes @@ -96,6 +96,7 @@ res/cardsfolder/a/advice_from_the_fae.txt -text res/cardsfolder/a/aegis_angel.txt -text res/cardsfolder/a/aegis_of_the_meek.txt svneol=native#text/plain res/cardsfolder/a/aeolipile.txt svneol=native#text/plain +res/cardsfolder/a/aeon_chronicler.txt -text res/cardsfolder/a/aerathi_berserker.txt svneol=native#text/plain res/cardsfolder/a/aerial_caravan.txt -text res/cardsfolder/a/aerie_mystics.txt svneol=native#text/plain diff --git a/res/cardsfolder/a/aeon_chronicler.txt b/res/cardsfolder/a/aeon_chronicler.txt new file mode 100644 index 00000000000..1885f4c858b --- /dev/null +++ b/res/cardsfolder/a/aeon_chronicler.txt @@ -0,0 +1,16 @@ +Name:Aeon Chronicler +ManaCost:3 U U +Types:Creature Avatar +Text:X can't be 0. +PT:*/* +S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$ Y | SetToughness$ Y | References$ Y | Description$ CARDNAME's power and toughness are each equal to the number of cards in your hand. +K:Suspend:X:XCantBe0 X 3 U +T:Mode$ CounterRemoved | ValidCard$ Card.Self | TriggerZones$ Exile | CounterType$ TIME | Execute$ TrigDraw | TriggerDescription$ Whenever a time counter is removed from CARDNAME while it's exiled, draw a card. +SVar:TrigDraw:DB$ Draw | NumCards$ 1 | Defined$ You +SVar:X:Count$xPaid +SVar:Y:Count$InYourHand +SVar:RemAIDeck:True +SVar:Rarity:Rare +SetInfo:PLC|Rare|http://magiccards.info/scans/en/pc/32.jpg +Oracle:Aeon Chronicler's power and toughness are each equal to the number of cards in your hand.\nSuspend X-{X}{3}{U}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{3}{U} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.)\nWhenever a time counter is removed from Aeon Chronicler while it's exiled, draw a card. +End \ No newline at end of file diff --git a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java index 4d7081293dc..f4f3570acd6 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java @@ -1170,13 +1170,14 @@ public class CardFactoryUtil { * a {@link forge.Card} object. * @param suspendCost * a {@link java.lang.String} object. - * @param suspendCounters + * @param timeCounters * a int. * @return a {@link forge.card.spellability.SpellAbility} object. */ - public static SpellAbility abilitySuspend(final Card sourceCard, final String suspendCost, final int suspendCounters) { + public static SpellAbility abilitySuspend(final Card sourceCard, final String suspendCost, final String timeCounters) { // be careful with Suspend ability, it will not hit the stack - final SpellAbility suspend = new AbilityStatic(sourceCard, suspendCost) { + Cost cost = new Cost(sourceCard, suspendCost, true); + final SpellAbility suspend = new AbilityStatic(sourceCard, cost, null) { @Override public boolean canPlay() { if (!(this.getRestrictions().canPlay(sourceCard, this))) { @@ -1200,22 +1201,24 @@ public class CardFactoryUtil { @Override public void resolve() { final Card c = Singletons.getModel().getGameAction().exile(sourceCard); - c.addCounter(Counters.TIME, suspendCounters); + + int counters = AbilityFactory.calculateAmount(c, timeCounters, this); + c.addCounter(Counters.TIME, counters); StringBuilder sb = new StringBuilder(); sb.append(this.getActivatingPlayer()).append(" has suspended "); sb.append(c.getName()).append("with "); - sb.append(suspendCounters).append(" time counters on it."); + sb.append(counters).append(" time counters on it."); AllZone.getGameLog().add("ResolveStack", sb.toString(), 2); } }; final StringBuilder sbDesc = new StringBuilder(); - sbDesc.append("Suspend ").append(suspendCounters).append(" - ").append(suspendCost); + sbDesc.append("Suspend ").append(timeCounters).append(" - ").append(cost.toSimpleString()); suspend.setDescription(sbDesc.toString()); final StringBuilder sbStack = new StringBuilder(); sbStack.append(sourceCard.getName()).append(" suspending for "); - sbStack.append(suspendCounters).append(" turns.)"); + sbStack.append(timeCounters).append(" turns.)"); suspend.setStackDescription(sbStack.toString()); suspend.getRestrictions().setZone(ZoneType.Hand); @@ -4232,7 +4235,7 @@ public class CardFactoryUtil { card.setSuspend(true); final String[] k = parse.split(":"); - final int timeCounters = Integer.parseInt(k[1]); + final String timeCounters = k[1]; final String cost = k[2]; card.addSpellAbility(CardFactoryUtil.abilitySuspend(card, cost, timeCounters)); } diff --git a/src/main/java/forge/card/cost/Cost.java b/src/main/java/forge/card/cost/Cost.java index 5e0c5e80760..ac608bffd3b 100644 --- a/src/main/java/forge/card/cost/Cost.java +++ b/src/main/java/forge/card/cost/Cost.java @@ -164,6 +164,7 @@ public class Cost { private static final String EXILE_FROM_TOP_STR = "ExileFromTop<"; private static final String RETURN_STR = "Return<"; private static final String REVEAL_STR = "Reveal<"; + private static final String XCANTBE0_STR = "XCantBe0"; public Cost(final Card card, CardManaCost cost, final boolean bAbility) { this(card, cost.toString(), bAbility); @@ -346,6 +347,11 @@ public class Cost { manaLocation++; } + boolean xCantBe0 = parse.contains(XCANTBE0_STR); + if (xCantBe0) { + parse = parse.replaceAll(XCANTBE0_STR, ""); + } + final String stripXCost = parse.replaceAll("X", ""); final int amountX = parse.length() - stripXCost.length(); @@ -356,7 +362,7 @@ public class Cost { } if ((amountX > 0) || !mana.equals("0")) { - this.costParts.add(manaLocation, new CostMana(mana, amountX)); + this.costParts.add(manaLocation, new CostMana(mana, amountX, xCantBe0)); } } @@ -428,7 +434,7 @@ public class Cost { if (!costChanged) { // Spells with a cost of 0 should be affected too final ManaCost changedCost = Singletons.getModel().getGameAction().getSpellCostChange(sa, new ManaCost("0")); - this.costParts.add(new CostMana(changedCost.toString(), 0)); + this.costParts.add(new CostMana(changedCost.toString(), 0, false)); } } diff --git a/src/main/java/forge/card/cost/CostMana.java b/src/main/java/forge/card/cost/CostMana.java index f35a3c56413..4258e96a2ea 100644 --- a/src/main/java/forge/card/cost/CostMana.java +++ b/src/main/java/forge/card/cost/CostMana.java @@ -44,6 +44,7 @@ public class CostMana extends CostPart { private String mana = ""; private int amountX = 0; private String adjustedMana = ""; + private boolean xCantBe0 = false; /** * Gets the mana. @@ -112,6 +113,20 @@ public class CostMana extends CostPart { this.adjustedMana = adjustedMana; } + /** + * @return the xCantBe0 + */ + public boolean isxCantBe0() { + return xCantBe0; + } + + /** + * @param xCantBe00 the xCantBe0 to set + */ + public void setxCantBe0(boolean xCantBe0) { + this.xCantBe0 = xCantBe0; // TODO: Add 0 to parameter's name. + } + /** * Gets the mana to pay. * @@ -133,12 +148,14 @@ public class CostMana extends CostPart { * the mana * @param amount * the amount + * @param xCantBe0 TODO */ - public CostMana(final String mana, final int amount) { + public CostMana(final String mana, final int amount, boolean xCantBe0) { this.mana = mana.trim(); this.amountX = amount; this.setUndoable(true); this.setReusable(true); + this.setxCantBe0(xCantBe0); } /* @@ -154,7 +171,7 @@ public class CostMana extends CostPart { if (!this.mana.equals("0")) { sb.append(this.mana); } - + return sb.toString().trim(); } @@ -264,21 +281,23 @@ public class CostMana extends CostPart { @Override public void showMessage() { - if (this.manaCost.toString().equals(Integer.toString(numX))) { - // only - // cancel - // if - // partially - // paid - // an X - // value - ButtonUtil.enableAll(); - } else { + if ((xPaid == 0 && costMana.isxCantBe0()) || + !this.manaCost.toString().equals(Integer.toString(numX))) { ButtonUtil.enableOnlyCancel(); + // only cancel if partially paid an X value + // or X is 0, and x can't be 0 + } else { + ButtonUtil.enableAll(); } - - CMatchUI.SINGLETON_INSTANCE.showMessage( - "Pay X Mana Cost for " + sa.getSourceCard().getName() + "\n" + this.xPaid + " Paid so far."); + + StringBuilder msg = new StringBuilder("Pay X Mana Cost for "); + msg.append(sa.getSourceCard().getName()).append("\n").append(this.xPaid); + msg.append(" Paid so far."); + if (costMana.isxCantBe0()) { + msg.append(" X Can't be 0."); + } + + CMatchUI.SINGLETON_INSTANCE.showMessage(msg.toString()); } // selectCard diff --git a/src/main/java/forge/card/cost/CostPayment.java b/src/main/java/forge/card/cost/CostPayment.java index a823e33009e..afde7583b1f 100644 --- a/src/main/java/forge/card/cost/CostPayment.java +++ b/src/main/java/forge/card/cost/CostPayment.java @@ -293,7 +293,7 @@ public class CostPayment { final ArrayList parts = this.cost.getCostParts(); if (this.getCost().getCostMana() == null) { - parts.add(new CostMana("0", 0)); + parts.add(new CostMana("0", 0, false)); } // Set all of the decisions before attempting to pay anything