- Added ChromaSource xCost (useful with Remembered and other list based calculate Amount). This should allow for most of the remaining Chroma cards to be scripted.

- Convert Sanity Grinding to script
This commit is contained in:
Sol
2013-02-23 23:31:28 +00:00
parent 502a28fe9b
commit d9da16954f
3 changed files with 33 additions and 487 deletions

View File

@@ -1,7 +1,10 @@
Name:Sanity Grinding
ManaCost:U U U
Types:Sorcery
Text:Chroma - Reveal the top ten cards of your library. For each blue mana symbol in the mana costs of the revealed cards, target opponent puts the top card of his or her library into his or her graveyard. Then put the cards you revealed this way on the bottom of your library in any order.
A:SP$ Dig | Cost$ U U U | DigNum$ 10 | Reveal$ True | ChangeNum$ 0 | RememberRevealed$ True | SubAbility$ MillTargeted | SpellDescription$ Chroma - Reveal the top ten cards of your library. For each blue mana symbol in the mana costs of the revealed cards, target opponent puts the top card of his or her library into his or her graveyard. Then put the cards you revealed this way on the bottom of your library in any order.
SVar:MillTargeted:DB$ Mill | NumCards$ X | ValidTgts$ Player | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:X:Remembered$ChromaSource.U
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/sanity_grinding.jpg
SetInfo:EVE|Rare|http://magiccards.info/scans/en/eve/29.jpg

View File

