mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
- Cathartic Adept should tap when using its ability.
- Added Arid Mesa, Marsh Flats, Misty Rainforest, Scalding Tarn, Verdant Catacombs, Bloodstained Mire, Flooded Strand, Polluted Delta, Windswept Heath, Wooded Foothills. - Added Rob's abPumpTgt keyword, including a bunch of new cards supported by it.
This commit is contained in:
@@ -18,6 +18,15 @@ forest.jpg http://resources.wizards.com/magic/cards/unh/en-us/card73946.jpg
|
||||
forest1.jpg http://gatherer.wizards.com/handlers/image.ashx?type=card&multiverseid=2748
|
||||
forest2.jpg http://gatherer.wizards.com/handlers/image.ashx?type=card&multiverseid=587
|
||||
forest3.jpg http://gatherer.wizards.com/handlers/image.ashx?type=card&multiverseid=586
|
||||
wooded_foothills.jpg http://www.wizards.com/global/images/magic/general/wooded_foothills.jpg
|
||||
windswept_heath.jpg http://www.wizards.com/global/images/magic/general/windswept_heath.jpg
|
||||
polluted_delta.jpg http://www.wizards.com/global/images/magic/general/polluted_delta.jpg
|
||||
flooded_strand.jpg http://www.wizards.com/global/images/magic/general/flooded_strand.jpg
|
||||
bloodstaind_mire.jpg http://www.wizards.com/global/images/magic/general/bloodstained_mire.jpg
|
||||
verdant_catacombs.jpg http://www.wizards.com/global/images/magic/general/verdant_catacombs.jpg
|
||||
scalding_tarn.jpg http://www.wizards.com/global/images/magic/general/scalding_tarn.jpg
|
||||
marsh_flats.jpg http://www.wizards.com/global/images/magic/general/marsh_flats.jpg
|
||||
arid_mesa.jpg http://www.wizards.com/global/images/magic/general/arid_mesa.jpg
|
||||
serpent_generator.jpg http://www.wizards.com/global/images/magic/general/serpent_generator.jpg
|
||||
pit_scorpion.jpg http://www.wizards.com/global/images/magic/general/pit_scorpion.jpg
|
||||
bridge_from_below.jpg http://www.wizards.com/global/images/magic/general/bridge_from_below.jpg
|
||||
|
||||
174
res/cards.txt
174
res/cards.txt
@@ -1,3 +1,169 @@
|
||||
Feral Animist
|
||||
1 R G
|
||||
Creature Goblic Shaman
|
||||
no text
|
||||
2/1
|
||||
abPump 3:Count$CardPower/+0:Feral Animist gets +X/+0 until end of turn, where X is its power.
|
||||
|
||||
Fire-Belly Changeling
|
||||
1 R
|
||||
Creature Shapeshifter
|
||||
Play this ability no more than twice each turn.
|
||||
1/1
|
||||
abPump R:+1/+0
|
||||
|
||||
Kitsune Loreweaver
|
||||
1 W
|
||||
Creature Fox Cleric
|
||||
no text
|
||||
2/1
|
||||
abPump 1 W:+0/Count$NumCardsInYourHand:Kitsune Loreweaver get +0/+X until end of turn, where X is the number of cards in your hand.
|
||||
|
||||
Knight of the Skyward Eye
|
||||
1 W
|
||||
Creature Human Knight
|
||||
Play this ability only once each turn.
|
||||
2/2
|
||||
abPump 3 G:+3/+3
|
||||
|
||||
Power Armor
|
||||
4
|
||||
Artifact
|
||||
Domain
|
||||
abPumpTgt 3 T:Count$Domain/Count$Domain:Target creature gets +1/+1 until end of turn for each basic land type among lands you control.
|
||||
|
||||
Seedcradle Witch
|
||||
GW
|
||||
Creature Elf Shaman
|
||||
no text
|
||||
1/1
|
||||
abPumpTgt 2 G W:+3/+3:Drawback$UntapTgt:Target creature gets +3/+3 until end of turn. Untap that creature.
|
||||
|
||||
Stormcloud Djinn
|
||||
4 U
|
||||
Creature Djinn
|
||||
no text
|
||||
3/3
|
||||
Flying
|
||||
This creature can block only creatures with flying.
|
||||
abPump R R:+2/+0:Drawback$DamageYou/1:Stormcloud Djinn gets +2/+0 until end of turn and deals 1 damage to you.
|
||||
|
||||
Timberwatch Elf
|
||||
2 G
|
||||
Creature Elf
|
||||
no text
|
||||
1/2
|
||||
abPumpTgt T:Count$TypeOnBattlefield.Elf/Count$TypeOnBattlefield.Elf:Target creature get +X/+X until end of turn, where X is the number of Elves on the battlefield.
|
||||
|
||||
Wandering Goblins
|
||||
2 R
|
||||
Creature Goblin Warrior
|
||||
Domain
|
||||
0/3
|
||||
abPump 3:Count$Domain/+0:Wandering Goblins gets +1/+0 until end of turn for each basic land type among lands you control.
|
||||
|
||||
Rappelling Scouts
|
||||
2 W W
|
||||
Creature Human Rebel Scout
|
||||
no text
|
||||
1/4
|
||||
Flying
|
||||
abPumpTgt 2 W:Protection from white
|
||||
abPumpTgt 2 W:Protection from blue
|
||||
abPumpTgt 2 W:Protection from black
|
||||
abPumpTgt 2 W:Protection from red
|
||||
abPumpTgt 2 W:Protection from green
|
||||
|
||||
Jodah's Avenger
|
||||
5 U
|
||||
Creature Shapeshifter
|
||||
no text
|
||||
4/4
|
||||
abPump 0:-1/-1/Double Strike
|
||||
abPump 0:-1/-1/Protection from red
|
||||
abPump 0:-1/-1/Vigilance
|
||||
abPump 0:-1/-1/Shadow
|
||||
|
||||
Wormwood Dryad
|
||||
2 G
|
||||
Creature Dryad
|
||||
no text
|
||||
3/1
|
||||
abPump G:Forestwalk:Drawback$DamageYou/1:Wormwood Dryad gains forestwalk until end of turn and deals 1 damage to you.
|
||||
abPump B:Swampwalk:Drawback$DamageYou/1:Wormwood Dryad gains swampwalk until end of turn and deals 1 damage to you.
|
||||
|
||||
Wormwood Treefolk
|
||||
3 G G
|
||||
Creature Treefolk
|
||||
no text
|
||||
4/4
|
||||
abPump G G:Forestwalk:Drawback$DamageYou/2:Wormwood Dryad gains forestwalk until end of turn and deals 2 damage to you.
|
||||
abPump B B:Swampwalk:Drawback$DamageYou/2:Wormwood Dryad gains swampwalk until end of turn and deals 2 damage to you.
|
||||
|
||||
Auriok Bladewarden
|
||||
1 W
|
||||
Creature Human Soldier
|
||||
no text
|
||||
1/1
|
||||
abPumpTgt T:Count$CardPower/Count$CardPower:Target creature get +X/+X until end of turn, where X is Auriok Bladewarden's power.
|
||||
|
||||
Boreal Centaur
|
||||
1 G
|
||||
Snow Creature Centaur Warrior
|
||||
Play this ability only once each turn.
|
||||
2/2
|
||||
abPump S:+1/+1
|
||||
|
||||
Wooded Foothills
|
||||
no cost
|
||||
Land
|
||||
no text
|
||||
|
||||
Windswept Heath
|
||||
no cost
|
||||
Land
|
||||
no text
|
||||
|
||||
Polluted Delta
|
||||
no cost
|
||||
Land
|
||||
no text
|
||||
|
||||
Flooded Strand
|
||||
no cost
|
||||
Land
|
||||
no text
|
||||
|
||||
Bloodstained Mire
|
||||
no cost
|
||||
Land
|
||||
no text
|
||||
|
||||
Verdant Catacombs
|
||||
no cost
|
||||
Land
|
||||
no text
|
||||
|
||||
Scalding Tarn
|
||||
no cost
|
||||
Land
|
||||
no text
|
||||
|
||||
Misty Rainforest
|
||||
no cost
|
||||
Land
|
||||
no text
|
||||
|
||||
Marsh Flats
|
||||
no cost
|
||||
Land
|
||||
no text
|
||||
|
||||
Arid Mesa
|
||||
no cost
|
||||
Land
|
||||
no text
|
||||
|
||||
Serpent Generator
|
||||
6
|
||||
Artifact
|
||||
@@ -1119,6 +1285,7 @@ no cost
|
||||
Land
|
||||
no text
|
||||
tap: add 1
|
||||
abPumpTgt R G T:+1/+1/Trample
|
||||
|
||||
Goblin Burrows
|
||||
no cost
|
||||
@@ -6060,6 +6227,7 @@ no text
|
||||
4/4
|
||||
Changeling
|
||||
Protection from black
|
||||
abPump 2 G G:Count$CardPower/Count$CardPower:Chameleon Colossus gets +X/+X until end of turn, where X is its power.
|
||||
|
||||
Rakdos Pit Dragon
|
||||
2 R R
|
||||
@@ -14260,12 +14428,6 @@ Creature Hound
|
||||
(NOTE: " and becomes color of your choice." not implemented.)
|
||||
2/2
|
||||
|
||||
Timberwatch Elf
|
||||
2 G
|
||||
Creature Elf
|
||||
no text
|
||||
1/2
|
||||
|
||||
Wirewood Elf
|
||||
1 G
|
||||
Creature Elf
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
program/mail=mtgerror@yahoo.com
|
||||
program/forum=http://www.slightlymagic.net/forum/viewforum.php?f=26
|
||||
program/version=Forge -- official beta: 09/12/14, SVN revision: 214
|
||||
program/version=Forge -- official beta: 09/12/14, SVN revision: 215
|
||||
|
||||
tokens--file=AllTokens.txt
|
||||
|
||||
|
||||
@@ -818,6 +818,628 @@ public class CardFactory implements NewConstants {
|
||||
} //if (should RegenerateMe)
|
||||
} //while - card has more RegenerateMe - Jungle Troll has two Regenerate keywords
|
||||
|
||||
while(hasKeyword(card, "abPump") != -1)
|
||||
{
|
||||
int n = hasKeyword(card, "abPump");
|
||||
if(n != -1)
|
||||
{
|
||||
String parse = card.getKeyword().get(n).toString();
|
||||
card.removeIntrinsicKeyword(parse);
|
||||
|
||||
String k[] = parse.split(":");
|
||||
|
||||
final boolean Tgt[] = {false};
|
||||
Tgt[0] = k[0].contains("Tgt");
|
||||
|
||||
String tmpCost;
|
||||
if (Tgt[0])
|
||||
tmpCost = k[0].substring(9);
|
||||
else
|
||||
tmpCost = k[0].substring(6);
|
||||
|
||||
boolean tapCost = false;
|
||||
boolean tapOnlyCost = false;
|
||||
|
||||
if (tmpCost.contains("T"))
|
||||
{
|
||||
tapCost = true;
|
||||
tmpCost = tmpCost.replace("T", "");
|
||||
tmpCost = tmpCost.trim();
|
||||
if (tmpCost.length() == 0)
|
||||
tapOnlyCost = true;
|
||||
}
|
||||
final String manaCost = tmpCost.trim();
|
||||
|
||||
final int NumAttack[] = {-1138};
|
||||
final String AttackX[] = {"none"};
|
||||
final int NumDefense[] = {-1138};
|
||||
final String DefenseX[] = {"none"};
|
||||
final String Keyword[] = {"none"};
|
||||
|
||||
String ptk[] = k[1].split("/");
|
||||
|
||||
if (ptk.length == 1)
|
||||
Keyword[0] = ptk[0];
|
||||
|
||||
if (ptk.length >= 2)
|
||||
{
|
||||
if (ptk[0].length() <= 3)
|
||||
NumAttack[0] = Integer.parseInt(ptk[0].replace("+", ""));
|
||||
else
|
||||
if (ptk[0].startsWith("Count$"))
|
||||
{
|
||||
String kk[] = ptk[0].split("\\$");
|
||||
AttackX[0] = kk[1].replace("\\", "/");
|
||||
}
|
||||
|
||||
if (ptk[1].length() <= 3)
|
||||
NumDefense[0] = Integer.parseInt(ptk[1].replace("+", ""));
|
||||
else
|
||||
if (ptk[1].startsWith("Count$"))
|
||||
{
|
||||
String kk[] = ptk[1].split("\\$");
|
||||
DefenseX[0] = kk[1].replace("\\", "/");
|
||||
}
|
||||
}
|
||||
|
||||
if (ptk.length == 3)
|
||||
Keyword[0] = ptk[2];
|
||||
|
||||
final String DrawBack[] = {"none"};
|
||||
final String spDesc[] = {"none"};
|
||||
final String stDesc[] = {"none"};
|
||||
String d = new String("none");
|
||||
|
||||
if ((AttackX[0].equals("none") && !(NumAttack[0] == -1138)) && (DefenseX[0].equals("none") && !(NumDefense[0] == -1138)) && Keyword[0].equals("none"))
|
||||
{
|
||||
// pt boost
|
||||
if (Tgt[0] == true)
|
||||
d = "Target creature gets ";
|
||||
else
|
||||
d = cardName + " gets ";
|
||||
|
||||
if (NumAttack[0] > 0 || (NumAttack[0] == 0 && NumDefense[0] > 0)) // +0/+1
|
||||
d = d + "+";
|
||||
else if (NumAttack[0] < 0 || (NumAttack[0] == 0 && NumDefense[0] < 0)) // -0/-1
|
||||
d = d + "-";
|
||||
|
||||
d = d + Math.abs(NumAttack[0]) + "/";
|
||||
|
||||
if (NumDefense[0] > 0 || (NumDefense[0] == 0 && NumAttack[0] > 0)) // +1/+0
|
||||
d = d + "+";
|
||||
else if (NumDefense[0] < 0 || (NumDefense[0] == 0 && NumAttack[0] < 0)) // -1/-0
|
||||
d = d + "-";
|
||||
|
||||
d = d + Math.abs(NumDefense[0]) + " until end of turn.";
|
||||
}
|
||||
if ((AttackX[0].equals("none") && NumAttack[0] == -1138) && (DefenseX[0].equals("none") && NumDefense[0] == -1138) && !Keyword[0].equals("none"))
|
||||
{
|
||||
// k boost
|
||||
if (Tgt[0] == true)
|
||||
d = "Target creature gains ";
|
||||
else
|
||||
d = cardName + " gains ";
|
||||
|
||||
d = d + Keyword[0] + " until end of turn.";
|
||||
}
|
||||
if ((AttackX[0].equals("none") && !(NumAttack[0] == -1138)) && (DefenseX[0].equals("none") && !(NumDefense[0] == -1138)) && !Keyword[0].equals("none"))
|
||||
{
|
||||
// ptk boost
|
||||
if (Tgt[0] == true)
|
||||
d = "Target creature gets ";
|
||||
else
|
||||
d = cardName + " gets ";
|
||||
|
||||
if (NumAttack[0] > 0 || (NumAttack[0] == 0 && NumDefense[0] > 0)) // +0/+1
|
||||
d = d + "+";
|
||||
else if (NumAttack[0] < 0 || (NumAttack[0] == 0 && NumDefense[0] < 0)) // -0/-1
|
||||
d = d + "-";
|
||||
|
||||
d = d + Math.abs(NumAttack[0]) + "/";
|
||||
|
||||
if (NumDefense[0] > 0 || (NumDefense[0] == 0 && NumAttack[0] > 0)) // +1/+0
|
||||
d = d + "+";
|
||||
else if (NumDefense[0] < 0 || (NumDefense[0] == 0 && NumAttack[0] < 0)) // -1/-0
|
||||
d = d + "-";
|
||||
|
||||
d = d + Math.abs(NumDefense[0]);
|
||||
|
||||
d = d + " and gains " + Keyword[0] + " until end of turn.";
|
||||
}
|
||||
|
||||
if (k.length > 2)
|
||||
{
|
||||
if (k[2].contains("Drawback$"))
|
||||
{
|
||||
String kk[] = k[2].split("\\$");
|
||||
DrawBack[0] = kk[1];
|
||||
if (k.length > 3)
|
||||
d = k[3];
|
||||
}
|
||||
else
|
||||
if (k.length > 2)
|
||||
d = k[2];
|
||||
}
|
||||
|
||||
if (!d.equals("none"))
|
||||
{
|
||||
if (tapOnlyCost == true)
|
||||
spDesc[0] = "Tap: " + d;
|
||||
else if (tapCost == true)
|
||||
spDesc[0] = manaCost + ", tap: " + d;
|
||||
else
|
||||
spDesc[0] = manaCost + ": " + d;
|
||||
|
||||
stDesc[0] = d;
|
||||
}
|
||||
|
||||
if (! tapCost)
|
||||
{
|
||||
final SpellAbility ability = new Ability_Activated(card, manaCost)
|
||||
{
|
||||
private static final long serialVersionUID = -1118592153328758083L;
|
||||
|
||||
private int defense;
|
||||
private String keyword;
|
||||
|
||||
private int getNumAttack()
|
||||
{
|
||||
if (NumAttack[0] != -1138)
|
||||
return NumAttack[0];
|
||||
|
||||
if (! AttackX[0].equals("none"))
|
||||
return CardFactoryUtil.xCount(card, AttackX[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
private int getNumDefense()
|
||||
{
|
||||
if (NumDefense[0] != -1138)
|
||||
return NumDefense[0];
|
||||
|
||||
if (! DefenseX[0].equals("none"))
|
||||
return CardFactoryUtil.xCount(card, DefenseX[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean canPlayAI()
|
||||
{
|
||||
defense = getNumDefense();
|
||||
keyword = Keyword[0];
|
||||
|
||||
if (AllZone.Phase.getPhase().equals(Constant.Phase.Main2))
|
||||
return false;
|
||||
|
||||
if (Tgt[0] == false)
|
||||
{
|
||||
setTargetCard(card);
|
||||
|
||||
if ((card.getNetDefense() + defense > 0) &&
|
||||
(! card.getKeyword().contains(keyword)))
|
||||
if (card.hasSickness() && keyword.equals("Haste"))
|
||||
return true;
|
||||
else if ((card.hasSickness() && (! keyword.equals("Haste"))) ||
|
||||
((! card.hasSickness()) && keyword.equals("Haste")))
|
||||
return false;
|
||||
else
|
||||
{
|
||||
Random r = new Random();
|
||||
if (r.nextFloat() <= Math.pow(.6667, card.getAbilityUsed()))
|
||||
return CardFactoryUtil.AI_doesCreatureAttack(card);
|
||||
}
|
||||
}
|
||||
|
||||
CardList list = getCreatures();
|
||||
if (!list.isEmpty())
|
||||
{
|
||||
boolean goodt = false;
|
||||
Card t = new Card();
|
||||
while (goodt == false && !list.isEmpty()) // loop until we find a target that is best and won't die when targeted or until no more creatures
|
||||
{
|
||||
t = CardFactoryUtil.AI_getBestCreature(list);
|
||||
if ((t.getNetDefense() + defense) > 0) // handle negative defense pumps
|
||||
goodt = true;
|
||||
else
|
||||
list.remove(t);
|
||||
}
|
||||
if (goodt == true)
|
||||
{
|
||||
Random r = new Random();
|
||||
if (r.nextFloat() <= Math.pow(.6667, card.getAbilityUsed()))
|
||||
{
|
||||
setTargetCard(t);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canPlay()
|
||||
{
|
||||
return (CardFactoryUtil.canUseAbility(card)) &&
|
||||
(AllZone.GameAction.isCardInPlay(card)) &&
|
||||
(! card.isFaceDown());
|
||||
}
|
||||
|
||||
private CardList getCreatures()
|
||||
{
|
||||
CardList list = new CardList(AllZone.Computer_Play.getCards());
|
||||
list = list.filter(new CardListFilter()
|
||||
{
|
||||
public boolean addCard(Card c)
|
||||
{
|
||||
if (c.isCreature())
|
||||
{
|
||||
if (c.hasSickness() && keyword.equals("Haste")) // AI_doesCreatureAttack would have prevented the effect from granting haste, because it assumes the creature would already have it
|
||||
return CardFactoryUtil.canTarget(card, c);
|
||||
|
||||
return (CardFactoryUtil.AI_doesCreatureAttack(c)) &&
|
||||
(CardFactoryUtil.canTarget(card, c)) &&
|
||||
(!keyword.equals("none") && !c.getKeyword().contains(keyword)) &&
|
||||
(! (! c.hasSickness()) && keyword.equals("Haste")); // if creature doesn't have sickness, the haste keyword won't help
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
// list.remove(card); // if mana-only cost, allow self-target
|
||||
return list;
|
||||
}//getCreatures()
|
||||
public void resolve()
|
||||
{
|
||||
if(AllZone.GameAction.isCardInPlay(getTargetCard()) && CardFactoryUtil.canTarget(card, getTargetCard()) )
|
||||
{
|
||||
final Card[] creature = new Card[1];
|
||||
if (Tgt[0] == true)
|
||||
creature[0] = getTargetCard();
|
||||
else
|
||||
creature[0] = card;
|
||||
|
||||
final int a = getNumAttack();
|
||||
final int d = getNumDefense();
|
||||
|
||||
final Command EOT = new Command()
|
||||
{
|
||||
private static final long serialVersionUID = -8840812331316327448L;
|
||||
|
||||
public void execute()
|
||||
{
|
||||
if(AllZone.GameAction.isCardInPlay(creature[0]))
|
||||
{
|
||||
creature[0].addTempAttackBoost(-1 * a);
|
||||
creature[0].addTempDefenseBoost(-1 * d);
|
||||
if (! Keyword[0].equals("none"))
|
||||
creature[0].removeExtrinsicKeyword(Keyword[0]);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
creature[0].addTempAttackBoost(a);
|
||||
creature[0].addTempDefenseBoost(d);
|
||||
if (! Keyword[0].equals("none"))
|
||||
creature[0].addExtrinsicKeyword(Keyword[0]);
|
||||
|
||||
card.setAbilityUsed(card.getAbilityUsed()+1);
|
||||
AllZone.EndOfTurn.addUntil(EOT);
|
||||
|
||||
if (! DrawBack[0].equals("none"))
|
||||
CardFactoryUtil.doDrawBack(DrawBack[0], 0, card.getController(), AllZone.GameAction.getOpponent(card.getController()), null, card, creature[0]);
|
||||
|
||||
}//if (card is in play)
|
||||
}//resolve()
|
||||
};//SpellAbility
|
||||
|
||||
ability.setDescription(spDesc[0]);
|
||||
ability.setStackDescription(stDesc[0]);
|
||||
|
||||
if (Tgt[0] == true)
|
||||
ability.setBeforePayMana(CardFactoryUtil.input_targetCreature(ability));
|
||||
else
|
||||
ability.setTargetCard(card);
|
||||
card.addSpellAbility(ability);
|
||||
}
|
||||
if (tapOnlyCost)
|
||||
{
|
||||
final SpellAbility ability = new Ability_Tap(card)
|
||||
{
|
||||
private static final long serialVersionUID = 5252594757468128739L;
|
||||
|
||||
private int defense;
|
||||
private String keyword;
|
||||
|
||||
private int getNumAttack()
|
||||
{
|
||||
if (NumAttack[0] != -1138)
|
||||
return NumAttack[0];
|
||||
|
||||
if (! AttackX[0].equals("none"))
|
||||
return CardFactoryUtil.xCount(card, AttackX[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
private int getNumDefense()
|
||||
{
|
||||
if (NumDefense[0] != -1138)
|
||||
return NumDefense[0];
|
||||
|
||||
if (! DefenseX[0].equals("none"))
|
||||
return CardFactoryUtil.xCount(card, DefenseX[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean canPlayAI()
|
||||
{
|
||||
defense = getNumDefense();
|
||||
keyword = Keyword[0];
|
||||
|
||||
if(CardFactoryUtil.AI_doesCreatureAttack(card))
|
||||
return false;
|
||||
|
||||
if (AllZone.Phase.getPhase().equals(Constant.Phase.Main2))
|
||||
return false;
|
||||
|
||||
CardList list = getCreatures();
|
||||
if (!list.isEmpty())
|
||||
{
|
||||
boolean goodt = false;
|
||||
Card t = new Card();
|
||||
while (goodt == false && !list.isEmpty())
|
||||
{
|
||||
t = CardFactoryUtil.AI_getBestCreature(list);
|
||||
if ((t.getNetDefense() + defense) > 0)
|
||||
goodt = true;
|
||||
else
|
||||
list.remove(t);
|
||||
}
|
||||
if (goodt == true)
|
||||
{
|
||||
setTargetCard(t);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
public boolean canPlay()
|
||||
{
|
||||
boolean sick = true;
|
||||
|
||||
if (!card.hasSickness() || !card.isCreature())
|
||||
sick = false;
|
||||
|
||||
if (card.isUntapped() && AllZone.GameAction.isCardInPlay(card)
|
||||
&& !sick && !card.isFaceDown())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
CardList getCreatures()
|
||||
{
|
||||
CardList list = new CardList(AllZone.Computer_Play.getCards());
|
||||
list = list.filter(new CardListFilter()
|
||||
{
|
||||
public boolean addCard(Card c)
|
||||
{
|
||||
if (c.isCreature())
|
||||
{
|
||||
if (c.hasSickness() && keyword.equals("Haste"))
|
||||
return CardFactoryUtil.canTarget(card, c);
|
||||
|
||||
return (CardFactoryUtil.AI_doesCreatureAttack(c)) &&
|
||||
(CardFactoryUtil.canTarget(card, c)) &&
|
||||
(!keyword.equals("none") && !c.getKeyword().contains(keyword)) &&
|
||||
(! (! c.hasSickness()) && keyword.equals("Haste"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
list.remove(card);
|
||||
return list;
|
||||
}//getCreature()
|
||||
|
||||
public void resolve()
|
||||
{
|
||||
if(AllZone.GameAction.isCardInPlay(getTargetCard()) && CardFactoryUtil.canTarget(card, getTargetCard()))
|
||||
{
|
||||
final Card[] creature = new Card[1];
|
||||
if (Tgt[0] == true)
|
||||
creature[0] = getTargetCard();
|
||||
else
|
||||
creature[0] = card;
|
||||
|
||||
final int a = getNumAttack();
|
||||
final int d = getNumDefense();
|
||||
|
||||
final Command EOT = new Command()
|
||||
{
|
||||
private static final long serialVersionUID = 2134353417588894452L;
|
||||
|
||||
public void execute()
|
||||
{
|
||||
if(AllZone.GameAction.isCardInPlay(creature[0]))
|
||||
{
|
||||
creature[0].addTempAttackBoost(-1 * a);
|
||||
creature[0].addTempDefenseBoost(-1 * d);
|
||||
if (! Keyword[0].equals("none"))
|
||||
creature[0].removeExtrinsicKeyword(Keyword[0]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
creature[0].addTempAttackBoost(a);
|
||||
creature[0].addTempDefenseBoost(d);
|
||||
if (! Keyword[0].equals("none"))
|
||||
creature[0].addExtrinsicKeyword(Keyword[0]);
|
||||
|
||||
AllZone.EndOfTurn.addUntil(EOT);
|
||||
|
||||
if (! DrawBack[0].equals("none"))
|
||||
CardFactoryUtil.doDrawBack(DrawBack[0], 0, card.getController(), AllZone.GameAction.getOpponent(card.getController()), null, card, creature[0]);
|
||||
}//if (card is in play)
|
||||
}//resolve()
|
||||
};//SpellAbility
|
||||
|
||||
ability.setDescription(spDesc[0]);
|
||||
ability.setStackDescription(stDesc[0]);
|
||||
|
||||
if (Tgt[0] == true)
|
||||
ability.setBeforePayMana(CardFactoryUtil.input_targetCreature(ability));
|
||||
else
|
||||
ability.setTargetCard(card);
|
||||
card.addSpellAbility(ability);
|
||||
}
|
||||
if (! tapOnlyCost && tapCost)
|
||||
{
|
||||
final SpellAbility ability = new Ability_Tap(card, manaCost)
|
||||
{
|
||||
private static final long serialVersionUID = 7593387152288440603L;
|
||||
|
||||
private int defense;
|
||||
private String keyword;
|
||||
|
||||
private int getNumAttack()
|
||||
{
|
||||
if (NumAttack[0] != -1138)
|
||||
return NumAttack[0];
|
||||
|
||||
if (! AttackX[0].equals("none"))
|
||||
return CardFactoryUtil.xCount(card, AttackX[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
private int getNumDefense()
|
||||
{
|
||||
if (NumDefense[0] != -1138)
|
||||
return NumDefense[0];
|
||||
|
||||
if (! DefenseX[0].equals("none"))
|
||||
return CardFactoryUtil.xCount(card, DefenseX[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean canPlayAI()
|
||||
{
|
||||
defense = getNumDefense();
|
||||
keyword = Keyword[0];
|
||||
if(CardFactoryUtil.AI_doesCreatureAttack(card))
|
||||
return false;
|
||||
|
||||
if (AllZone.Phase.getPhase().equals(Constant.Phase.Main2))
|
||||
return false;
|
||||
|
||||
CardList list = getCreatures();
|
||||
if (!list.isEmpty())
|
||||
{
|
||||
boolean goodt = false;
|
||||
Card t = new Card();
|
||||
while (goodt == false && !list.isEmpty())
|
||||
{
|
||||
t = CardFactoryUtil.AI_getBestCreature(list);
|
||||
if ((t.getNetDefense() + defense) > 0)
|
||||
goodt = true;
|
||||
else
|
||||
list.remove(t);
|
||||
}
|
||||
if (goodt == true)
|
||||
{
|
||||
setTargetCard(t);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
public boolean canPlay()
|
||||
{
|
||||
boolean sick = true;
|
||||
|
||||
if (!card.hasSickness() || !card.isCreature())
|
||||
sick = false;
|
||||
|
||||
if (card.isUntapped() && AllZone.GameAction.isCardInPlay(card) &&
|
||||
!sick && !card.isFaceDown())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
CardList getCreatures()
|
||||
{
|
||||
CardList list = new CardList(AllZone.Computer_Play.getCards());
|
||||
list = list.filter(new CardListFilter()
|
||||
{
|
||||
public boolean addCard(Card c)
|
||||
{
|
||||
if (c.hasSickness() && keyword.equals("Hsste"))
|
||||
return CardFactoryUtil.canTarget(card, c);
|
||||
|
||||
return (CardFactoryUtil.AI_doesCreatureAttack(c)) &&
|
||||
(CardFactoryUtil.canTarget(card, c)) &&
|
||||
(!keyword.equals("none") && !c.getKeyword().contains(keyword)) &&
|
||||
(! (! c.hasSickness()) && keyword.equals("Haste"));
|
||||
}
|
||||
});
|
||||
list.remove(card);
|
||||
return list;
|
||||
}//getCreature()
|
||||
public void resolve()
|
||||
{
|
||||
if(AllZone.GameAction.isCardInPlay(getTargetCard()) && CardFactoryUtil.canTarget(card ,getTargetCard()))
|
||||
{
|
||||
final Card[] creature = new Card[1];
|
||||
if (Tgt[0] == true)
|
||||
creature[0] = getTargetCard();
|
||||
else
|
||||
creature[0] = card;
|
||||
|
||||
final int a = getNumAttack();
|
||||
final int d = getNumDefense();
|
||||
|
||||
final Command EOT = new Command()
|
||||
{
|
||||
private static final long serialVersionUID = 3532917180149273560L;
|
||||
|
||||
public void execute()
|
||||
{
|
||||
if(AllZone.GameAction.isCardInPlay(creature[0]))
|
||||
{
|
||||
creature[0].addTempAttackBoost(-1 * a);
|
||||
creature[0].addTempDefenseBoost(-1 * d);
|
||||
if (! Keyword[0].equals("none"))
|
||||
creature[0].removeExtrinsicKeyword(Keyword[0]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
creature[0].addTempAttackBoost(a);
|
||||
creature[0].addTempDefenseBoost(d);
|
||||
if (! Keyword[0].equals("none"))
|
||||
creature[0].addExtrinsicKeyword(Keyword[0]);
|
||||
AllZone.EndOfTurn.addUntil(EOT);
|
||||
|
||||
if (! DrawBack[0].equals("none"))
|
||||
CardFactoryUtil.doDrawBack(DrawBack[0], 0, card.getController(), AllZone.GameAction.getOpponent(card.getController()), null, card, creature[0]);
|
||||
}//if (card is in play)
|
||||
}//resolve()
|
||||
};//SpellAbility
|
||||
|
||||
ability.setDescription(spDesc[0]);
|
||||
ability.setStackDescription(stDesc[0]);
|
||||
|
||||
if (Tgt[0] == true)
|
||||
ability.setBeforePayMana(CardFactoryUtil.input_targetCreature(ability));
|
||||
else
|
||||
ability.setTargetCard(card);
|
||||
card.addSpellAbility(ability);
|
||||
}
|
||||
}
|
||||
}//while
|
||||
|
||||
|
||||
if (hasKeyword(card, "Untap") != -1)
|
||||
{
|
||||
|
||||
@@ -2453,6 +2453,13 @@ public class CardFactoryUtil
|
||||
else
|
||||
return doXMath(Integer.parseInt(sq[2]), m); // not Hellbent
|
||||
|
||||
// Count$CardPower
|
||||
if (sq[0].contains("CardPower"))
|
||||
return doXMath(c.getNetAttack(), m);
|
||||
// Count$CardToughness
|
||||
if (sq[0].contains("CardToughness"))
|
||||
return doXMath(c.getNetDefense(), m);
|
||||
|
||||
|
||||
//Generic Zone-based counting
|
||||
// Count$QualityAndZones.Subquality
|
||||
@@ -2726,6 +2733,9 @@ public class CardFactoryUtil
|
||||
for (int i=0; i < X; i++)
|
||||
AllZone.GameAction.drawCard(dbPlayer);
|
||||
|
||||
if (d[0].contains("UntapTgt"))
|
||||
TgtC.untap();
|
||||
|
||||
if (d[0].contains("GenToken")) // placeholder for effect
|
||||
X = X + 0;
|
||||
|
||||
|
||||
@@ -7288,6 +7288,7 @@ public class CardFactory_Creatures {
|
||||
}//*************** END ************ END **************************
|
||||
|
||||
|
||||
/*
|
||||
|
||||
//*************** START *********** START **************************
|
||||
else if(cardName.equals("Timberwatch Elf"))
|
||||
@@ -7368,9 +7369,7 @@ public class CardFactory_Creatures {
|
||||
|
||||
ability.setBeforePayMana(CardFactoryUtil.input_targetCreature_NoCost_TapAbility(ability));
|
||||
}//*************** END ************ END **************************
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
//*************** START *********** START **************************
|
||||
else if(cardName.equals("Mad Auntie"))
|
||||
@@ -18318,7 +18317,7 @@ public class CardFactory_Creatures {
|
||||
//*************** START *********** START **************************
|
||||
else if(cardName.equals("Cathartic Adept"))
|
||||
{
|
||||
final SpellAbility a1 = new Ability_Tap(card, "0")
|
||||
final Ability_Tap a1 = new Ability_Tap(card)
|
||||
{
|
||||
private static final long serialVersionUID = 2359247592519063187L;
|
||||
|
||||
@@ -18342,8 +18341,6 @@ public class CardFactory_Creatures {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public boolean canPlayAI()
|
||||
{
|
||||
String player = getTargetPlayer();
|
||||
@@ -18352,11 +18349,23 @@ public class CardFactory_Creatures {
|
||||
return libList.size() > 0;
|
||||
}
|
||||
};//SpellAbility
|
||||
card.addSpellAbility(a1);
|
||||
|
||||
//not sure why, but this card doesn't seem to want to tap:
|
||||
final Command tap = new Command()
|
||||
{
|
||||
private static final long serialVersionUID = -6290276896549170403L;
|
||||
|
||||
public void execute()
|
||||
{
|
||||
card.tap();
|
||||
}
|
||||
};
|
||||
|
||||
a1.setDescription("tap: Target player puts the top card of his or her library into his or her graveyard.");
|
||||
a1.setStackDescription("Player puts the top card of his or her library into his or her graveyard");
|
||||
a1.setBeforePayMana(new Input_PayManaCost(a1));
|
||||
a1.setBeforePayMana(CardFactoryUtil.input_targetPlayer(a1));
|
||||
//a1.setBeforePayMana(new Input_PayManaCost(a1));
|
||||
a1.setBeforePayMana(CardFactoryUtil.input_targetPlayer(a1, tap));
|
||||
card.addSpellAbility(a1);
|
||||
}//*************** END ************ END **************************
|
||||
|
||||
|
||||
|
||||
@@ -704,7 +704,7 @@ class CardFactory_Lands {
|
||||
PlayerZone library = AllZone.getZone(Constant.Zone.Library, card.getController());
|
||||
CardList list = new CardList(library.getCards());
|
||||
list = list.getType("Basic");
|
||||
if (list.size() > 0 && AllZone.GameAction.isCardInPlay(card))
|
||||
if (super.canPlay() && list.size() > 0 && AllZone.GameAction.isCardInPlay(card))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
@@ -797,6 +797,126 @@ class CardFactory_Lands {
|
||||
ability.setBeforePayMana(runtime);
|
||||
}//*************** END ************ END **************************
|
||||
|
||||
|
||||
//*************** START *********** START **************************
|
||||
else if(cardName.equals("Arid Mesa") || cardName.equals("Marsh Flats") || cardName.equals("Misty Rainforest") ||
|
||||
cardName.equals("Scalding Tarn") || cardName.equals("Verdant Catacombs") ||
|
||||
cardName.equals("Bloodstained Mire") || cardName.equals("Flooded Strand") || cardName.equals("Polluted Delta") ||
|
||||
cardName.equals("Windswept Heath") || cardName.equals("Wooded Foothills"))
|
||||
{
|
||||
|
||||
final String[] land1 = new String[1];
|
||||
final String[] land2 = new String[1];
|
||||
|
||||
if (cardName.equals("Arid Mesa")) { land1[0] = "Mountain"; land2[0] = "Plains";}
|
||||
else if (cardName.equals("Marsh Flats")) { land1[0] = "Plains"; land2[0] = "Swamp";}
|
||||
else if (cardName.equals("Misty Rainforest")) { land1[0] = "Forest"; land2[0] = "Island";}
|
||||
else if (cardName.equals("Scalding Tarn")) { land1[0] = "Island"; land2[0] = "Mountain";}
|
||||
else if (cardName.equals("Verdant Catacombs")) { land1[0] = "Swamp"; land2[0] = "Forest";}
|
||||
else if (cardName.equals("Bloodstained Mire")) { land1[0] = "Swamp"; land2[0] = "Mountain";}
|
||||
else if (cardName.equals("Flooded Strand")) { land1[0] = "Plains"; land2[0] = "Island";}
|
||||
else if (cardName.equals("Polluted Delta")) { land1[0] = "Island"; land2[0] = "Swamp";}
|
||||
else if (cardName.equals("Windswept Heath")) { land1[0] = "Forest"; land2[0] = "Plains";}
|
||||
else if (cardName.equals("Wooded Foothills")) { land1[0] = "Mountain"; land2[0] = "Forest";}
|
||||
|
||||
//tap sacrifice
|
||||
final Ability_Tap ability = new Ability_Tap(card, "0")
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = 6865042319287843154L;
|
||||
|
||||
public boolean canPlayAI()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public void chooseTargetAI()
|
||||
{
|
||||
AllZone.GameAction.sacrifice(card);
|
||||
}
|
||||
public boolean canPlay()
|
||||
{
|
||||
PlayerZone library = AllZone.getZone(Constant.Zone.Library, card.getController());
|
||||
CardList list = new CardList(library.getCards());
|
||||
list = list.filter(new CardListFilter()
|
||||
{
|
||||
public boolean addCard(Card c)
|
||||
{
|
||||
return c.getType().contains(land1[0]) || c.getType().contains(land2[0]);
|
||||
}
|
||||
});
|
||||
if (super.canPlay() && list.size() > 0 && AllZone.GameAction.isCardInPlay(card))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
}//canPlay()
|
||||
public void resolve()
|
||||
{
|
||||
if(card.getOwner().equals(Constant.Player.Human))
|
||||
humanResolve();
|
||||
//else
|
||||
// computerResolve();
|
||||
}
|
||||
|
||||
public void humanResolve()
|
||||
{
|
||||
PlayerZone library = AllZone.getZone(Constant.Zone.Library, card.getController());
|
||||
PlayerZone play = AllZone.getZone(Constant.Zone.Play , card.getController());
|
||||
|
||||
CardList full = new CardList(library.getCards());
|
||||
CardList land = new CardList(library.getCards());
|
||||
land = land.filter(new CardListFilter()
|
||||
{
|
||||
public boolean addCard(Card c)
|
||||
{
|
||||
return c.getType().contains(land1[0]) || c.getType().contains(land2[0]);
|
||||
}
|
||||
});
|
||||
|
||||
Object o = AllZone.Display.getChoiceOptional("Choose a " +land1[0] + " or " + land2[0], full.toArray());
|
||||
if(o != null)
|
||||
{
|
||||
|
||||
Card c = (Card)o;
|
||||
if (land.contains(c))
|
||||
{
|
||||
library.remove(c);
|
||||
play.add(c);
|
||||
}
|
||||
}
|
||||
AllZone.GameAction.shuffle(card.getController());
|
||||
}//resolve()
|
||||
};//SpellAbility
|
||||
|
||||
Input runtime = new Input()
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = -7328086812286814833L;
|
||||
boolean once = true;
|
||||
public void showMessage()
|
||||
{
|
||||
//this is necessary in order not to have a StackOverflowException
|
||||
//because this updates a card, it creates a circular loop of observers
|
||||
if(once)
|
||||
{
|
||||
once = false;
|
||||
String player = card.getController();
|
||||
AllZone.GameAction.getPlayerLife(player).subtractLife(1);
|
||||
AllZone.GameAction.sacrifice(card);
|
||||
|
||||
ability.setStackDescription(card.getController() +" - Search your library for a "+land1[0]+" or "+land2[0]+" card and put it onto the battlefield. Then shuffle your library.");
|
||||
AllZone.Stack.add(ability);
|
||||
|
||||
stop();
|
||||
}
|
||||
}//showMessage()
|
||||
};
|
||||
card.addSpellAbility(ability);
|
||||
ability.setDescription("Tap, Pay 1 life, Sacrifice " + card.getName() +": Search your library for a "+land1[0]+" or "+land2[0]+" card and put it onto the battlefield. Then shuffle your library.");
|
||||
ability.setBeforePayMana(runtime);
|
||||
}//*************** END ************ END **************************
|
||||
|
||||
|
||||
//*************** START *********** START **************************
|
||||
else if(cardName.equals("Tortuga"))
|
||||
{
|
||||
@@ -2438,6 +2558,7 @@ class CardFactory_Lands {
|
||||
|
||||
}//*************** END ************ END **************************
|
||||
|
||||
/*
|
||||
//*************** START *********** START **************************
|
||||
else if(cardName.equals("Skarrg, the Rage Pits"))
|
||||
{
|
||||
@@ -2537,6 +2658,8 @@ class CardFactory_Lands {
|
||||
|
||||
}//*************** END ************ END **************************
|
||||
|
||||
*/
|
||||
|
||||
//*************** START *********** START **************************
|
||||
else if(cardName.equals("Daru Encampment"))
|
||||
{
|
||||
|
||||
@@ -1804,7 +1804,7 @@ public class CombatUtil
|
||||
AllZone.EndOfCombat.addAt(atEOC);
|
||||
}
|
||||
|
||||
else if (b.getName().equals("AEther Membrane") )
|
||||
else if (b.getName().equals("AEther Membrane") || b.getName().equals("Aether Membrane") )
|
||||
{
|
||||
final Card attacker = a;
|
||||
final Ability ability = new Ability(b, "0")
|
||||
|
||||
@@ -87,6 +87,7 @@ public class ReadCard implements Runnable, NewConstants {
|
||||
s = readLine();
|
||||
if(c.isCreature()) {
|
||||
|
||||
//System.out.println("Creature name:" + c.getName());
|
||||
int n = s.indexOf("/");
|
||||
int att = Integer.parseInt(s.substring(0, n));
|
||||
int def = Integer.parseInt(s.substring(n + 1));
|
||||
|
||||
Reference in New Issue
Block a user