mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
- 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:
@@ -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
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
Reference in New Issue
Block a user