mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
- Converted abGainLife to use abCost and Tgt.
- Added player as possible ValidTarget option in TargetSelection. - Updated Mournful Zombie, Spike Feeder, Bottle Gnomes.
This commit is contained in:
@@ -3,6 +3,7 @@ ManaCost:3
|
|||||||
Types:Artifact Creature Gnome
|
Types:Artifact Creature Gnome
|
||||||
Text:no text
|
Text:no text
|
||||||
PT:1/3
|
PT:1/3
|
||||||
|
K:abGainLife Sac<1/CARDNAME>:3
|
||||||
SVar:Rarity:Uncommon
|
SVar:Rarity:Uncommon
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/bottle_gnomes.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/bottle_gnomes.jpg
|
||||||
End
|
End
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ ManaCost:2 B
|
|||||||
Types:Creature Zombie
|
Types:Creature Zombie
|
||||||
Text:no text
|
Text:no text
|
||||||
PT:2/1
|
PT:2/1
|
||||||
K:abGainLifeTgt W T:1
|
K:abGainLifeTgtV W T:player:1
|
||||||
SVar:Rarity:Common
|
SVar:Rarity:Common
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/mournful_zombie.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/mournful_zombie.jpg
|
||||||
End
|
End
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ Types:Creature Spike
|
|||||||
Text:no text
|
Text:no text
|
||||||
PT:0/0
|
PT:0/0
|
||||||
K:Spike 2
|
K:Spike 2
|
||||||
|
K:abGainLife SubCounter<1/P1P1>:2
|
||||||
SVar:Rarity:Uncommon
|
SVar:Rarity:Uncommon
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/spike_feeder.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/spike_feeder.jpg
|
||||||
End
|
End
|
||||||
|
|||||||
@@ -4520,71 +4520,69 @@ public class CardFactory implements NewConstants {
|
|||||||
card.removeIntrinsicKeyword(parse);
|
card.removeIntrinsicKeyword(parse);
|
||||||
|
|
||||||
String k[] = parse.split(":");
|
String k[] = parse.split(":");
|
||||||
|
String tmp = k[0].replace("abGainLife", "");
|
||||||
|
|
||||||
final boolean Tgt[] = {false};
|
String[] tmpCost = tmp.split(" ", 2);
|
||||||
Tgt[0] = k[0].contains("Tgt");
|
|
||||||
|
|
||||||
String tmpCost = "";
|
int inc = 0;
|
||||||
|
|
||||||
if (Tgt[0])
|
final Target abTgt;
|
||||||
tmpCost = k[0].substring(13);
|
if (tmpCost[0].equals(""))
|
||||||
else
|
abTgt = null;
|
||||||
tmpCost = k[0].substring(10);
|
else{
|
||||||
|
abTgt = new Target(tmpCost[0]);
|
||||||
boolean tapCost = false;
|
abTgt.setValidTgts(k[1].split(","));
|
||||||
boolean tapOnlyCost = false;
|
abTgt.setVTSelection("Target a player to gain life");
|
||||||
|
|
||||||
if (tmpCost.contains("T"))
|
inc++;
|
||||||
{
|
|
||||||
tapCost = true;
|
|
||||||
tmpCost = tmpCost.replace("T", "").trim();
|
|
||||||
if (tmpCost.length() == 0)
|
|
||||||
tapOnlyCost = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final String manaCost = tmpCost;
|
final Ability_Cost abCost = new Ability_Cost(tmpCost[1], card.getName(), true);
|
||||||
|
|
||||||
final int NumLife[] = {-1};
|
final int NumLife[] = {-1};
|
||||||
final String NumLifeX[] = {"none"};
|
final String NumLifeX[] = {"none"};
|
||||||
|
|
||||||
if (k[1].matches("X"))
|
int lifePos = 1 + inc;
|
||||||
|
int drawbackPos = 2 + inc;
|
||||||
|
|
||||||
|
if (k[lifePos].matches("X"))
|
||||||
{
|
{
|
||||||
String x = card.getSVar(k[1]);
|
String x = card.getSVar(k[lifePos]);
|
||||||
if (x.startsWith("Count$"))
|
if (x.startsWith("Count$"))
|
||||||
{
|
{
|
||||||
String kk[] = x.split("\\$");
|
String kk[] = x.split("\\$");
|
||||||
NumLifeX[0] = kk[1];
|
NumLifeX[0] = kk[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (k[1].matches("[0-9][0-9]?"))
|
else if (k[lifePos].matches("[0-9][0-9]?"))
|
||||||
NumLife[0] = Integer.parseInt(k[1]);
|
NumLife[0] = Integer.parseInt(k[lifePos]);
|
||||||
|
|
||||||
// drawbacks and descriptions
|
// drawbacks and descriptions
|
||||||
final String DrawBack[] = {"none"};
|
final String DrawBack[] = {"none"};
|
||||||
final String spDesc[] = {"none"};
|
final String spDesc[] = {"none"};
|
||||||
final String stDesc[] = {"none"};
|
final String stDesc[] = {"none"};
|
||||||
if (k.length > 2)
|
if (k.length > drawbackPos)
|
||||||
{
|
{
|
||||||
if (k[2].contains("Drawback$"))
|
if (k[drawbackPos].contains("Drawback$"))
|
||||||
{
|
{
|
||||||
String kk[] = k[2].split("\\$");
|
String kk[] = k[drawbackPos].split("\\$");
|
||||||
DrawBack[0] = kk[1];
|
DrawBack[0] = kk[1];
|
||||||
if (k.length > 3)
|
if (k.length > drawbackPos+1)
|
||||||
spDesc[0] = k[3];
|
spDesc[0] = k[drawbackPos+1];
|
||||||
if (k.length > 4)
|
if (k.length > drawbackPos+2)
|
||||||
stDesc[0] = k[4];
|
stDesc[0] = k[drawbackPos+2];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (k.length > 2)
|
if (k.length > drawbackPos)
|
||||||
spDesc[0] = k[2];
|
spDesc[0] = k[drawbackPos];
|
||||||
if (k.length > 3)
|
if (k.length > drawbackPos+1)
|
||||||
stDesc[0] = k[3];
|
stDesc[0] = k[drawbackPos+1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Tgt[0] == true)
|
if (abTgt != null)
|
||||||
{
|
{
|
||||||
spDesc[0] = "Target player gains " + NumLife[0] + " life.";
|
spDesc[0] = "Target player gains " + NumLife[0] + " life.";
|
||||||
stDesc[0] = cardName + " - target player gains life";
|
stDesc[0] = cardName + " - target player gains life";
|
||||||
@@ -4595,129 +4593,65 @@ public class CardFactory implements NewConstants {
|
|||||||
stDesc[0] = cardName + " - you gain life";
|
stDesc[0] = cardName + " - you gain life";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!tapCost)
|
final SpellAbility abGainLife = new Ability_Activated(card, abCost.getMana())
|
||||||
{
|
{
|
||||||
final SpellAbility abGainLife = new Ability_Activated(card, manaCost)
|
private static final long serialVersionUID = -936369754466156082L;
|
||||||
{
|
|
||||||
private static final long serialVersionUID = -936369754466156082L;
|
public int getNumLife()
|
||||||
|
{
|
||||||
public int getNumLife()
|
if (NumLife[0] != -1)
|
||||||
{
|
return NumLife[0];
|
||||||
if (NumLife[0] != -1)
|
|
||||||
return NumLife[0];
|
if (! NumLifeX[0].equals("none"))
|
||||||
|
return CardFactoryUtil.xCount(card, NumLifeX[0]);
|
||||||
if (! NumLifeX[0].equals("none"))
|
|
||||||
return CardFactoryUtil.xCount(card, NumLifeX[0]);
|
return 0;
|
||||||
|
}
|
||||||
return 0;
|
|
||||||
}
|
public boolean canPlayAI()
|
||||||
|
{
|
||||||
public boolean canPlayAI()
|
int life = AllZone.GameAction.getPlayerLife(Constant.Player.Computer).getLife();
|
||||||
{
|
if (abCost.getSacCost() && life > 5) return false;
|
||||||
Random r = new Random();
|
if (abCost.getSubCounter() && life > 5) return false;
|
||||||
boolean rr = false; // prevent run-away activations - first time will always return true
|
if (abCost.getLifeCost() && life > 5) return false;
|
||||||
if (r.nextFloat() <= Math.pow(.6667, card.getAbilityUsed()))
|
|
||||||
rr = true;
|
|
||||||
|
|
||||||
if (Tgt[0] == true)
|
|
||||||
setTargetPlayer(Constant.Player.Computer);
|
|
||||||
|
|
||||||
if (AllZone.Computer_Life.getLife() < 10)
|
|
||||||
return true && rr;
|
|
||||||
else
|
|
||||||
return ((r.nextFloat() < .6667) && rr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resolve()
|
|
||||||
{
|
|
||||||
int nlife = getNumLife();
|
|
||||||
String TgtPlayer;
|
|
||||||
|
|
||||||
if (Tgt[0] == true)
|
|
||||||
TgtPlayer = getTargetPlayer();
|
|
||||||
else
|
|
||||||
TgtPlayer = card.getController();
|
|
||||||
|
|
||||||
AllZone.GameAction.gainLife(TgtPlayer, nlife);
|
|
||||||
if (!DrawBack[0].equals("none"))
|
|
||||||
CardFactoryUtil.doDrawBack(DrawBack[0], nlife, card.getController(), AllZone.GameAction.getOpponent(card.getController()), TgtPlayer, card, null, this);
|
|
||||||
}//resolve()
|
|
||||||
};//SpellAbility
|
|
||||||
|
|
||||||
if (Tgt[0] == true)
|
|
||||||
abGainLife.setBeforePayMana(CardFactoryUtil.input_targetPlayer(abGainLife));
|
|
||||||
|
|
||||||
abGainLife.setDescription(manaCost + ": " + spDesc[0]);
|
|
||||||
abGainLife.setStackDescription(stDesc[0]);
|
|
||||||
|
|
||||||
card.addSpellAbility(abGainLife);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
final SpellAbility abGainLife = new Ability_Tap(card)
|
|
||||||
{
|
|
||||||
private static final long serialVersionUID = -3661692584660594012L;
|
|
||||||
|
|
||||||
public int getNumLife()
|
|
||||||
{
|
|
||||||
if (NumLife[0] != -1)
|
|
||||||
return NumLife[0];
|
|
||||||
|
|
||||||
if (! NumLifeX[0].equals("none"))
|
|
||||||
return CardFactoryUtil.xCount(card, NumLifeX[0]);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canPlayAI()
|
|
||||||
{
|
|
||||||
boolean att = !CardFactoryUtil.AI_doesCreatureAttack(card);
|
|
||||||
|
|
||||||
if (Tgt[0] == true)
|
|
||||||
setTargetPlayer(Constant.Player.Computer);
|
|
||||||
|
|
||||||
if (AllZone.Computer_Life.getLife() < 10)
|
|
||||||
return true && att;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Random r = new Random();
|
|
||||||
return ((r.nextFloat() < .6667) && att);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resolve()
|
|
||||||
{
|
|
||||||
int nlife = getNumLife();
|
|
||||||
String TgtPlayer;
|
|
||||||
|
|
||||||
if (Tgt[0] == true)
|
|
||||||
TgtPlayer = getTargetPlayer();
|
|
||||||
else
|
|
||||||
TgtPlayer = card.getController();
|
|
||||||
|
|
||||||
AllZone.GameAction.gainLife(TgtPlayer, nlife);
|
|
||||||
|
|
||||||
if (!DrawBack[0].equals("none"))
|
|
||||||
CardFactoryUtil.doDrawBack(DrawBack[0], nlife, card.getController(), AllZone.GameAction.getOpponent(card.getController()), TgtPlayer, card, null, this);
|
|
||||||
}//resolve()
|
|
||||||
};//SpellAbility
|
|
||||||
|
|
||||||
if (Tgt[0] == true)
|
|
||||||
abGainLife.setBeforePayMana(CardFactoryUtil.input_targetPlayer(abGainLife));
|
|
||||||
|
|
||||||
if (tapOnlyCost)
|
|
||||||
abGainLife.setDescription("Tap: " + spDesc[0]);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
abGainLife.setDescription(manaCost + ", tap: " + spDesc[0]);
|
|
||||||
abGainLife.setManaCost(manaCost);
|
|
||||||
}
|
|
||||||
|
|
||||||
abGainLife.setStackDescription(stDesc[0]);
|
if (!ComputerUtil.canPayCost(this))
|
||||||
|
return false;
|
||||||
card.addSpellAbility(abGainLife);
|
|
||||||
}
|
Random r = new Random();
|
||||||
|
boolean rr = false; // prevent run-away activations - first time will always return true
|
||||||
|
if (r.nextFloat() <= Math.pow(.6667, card.getAbilityUsed()))
|
||||||
|
rr = true;
|
||||||
|
|
||||||
|
if (abTgt != null)
|
||||||
|
setTargetPlayer(Constant.Player.Computer);
|
||||||
|
|
||||||
|
if (AllZone.Computer_Life.getLife() < 10)
|
||||||
|
return true && rr;
|
||||||
|
else
|
||||||
|
return ((r.nextFloat() < .6667) && rr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resolve()
|
||||||
|
{
|
||||||
|
int nlife = getNumLife();
|
||||||
|
String TgtPlayer = (abTgt != null) ? getTargetPlayer() : getActivatingPlayer();
|
||||||
|
|
||||||
|
AllZone.GameAction.gainLife(TgtPlayer, nlife);
|
||||||
|
if (!DrawBack[0].equals("none"))
|
||||||
|
CardFactoryUtil.doDrawBack(DrawBack[0], nlife, card.getController(), AllZone.GameAction.getOpponent(card.getController()), TgtPlayer, card, null, this);
|
||||||
|
}//resolve()
|
||||||
|
};//SpellAbility
|
||||||
|
|
||||||
|
abGainLife.setDescription(abCost.toString() + spDesc[0]);
|
||||||
|
abGainLife.setStackDescription(stDesc[0]);
|
||||||
|
|
||||||
|
if (abTgt != null)
|
||||||
|
abGainLife.setTarget(abTgt);
|
||||||
|
|
||||||
|
abGainLife.setPayCosts(abCost);
|
||||||
|
|
||||||
|
card.addSpellAbility(abGainLife);
|
||||||
}
|
}
|
||||||
}// abGainLife
|
}// abGainLife
|
||||||
|
|
||||||
|
|||||||
@@ -7969,42 +7969,6 @@ public class CardFactory_Creatures {
|
|||||||
}));
|
}));
|
||||||
}//*************** END ************ END **************************
|
}//*************** END ************ END **************************
|
||||||
|
|
||||||
|
|
||||||
//*************** START *********** START **************************
|
|
||||||
else if(cardName.equals("Bottle Gnomes")) {
|
|
||||||
final Ability ability = new Ability(card, "0") {
|
|
||||||
@Override
|
|
||||||
public boolean canPlayAI() {
|
|
||||||
return AllZone.Computer_Life.getLife() < 3;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlay() {
|
|
||||||
SpellAbility sa;
|
|
||||||
for(int i = 0; i < AllZone.Stack.size(); i++) {
|
|
||||||
sa = AllZone.Stack.peek(i);
|
|
||||||
if(sa.getSourceCard().equals(card)) return false;
|
|
||||||
}
|
|
||||||
if(AllZone.GameAction.isCardInPlay(card) && super.canPlay()) return true;
|
|
||||||
else return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void resolve() {
|
|
||||||
AllZone.GameAction.gainLife(card.getController(), 3);
|
|
||||||
|
|
||||||
AllZone.GameAction.sacrifice(card);
|
|
||||||
}//resolve()
|
|
||||||
};//SpellAbility
|
|
||||||
|
|
||||||
card.addSpellAbility(ability);
|
|
||||||
ability.setDescription("Sacrifice Bottle Gnomes: Gain 3 life.");
|
|
||||||
ability.setStackDescription(card.getName() + " - " + card.getController() + " gains 3 life.");
|
|
||||||
|
|
||||||
}//*************** END ************ END **************************
|
|
||||||
|
|
||||||
|
|
||||||
//*************** START *********** START **************************
|
//*************** START *********** START **************************
|
||||||
else if(cardName.equals("Painter's Servant")) {
|
else if(cardName.equals("Painter's Servant")) {
|
||||||
final long[] timeStamp = new long[1];
|
final long[] timeStamp = new long[1];
|
||||||
@@ -19166,44 +19130,6 @@ public class CardFactory_Creatures {
|
|||||||
card.addSpellAbility(fog);
|
card.addSpellAbility(fog);
|
||||||
}//*************** END ************ END **************************
|
}//*************** END ************ END **************************
|
||||||
|
|
||||||
|
|
||||||
//*************** START *********** START **************************
|
|
||||||
else if(cardName.equals("Spike Feeder")) {
|
|
||||||
final SpellAbility heal = new Ability(card, "0") {
|
|
||||||
// removing of a +1/+1 should be in the activation, but it doesn't work properly right now.
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void resolve() {
|
|
||||||
if (card.getCounters(Counters.P1P1) > 0){
|
|
||||||
card.subtractCounter(Counters.P1P1, 1);
|
|
||||||
AllZone.GameAction.gainLife(getActivatingPlayer(), 2);
|
|
||||||
}
|
|
||||||
}//resolve
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlay() {
|
|
||||||
// stack peek is needed to prevent Spike Feeder from trying to double activate
|
|
||||||
SpellAbility sa;
|
|
||||||
for(int i = 0; i < AllZone.Stack.size(); i++) {
|
|
||||||
sa = AllZone.Stack.peek(i);
|
|
||||||
if(sa.getSourceCard().equals(card)) return false;
|
|
||||||
}
|
|
||||||
return card.getCounters(Counters.P1P1) > 0 && super.canPlay();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlayAI() {
|
|
||||||
// when should the AI sacrifice his feeder for health?
|
|
||||||
return card.getCounters(Counters.P1P1) > 0 && AllZone.Computer_Life.getLife() < 5;
|
|
||||||
}
|
|
||||||
};//SpellAbility
|
|
||||||
|
|
||||||
heal.setDescription("Remove a +1/+1 counter: Gain 2 life.");
|
|
||||||
heal.setStackDescription("Gain 2 life");
|
|
||||||
card.addSpellAbility(heal);
|
|
||||||
}//*************** END ************ END **************************
|
|
||||||
|
|
||||||
|
|
||||||
//*************** START *********** START **************************
|
//*************** START *********** START **************************
|
||||||
else if (cardName.equals("Yavimaya Elder"))
|
else if (cardName.equals("Yavimaya Elder"))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -209,17 +209,21 @@ public class Target_Selection {
|
|||||||
CardList allCards = new CardList();
|
CardList allCards = new CardList();
|
||||||
allCards.addAll(AllZone.Human_Play.getCards());
|
allCards.addAll(AllZone.Human_Play.getCards());
|
||||||
allCards.addAll(AllZone.Computer_Play.getCards());
|
allCards.addAll(AllZone.Computer_Play.getCards());
|
||||||
|
|
||||||
CardList choices = allCards.getValidCards(Tgts);
|
CardList choices = allCards.getValidCards(Tgts);
|
||||||
|
|
||||||
|
boolean canTargetPlayer = false;
|
||||||
|
for(String s : Tgts)
|
||||||
|
if (s.equals("player"))
|
||||||
|
canTargetPlayer = true;
|
||||||
|
|
||||||
stopSetNext(input_targetSpecific(sa, choices, message, true, select, req));
|
stopSetNext(input_targetSpecific(sa, choices, message, true, canTargetPlayer, select, req));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}//input_targetValid
|
}//input_targetValid
|
||||||
|
|
||||||
//CardList choices are the only cards the user can successful select
|
//CardList choices are the only cards the user can successful select
|
||||||
public static Input input_targetSpecific(final SpellAbility spell, final CardList choices, final String message,
|
public static Input input_targetSpecific(final SpellAbility spell, final CardList choices, final String message,
|
||||||
final boolean targeted, final Target_Selection select, final SpellAbility_Requirements req) {
|
final boolean targeted, final boolean bTgtPlayer, final Target_Selection select, final SpellAbility_Requirements req) {
|
||||||
Input target = new Input() {
|
Input target = new Input() {
|
||||||
private static final long serialVersionUID = -1091595663541356356L;
|
private static final long serialVersionUID = -1091595663541356356L;
|
||||||
|
|
||||||
@@ -247,6 +251,14 @@ public class Target_Selection {
|
|||||||
}
|
}
|
||||||
}//selectCard()
|
}//selectCard()
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void selectPlayer(String player) {
|
||||||
|
if (bTgtPlayer){ // todo: check if the player has Shroud too
|
||||||
|
spell.setTargetPlayer(player);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void done() {
|
void done() {
|
||||||
select.incrementTargets();
|
select.incrementTargets();
|
||||||
stop();
|
stop();
|
||||||
|
|||||||
Reference in New Issue
Block a user