From 945d4f06d8fb968013d3ed9e7efad096921b9ee6 Mon Sep 17 00:00:00 2001 From: jendave Date: Sat, 6 Aug 2011 08:28:57 +0000 Subject: [PATCH] - Converted abGainLife to use abCost and Tgt. - Added player as possible ValidTarget option in TargetSelection. - Updated Mournful Zombie, Spike Feeder, Bottle Gnomes. --- res/cardsfolder/bottle_gnomes.txt | 1 + res/cardsfolder/mournful_zombie.txt | 2 +- res/cardsfolder/spike_feeder.txt | 1 + src/forge/CardFactory.java | 244 ++++++++++----------------- src/forge/CardFactory_Creatures.java | 74 -------- src/forge/Target_Selection.java | 18 +- 6 files changed, 107 insertions(+), 233 deletions(-) diff --git a/res/cardsfolder/bottle_gnomes.txt b/res/cardsfolder/bottle_gnomes.txt index 04c49bf9927..fc1fd904fa1 100644 --- a/res/cardsfolder/bottle_gnomes.txt +++ b/res/cardsfolder/bottle_gnomes.txt @@ -3,6 +3,7 @@ ManaCost:3 Types:Artifact Creature Gnome Text:no text PT:1/3 +K:abGainLife Sac<1/CARDNAME>:3 SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/bottle_gnomes.jpg End diff --git a/res/cardsfolder/mournful_zombie.txt b/res/cardsfolder/mournful_zombie.txt index 520b9cf3e9d..c33cacb668a 100644 --- a/res/cardsfolder/mournful_zombie.txt +++ b/res/cardsfolder/mournful_zombie.txt @@ -3,7 +3,7 @@ ManaCost:2 B Types:Creature Zombie Text:no text PT:2/1 -K:abGainLifeTgt W T:1 +K:abGainLifeTgtV W T:player:1 SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/mournful_zombie.jpg End diff --git a/res/cardsfolder/spike_feeder.txt b/res/cardsfolder/spike_feeder.txt index cb8acaf9614..e3f7889df98 100644 --- a/res/cardsfolder/spike_feeder.txt +++ b/res/cardsfolder/spike_feeder.txt @@ -4,6 +4,7 @@ Types:Creature Spike Text:no text PT:0/0 K:Spike 2 +K:abGainLife SubCounter<1/P1P1>:2 SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/spike_feeder.jpg End diff --git a/src/forge/CardFactory.java b/src/forge/CardFactory.java index b8b495f75fd..77f677b5e03 100644 --- a/src/forge/CardFactory.java +++ b/src/forge/CardFactory.java @@ -4520,71 +4520,69 @@ public class CardFactory implements NewConstants { card.removeIntrinsicKeyword(parse); String k[] = parse.split(":"); + String tmp = k[0].replace("abGainLife", ""); - final boolean Tgt[] = {false}; - Tgt[0] = k[0].contains("Tgt"); + String[] tmpCost = tmp.split(" ", 2); - String tmpCost = ""; + int inc = 0; - if (Tgt[0]) - tmpCost = k[0].substring(13); - else - tmpCost = k[0].substring(10); - - boolean tapCost = false; - boolean tapOnlyCost = false; - - if (tmpCost.contains("T")) - { - tapCost = true; - tmpCost = tmpCost.replace("T", "").trim(); - if (tmpCost.length() == 0) - tapOnlyCost = true; + final Target abTgt; + if (tmpCost[0].equals("")) + abTgt = null; + else{ + abTgt = new Target(tmpCost[0]); + abTgt.setValidTgts(k[1].split(",")); + abTgt.setVTSelection("Target a player to gain life"); + + inc++; } - final String manaCost = tmpCost; + final Ability_Cost abCost = new Ability_Cost(tmpCost[1], card.getName(), true); final int NumLife[] = {-1}; 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$")) { String kk[] = x.split("\\$"); NumLifeX[0] = kk[1]; } } - else if (k[1].matches("[0-9][0-9]?")) - NumLife[0] = Integer.parseInt(k[1]); + else if (k[lifePos].matches("[0-9][0-9]?")) + NumLife[0] = Integer.parseInt(k[lifePos]); // drawbacks and descriptions final String DrawBack[] = {"none"}; final String spDesc[] = {"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]; - if (k.length > 3) - spDesc[0] = k[3]; - if (k.length > 4) - stDesc[0] = k[4]; + if (k.length > drawbackPos+1) + spDesc[0] = k[drawbackPos+1]; + if (k.length > drawbackPos+2) + stDesc[0] = k[drawbackPos+2]; } else { - if (k.length > 2) - spDesc[0] = k[2]; - if (k.length > 3) - stDesc[0] = k[3]; + if (k.length > drawbackPos) + spDesc[0] = k[drawbackPos]; + if (k.length > drawbackPos+1) + stDesc[0] = k[drawbackPos+1]; } } else { - if (Tgt[0] == true) + if (abTgt != null) { spDesc[0] = "Target player gains " + NumLife[0] + " life."; stDesc[0] = cardName + " - target player gains life"; @@ -4595,129 +4593,65 @@ public class CardFactory implements NewConstants { 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; - - 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() - { - 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 (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); - } + private static final long serialVersionUID = -936369754466156082L; + + 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() + { + int life = AllZone.GameAction.getPlayerLife(Constant.Player.Computer).getLife(); + if (abCost.getSacCost() && life > 5) return false; + if (abCost.getSubCounter() && life > 5) return false; + if (abCost.getLifeCost() && life > 5) return false; - abGainLife.setStackDescription(stDesc[0]); - - card.addSpellAbility(abGainLife); - } + if (!ComputerUtil.canPayCost(this)) + return false; + + 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 diff --git a/src/forge/CardFactory_Creatures.java b/src/forge/CardFactory_Creatures.java index de2a9cedcac..8ed68209dca 100644 --- a/src/forge/CardFactory_Creatures.java +++ b/src/forge/CardFactory_Creatures.java @@ -7969,42 +7969,6 @@ public class CardFactory_Creatures { })); }//*************** 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 ************************** else if(cardName.equals("Painter's Servant")) { final long[] timeStamp = new long[1]; @@ -19166,44 +19130,6 @@ public class CardFactory_Creatures { card.addSpellAbility(fog); }//*************** 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 ************************** else if (cardName.equals("Yavimaya Elder")) { diff --git a/src/forge/Target_Selection.java b/src/forge/Target_Selection.java index 54d7911b42e..5d8b04d944b 100644 --- a/src/forge/Target_Selection.java +++ b/src/forge/Target_Selection.java @@ -209,17 +209,21 @@ public class Target_Selection { CardList allCards = new CardList(); allCards.addAll(AllZone.Human_Play.getCards()); allCards.addAll(AllZone.Computer_Play.getCards()); - 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 //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, - 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() { private static final long serialVersionUID = -1091595663541356356L; @@ -247,6 +251,14 @@ public class Target_Selection { } }//selectCard() + @Override + public void selectPlayer(String player) { + if (bTgtPlayer){ // todo: check if the player has Shroud too + spell.setTargetPlayer(player); + done(); + } + } + void done() { select.incrementTargets(); stop();