@@ -603,482 +603,6 @@ public class CardFactorySorceries {
return spell;
}
private static final SpellAbility getSanityGrinding(final Card card) {
/*
* Chroma - Reveal the top ten cards of your library. For each blue
* mana symbol in the mana costs of the revealed cards, target
* opponent puts the top card of his or her library into his or her
* graveyard. Then put the cards you revealed this way on the bottom
* of your library in any order.
*/
return new Spell(card) {
private static final long serialVersionUID = 4475834103787262421L;
@Override
public void resolve() {
final Player player = card.getController();
final Player opp = player.getOpponent();
final PlayerZone lib = card.getController().getZone(ZoneType.Library);
int maxCards = lib.size();
maxCards = Math.min(maxCards, 10);
if (maxCards == 0) {
return;
}
final List<Card> topCards = new ArrayList<Card>();
// show top n cards:
for (int j = 0; j < maxCards; j++) {
topCards.add(lib.get(j));
}
final int num = CardFactoryUtil.getNumberOfManaSymbolsByColor("U", topCards);
final StringBuilder sb = new StringBuilder();
sb.append("Revealed cards - ").append(num).append(" U mana symbols");
GuiChoose.oneOrNone(sb.toString(), topCards);
// opponent moves this many cards to graveyard
opp.mill(num);
// then, move revealed cards to bottom of library
for (final Card c : topCards) {
Singletons.getModel().getGame().getAction().moveToBottomOfLibrary(c);
}
} // resolve()
@Override
public boolean canPlayAI() {
return !getActivatingPlayer().getZone(ZoneType.Library).isEmpty();
}
};
}
/*private static final SpellAbility getProfaneCommand(final Card card) {
// not sure what to call variables, so I just made up something
final Player[] ab0player = new Player[1];
final Card[] ab1card = new Card[1];
final Card[] ab2card = new Card[1];
final ArrayList<Card> ab3cards = new ArrayList<Card>();
final int[] x = new int[1];
final ArrayList<String> userChoice = new ArrayList<String>();
final String[] cardChoice = {
"Target player loses X life",
"Return target creature card with converted mana cost X "
+ "or less from your graveyard to the battlefield",
"Target creature gets -X/-X until end of turn",
"Up to X target creatures gain fear until end of turn" };
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = -2924301460675657126L;
@Override
public void resolve() {
// System.out.println(userChoice);
// System.out.println("0: "+ab0player[0]);
// System.out.println("1: "+ab1card[0]);
// System.out.println("2: "+ab2card[0]);
// System.out.println("3: "+ab3cards);
// "Target player loses X life",
for (int i = 0; i < card.getChoices().size(); i++) {
if (card.getChoice(i).equals(cardChoice[0])) {
if (ab0player[0] != null) {
this.setTargetPlayer(ab0player[0]);
if (this.getTargetPlayer().canBeTargetedBy(this)) {
this.getTargetPlayer().addDamage(x[0], card);
}
}
}
}
// "Return target creature card with converted mana cost
// X or less from your graveyard to the battlefield",
if (userChoice.contains(cardChoice[1]) || card.getChoices().contains(cardChoice[1])) {
final Card c = ab1card[0];
if (c != null) {
if (card.getController().getZone(ZoneType.Graveyard).contains(c) && c.canBeTargetedBy(this)) {
Singletons.getModel().getGame().getAction().moveToPlay(c);
}
}
}
// "Target creature gets -X/-X until end of turn",
for (int i = 0; i < card.getChoices().size(); i++) {
if (card.getChoice(i).equals(cardChoice[2])) {
final Card c = ab2card[0];
if (c != null) {
if (c.isInPlay() && c.canBeTargetedBy(this)) {
final int boost = x[0] * -1;
c.addTempAttackBoost(boost);
c.addTempDefenseBoost(boost);
final Command untilEOT = new Command() {
private static final long serialVersionUID = -6010783402521993651L;
@Override
public void execute() {
if (c.isInPlay()) {
c.addTempAttackBoost(-1 * boost);
c.addTempDefenseBoost(-1 * boost);
}
}
};
Singletons.getModel().getGame().getEndOfTurn().addUntil(untilEOT);
}
}
}
} // end ab[2]
// "Up to X target creatures gain fear until end of turn"
if (userChoice.contains(cardChoice[3]) || card.getChoices().contains(cardChoice[3])) {
final ArrayList<Card> cs = new ArrayList<Card>();
cs.addAll(ab3cards);
for (final Card c : cs) {
if (c.isInPlay() && c.canBeTargetedBy(this)) {
c.addExtrinsicKeyword("Fear");
final Command untilEOT = new Command() {
private static final long serialVersionUID = 986259855862338866L;
@Override
public void execute() {
if (c.isInPlay()) {
c.removeExtrinsicKeyword("Fear");
}
}
};
Singletons.getModel().getGame().getEndOfTurn().addUntil(untilEOT);
}
}
} // end ab[3]
} // resolve()
@Override
public boolean canPlayAI() {
return false;
}
}; // SpellAbility
final Command setStackDescription = new Command() {
private static final long serialVersionUID = 5840471361149632482L;
@Override
public void execute() {
final ArrayList<String> a = new ArrayList<String>();
if (userChoice.contains(cardChoice[0]) || card.getChoices().contains(cardChoice[0])) {
a.add(ab0player[0] + " loses X life");
}
if (userChoice.contains(cardChoice[1]) || card.getChoices().contains(cardChoice[1])) {
a.add("return " + ab1card[0] + " from graveyard to play");
}
if (userChoice.contains(cardChoice[2]) || card.getChoices().contains(cardChoice[2])) {
a.add(ab2card[0] + " gets -X/-X until end of turn");
}
if (userChoice.contains(cardChoice[3]) || card.getChoices().contains(cardChoice[3])) {
a.add("up to X target creatures gain Fear until end of turn");
}
final String s = a.get(0) + ", " + a.get(1);
spell.setStackDescription(card.getName() + " - " + s);
}
}; // Command
// for ab[3] - X creatures gain fear until EOT
final Input targetXCreatures = new Input() {
private static final long serialVersionUID = 2584765431286321048L;
private int stop = 0;
private int count = 0;
@Override
public void showMessage() {
if (this.count == 0) {
this.stop = x[0];
}
final StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - Select a target creature to gain Fear (up to ");
sb.append(this.stop - this.count).append(" more)");
CMatchUI.SINGLETON_INSTANCE.showMessage(sb.toString());
ButtonUtil.enableAllFocusOk();
}
@Override
public void selectButtonCancel() {
this.stop();
}
@Override
public void selectButtonOK() {
this.done();
}
@Override
public void selectCard(final Card c) {
Zone zone = Singletons.getModel().getGame().getZoneOf(c);
if (c.isCreature() && zone.is(ZoneType.Battlefield) && c.canBeTargetedBy(spell)
&& !ab3cards.contains(c)) {
ab3cards.add(c);
this.count++;
if (this.count == this.stop) {
this.done();
} else {
this.showMessage();
}
}
} // selectCard()
private void done() {
setStackDescription.execute();
this.stopSetNext(new InputPayManaSimple(Singletons.getModel().getGame(), spell));
}
};
// for ab[2] target creature gets -X/-X
final Input targetCreature = new Input() {
private static final long serialVersionUID = -6879692803780014943L;
@Override
public void showMessage() {
final StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - Select target creature to get -X/-X");
CMatchUI.SINGLETON_INSTANCE.showMessage(sb.toString());
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
this.stop();
}
@Override
public void selectCard(final Card c) {
Zone zone = Singletons.getModel().getGame().getZoneOf(c);
if (c.isCreature() && zone.is(ZoneType.Battlefield) && c.canBeTargetedBy(spell)) {
ab2card[0] = c;
setStackDescription.execute();
if (userChoice.contains(cardChoice[3]) || card.getChoices().contains(cardChoice[3])) {
this.stopSetNext(targetXCreatures);
} else {
final StringBuilder sb = new StringBuilder();
sb.append("Input_PayManaCost for spell is getting: ");
sb.append(spell.getManaCost());
System.out.println(sb.toString());
this.stopSetNext(new InputPayManaSimple(Singletons.getModel().getGame(), spell));
}
} // if
} // selectCard()
}; // Input targetCreature
// for ab[1] - return creature from grave to the battlefield
final Input targetGraveCreature = new Input() {
private static final long serialVersionUID = -7558252187229252725L;
@Override
public void showMessage() {
List<Card> grave = CardLists.filter(card.getController().getCardsIn(ZoneType.Graveyard), Presets.CREATURES);
grave = CardLists.filter(grave, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return c.getCMC() <= x[0];
}
});
final Card check = GuiChoose.oneOrNone("Select target creature with CMC < X", grave);
if (check != null) {
final Card c = check;
if (c.canBeTargetedBy(spell)) {
ab1card[0] = c;
}
} else {
this.stop();
}
this.done();
} // showMessage()
public void done() {
if (userChoice.contains(cardChoice[2]) || card.getChoices().contains(cardChoice[2])) {
this.stopSetNext(targetCreature);
} else if (userChoice.contains(cardChoice[3]) || card.getChoices().contains(cardChoice[3])) {
this.stopSetNext(targetXCreatures);
} else {
this.stopSetNext(new InputPayManaSimple(Singletons.getModel().getGame(), spell));
}
}
}; // Input
// for ab[0] - target player loses X life
final Input targetPlayer = new Input() {
private static final long serialVersionUID = 9101387253945650303L;
@Override
public void showMessage() {
final StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - Select target player to lose life");
CMatchUI.SINGLETON_INSTANCE.showMessage(sb.toString());
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
this.stop();
}
@Override
public void selectPlayer(final Player player) {
if (player.canBeTargetedBy(spell)) {
ab0player[0] = player;
setStackDescription.execute();
if (userChoice.contains(cardChoice[1]) || card.getChoices().contains(cardChoice[1])) {
this.stopSetNext(targetGraveCreature);
} else if (userChoice.contains(cardChoice[2]) || card.getChoices().contains(cardChoice[2])) {
this.stopSetNext(targetCreature);
} else if (userChoice.contains(cardChoice[3]) || card.getChoices().contains(cardChoice[3])) {
this.stopSetNext(targetXCreatures);
} else {
this.stopSetNext(new InputPayManaSimple(Singletons.getModel().getGame(), spell));
}
}
} // selectPlayer()
}; // Input targetPlayer
final Input chooseX = new Input() {
private static final long serialVersionUID = 5625588008756700226L;
@Override
public void showMessage() {
if (card.isCopiedSpell()) {
x[0] = 0;
if (userChoice.contains(cardChoice[0])) {
this.stopSetNext(targetPlayer);
} else if (userChoice.contains(cardChoice[1])) {
this.stopSetNext(targetGraveCreature);
} else if (userChoice.contains(cardChoice[2])) {
this.stopSetNext(targetCreature);
} else if (userChoice.contains(cardChoice[3])) {
this.stopSetNext(targetXCreatures);
} else {
throw new RuntimeException(
"Something in if(isCopiedSpell()) in Profane Command selection is FUBAR.");
}
} else {
final int max = card.getController().getLife();
final Integer[] choices = new Integer[max + 1];
for (int i = 0; i <= max; i++) {
choices[i] = Integer.valueOf(i);
}
final Integer answer = GuiChoose.one("Choose X", choices);
// everything stops here if user cancelled
if (answer == null) {
this.stop();
return;
}
x[0] = answer;
spell.setManaCost(new SpellManaCost( new ManaCostParser(x[0] + " B B")));
spell.setIsXCost(false);
if (userChoice.contains(cardChoice[0])) {
this.stopSetNext(targetPlayer);
} else if (userChoice.contains(cardChoice[1])) {
this.stopSetNext(targetGraveCreature);
} else if (userChoice.contains(cardChoice[2])) {
this.stopSetNext(targetCreature);
} else if (userChoice.contains(cardChoice[3])) {
this.stopSetNext(targetXCreatures);
} else {
throw new RuntimeException("Something in Profane Command selection is FUBAR.");
}
}
} // showMessage()
}; // Input chooseX
final Input chooseTwoInput = new Input() {
private static final long serialVersionUID = 5625588008756700226L;
@Override
public void showMessage() {
if (card.isCopiedSpell()) {
if (userChoice.contains(cardChoice[0])) {
this.stopSetNext(targetPlayer);
} else if (userChoice.contains(cardChoice[1])) {
this.stopSetNext(targetGraveCreature);
} else if (userChoice.contains(cardChoice[2])) {
this.stopSetNext(targetCreature);
} else if (userChoice.contains(cardChoice[3])) {
this.stopSetNext(targetXCreatures);
} else {
throw new RuntimeException(
"Something in if(isCopiedSpell()) in Profane Command selection is FUBAR.");
}
} else {
// reset variables
ab0player[0] = null;
ab1card[0] = null;
ab2card[0] = null;
ab3cards.clear();
userChoice.clear();
final ArrayList<String> display = new ArrayList<String>();
// get all
final List<Card> creatures =
CardLists.filter(Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield), Presets.CREATURES);
List<Card> grave = CardLists.filter(card.getController().getCardsIn(ZoneType.Graveyard), Presets.CREATURES);
for (Player p : Singletons.getModel().getGame().getPlayers()) {
if (p.canBeTargetedBy(spell)) {
display.add("Target player loses X life");
break;
}
}
if (grave.size() > 0) {
display.add("Return target creature card with converted mana "
+ "cost X or less from your graveyard to the battlefield");
}
if (creatures.size() > 0) {
display.add("Target creature gets -X/-X until end of turn");
}
display.add("Up to X target creatures gain fear until end of turn");
final ArrayList<String> a = this.chooseTwo(display);
// everything stops here if user cancelled
if (a == null) {
this.stop();
return;
}
userChoice.addAll(a);
this.stopSetNext(chooseX);
}
} // showMessage()
private ArrayList<String> chooseTwo(final ArrayList<String> choices) {
final ArrayList<String> out = new ArrayList<String>();
Object o = GuiChoose.oneOrNone("Choose Two", choices);
if (o == null) {
return null;
}
out.add((String) o);
choices.remove(out.get(0));
o = GuiChoose.oneOrNone("Choose Two", choices);
if (o == null) {
return null;
}
out.add((String) o);
card.setSpellChoice(out);
return out;
} // chooseTwo()
}; // Input chooseTwoInput
spell.setBeforePayMana(chooseTwoInput);
card.setSpellWithChoices(true);
return spell;
}*/
private static final SpellAbility getTransmuteArtifact(final Card card) {
/*
* Sacrifice an artifact. If you do, search your library for an
@@ -1165,7 +689,6 @@ public class CardFactorySorceries {
} else if (cardName.equals("Global Ruin")) { card.addSpellAbility(getGlobalRuin(card));
} else if (cardName.equals("Balance")) { card.addSpellAbility(getBalance(card));
} else if (cardName.equals("Patriarch's Bidding")) { card.addSpellAbility(getPatriarchsBidding(card));
} else if (cardName.equals("Sanity Grinding")) { card.addSpellAbility(getSanityGrinding(card));
} else if (cardName.equals("Transmute Artifact")) { card.addSpellAbility(getTransmuteArtifact(card));
}
} // getCard

View File

@@ -1377,21 +1377,32 @@ public class CardFactoryUtil {
* @param colorAbb
* a {@link java.lang.String} object.
* @param cards
* a {@link forge.CardList} object.
* a {@link forge.List<Card>} object.
* @return a int.
*/
public static int getNumberOfManaSymbolsByColor(final String colorAbb, final List<Card> cards) {
int count = 0;
for (int i = 0; i < cards.size(); i++) {
final Card c = cards.get(i);
if (!c.isToken()) {
String manaCost = c.getManaCost().toString();
manaCost = manaCost.trim();
count += CardFactoryUtil.countOccurrences(manaCost, colorAbb);
}
for(Card c : cards) {
// Certain tokens can have mana cost, so don't skip them
count += CardFactoryUtil.getNumberOfManaSymbolsByColor(colorAbb, c);
}
return count;
}
/**
* <p>
* getNumberOfManaSymbolsByColor.
* </p>
*
* @param colorAbb
* a {@link java.lang.String} object.
* @param card
* a {@link forge.Card} object.
* @return a int.
*/
public static int getNumberOfManaSymbolsByColor(final String colorAbb, final Card card) {
return CardFactoryUtil.countOccurrences(card.getManaCost().toString().trim(), colorAbb);
}
/**
* <p>
@@ -2311,9 +2322,18 @@ public class CardFactoryUtil {
// Count$Chroma.<mana letter>
if (sq[0].contains("Chroma")) {
return CardFactoryUtil.doXMath(
if (sq[0].contains("ChromaSource")) {
// Runs Chroma for passed in Source card
List<Card> chromaList = CardLists.createCardList(c);
return CardFactoryUtil.doXMath(CardFactoryUtil.getNumberOfManaSymbolsByColor(sq[1], chromaList), m, c);
}
else {
return CardFactoryUtil.doXMath(
CardFactoryUtil.getNumberOfManaSymbolsControlledByColor(sq[1], cardController), m, c);
}
}
// Count$Hellbent.<numHB>.<numNotHB>
if (sq[0].contains("Hellbent")) {