From 6ea2a161fbb33f1776b97a60be83b7c7e6747b49 Mon Sep 17 00:00:00 2001 From: jendave Date: Sat, 6 Aug 2011 09:36:57 +0000 Subject: [PATCH] Conversion of spPump and abPump to AbilityFactory - SP$Pump and AB$Pump. Only supports normal targeted pumps and self-pumps. Equipment pumps are not supported. Sample cards - Captive Flame, Colos Yearling and Giant Growth. --- res/cardsfolder/captive_flame.txt | 3 +- res/cardsfolder/colos_yearling.txt | 3 +- res/cardsfolder/giant_growth.txt | 3 +- src/forge/AbilityFactory.java | 15 +- src/forge/AbilityFactory_Pump.java | 313 ++++++++++++++++++++++++++++- 5 files changed, 331 insertions(+), 6 deletions(-) diff --git a/res/cardsfolder/captive_flame.txt b/res/cardsfolder/captive_flame.txt index 312b1fe135b..c22b4ad76d9 100644 --- a/res/cardsfolder/captive_flame.txt +++ b/res/cardsfolder/captive_flame.txt @@ -2,7 +2,8 @@ Name:Captive Flame ManaCost:2 R Types:Enchantment Text:no text -K:abPumpTgtC R:+1/+0 +# K:abPumpTgtC R:+1/+0 +A:AB$Pump|Cost$R|Tgt$TgtC|NumAtt$+1|SpellDescription$Target creature gets +1/+0 until end of turn. SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/captive_flame.jpg End diff --git a/res/cardsfolder/colos_yearling.txt b/res/cardsfolder/colos_yearling.txt index 27dbe24fe97..455fe3e5d3a 100644 --- a/res/cardsfolder/colos_yearling.txt +++ b/res/cardsfolder/colos_yearling.txt @@ -4,7 +4,8 @@ Types:Creature Goat Beast Text:no text PT:1/1 K:Mountainwalk -K:abPump R:+1/+0 +# K:abPump R:+1/+0 +A:AB$Pump|Cost$R|NumAtt$+1|SpellDescription$Colos Yearling gets +1/+0 until end of turn. SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/colos_yearling.jpg End diff --git a/res/cardsfolder/giant_growth.txt b/res/cardsfolder/giant_growth.txt index 583c5e10ee2..bdc2b5cea24 100644 --- a/res/cardsfolder/giant_growth.txt +++ b/res/cardsfolder/giant_growth.txt @@ -2,7 +2,8 @@ Name:Giant Growth ManaCost:G Types:Instant Text:no text -K:spPumpTgt:+3/+3 +# K:spPumpTgt:+3/+3 +A:SP$Pump|Cost$G|ValidTgts$Creature|NumAtt$+3|NumDef$+3|SpellDescription$Target creature gets +3/+3 until end of turn.|TgtPrompt$Select target creature. SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/giant_growth.jpg End diff --git a/src/forge/AbilityFactory.java b/src/forge/AbilityFactory.java index d0c4e302fc4..a295cf20f0f 100644 --- a/src/forge/AbilityFactory.java +++ b/src/forge/AbilityFactory.java @@ -179,7 +179,6 @@ public class AbilityFactory { } - // additional API keywords here if (API.equals("PutCounter")){ if (isAb) SA = AbilityFactory_Counters.createAbilityPutCounters(this); @@ -196,6 +195,18 @@ public class AbilityFactory { } } + if (API.equals("Pump")) + { + AbilityFactory_Pump afPump = new AbilityFactory_Pump(this); + + if (isAb) + SA = afPump.getAbility(); + if (isSp) + SA = afPump.getSpell(); + + hostCard.setSVar("PlayMain1", "TRUE"); + } + if (API.equals("GainLife")){ if (isAb) SA = AbilityFactory_AlterLife.createAbilityGainLife(this); @@ -203,7 +214,7 @@ public class AbilityFactory { SA = AbilityFactory_AlterLife.createSpellGainLife(this); } } - + if (API.equals("LoseLife")){ if (isAb) SA = AbilityFactory_AlterLife.createAbilityLoseLife(this); diff --git a/src/forge/AbilityFactory_Pump.java b/src/forge/AbilityFactory_Pump.java index e51493627bd..d6a9622a34c 100644 --- a/src/forge/AbilityFactory_Pump.java +++ b/src/forge/AbilityFactory_Pump.java @@ -1,6 +1,8 @@ package forge; +import java.util.ArrayList; import java.util.HashMap; +import java.util.Random; public class AbilityFactory_Pump { @@ -8,6 +10,7 @@ public class AbilityFactory_Pump { private final int NumDefense[] = {-1138}; private final String AttackX[] = {"none"}; private final String DefenseX[] = {"none"}; + private final ArrayList Keywords = new ArrayList(); private AbilityFactory AF = null; private HashMap params = null; @@ -42,7 +45,315 @@ public class AbilityFactory_Pump { else if(tmp.matches("[\\+\\-][0-9]")) NumAttack[0] = Integer.parseInt(tmp.replace("+", "")); - + } + + if (params.containsKey("NumDef")) + { + String tmp = params.get("NumDef"); + if(tmp.matches("[\\+\\-][XY]")) + { + String xy = hostCard.getSVar(tmp.replaceAll("[\\+\\-]", "")); + if(xy.startsWith("Count$")) { + String kk[] = xy.split("\\$"); + DefenseX[0] = kk[1]; + + if(tmp.contains("-")) + { + if(DefenseX[0].contains("/")) + DefenseX[0] = DefenseX[0].replace("/", "/Negative"); + else + DefenseX[0] += "/Negative"; + } + } + } + else if(tmp.matches("[\\+\\-][0-9]")) + NumDefense[0] = Integer.parseInt(tmp.replace("+", "")); + + } + + Keywords.add("none"); + if (params.containsKey("KW")) + { + String tmp = params.get("KW"); + String kk[] = tmp.split(" & "); + + Keywords.clear(); + for (int i=0; i chance) + return false; + } + //if (bPumpEquipped && card.getEquippingCard() == null) return false; + + if (!ComputerUtil.canPayCost(this)) + return false; + + int defense = getNumDefense(); + + if(AllZone.Phase.getPhase().equals(Constant.Phase.Main2)) return false; + + if(!AF.getAbTgt().doesTarget()) { + Card creature; + //if (bPumpEquipped) + // creature = card.getEquippingCard(); + //else + creature = hostCard; + + if((creature.getNetDefense() + defense > 0) && (!creature.hasAnyKeyword((String[]) Keywords.toArray()))) { + if(creature.hasSickness() && Keywords.contains("Haste")) + return true; + else if (creature.hasSickness() ^ Keywords.contains("Haste")) + return false; + else { + Random r = new Random(); + if(r.nextFloat() <= Math.pow(.6667, hostCard.getAbilityUsed())) + return CardFactoryUtil.AI_doesCreatureAttack(creature); + } + } + } + else + return doTgtAI(this); + + return false; + } + + @Override + public boolean canPlay() { + return (Cost_Payment.canPayAdditionalCosts(AF.getAbCost(), this) && CardFactoryUtil.canUseAbility(hostCard) && super.canPlay()); + } + + @Override + public void resolve() { +// final Card[] creature = new Card[1]; +// if(abTgt.doesTarget()) +// creature[0] = getTargetCard(); +// else if (bPumpEquipped) +// creature[0] = card.getEquippingCard(); +// else +// creature[0] = card; + + doResolve(this); + + hostCard.setAbilityUsed(hostCard.getAbilityUsed() + 1); + }//resolve() + + + };//SpellAbility + + return abPump; + } + + private int getNumAttack() { + if(NumAttack[0] != -1138) + return NumAttack[0]; + + if(!AttackX[0].equals("none")) + return CardFactoryUtil.xCount(hostCard, AttackX[0]); + + return 0; + } + + private int getNumDefense() { + if(NumDefense[0] != -1138) + return NumDefense[0]; + + if(!DefenseX[0].equals("none")) + return CardFactoryUtil.xCount(hostCard, DefenseX[0]); + + return 0; + } + + private CardList getPumpCreatures() { + CardList list = new CardList(AllZone.Computer_Play.getCards()); + list = list.getType("Creature"); + list = list.filter(new CardListFilter() { + public boolean addCard(Card c) { + boolean hSick = c.hasSickness(); + boolean kHaste = Keywords.contains("Haste"); + boolean cTgt = CardFactoryUtil.canTarget(hostCard, c); + + if(hSick && kHaste) + return cTgt; + + boolean cAtt = CardFactoryUtil.AI_doesCreatureAttack(c); + boolean kSize = Keywords.size() > 0; + String KWs[] = {"none"}; + if (!Keywords.get(0).equals("none")) + KWs = (String[]) Keywords.toArray(); + + boolean hKW = c.hasAnyKeyword(KWs); + return (cAtt && cTgt && (kSize && !hKW) && !(!hSick && kHaste)); + + //return false; + } + }); + return list; + } + + private CardList getCurseCreatures() + { + final int defense = getNumDefense(); + + CardList list = new CardList(AllZone.Human_Play.getCards()); + list = list.filter(new CardListFilter() { + public boolean addCard(Card c) { + return CardFactoryUtil.canTarget(hostCard, c) && c.isCreature(); + } + }); + if (defense < 0 && !list.isEmpty()) { // with spells that give -X/-X, compi will try to destroy a creature + list = list.filter(new CardListFilter() { + public boolean addCard(Card c) { + if (c.getNetDefense() <= -defense ) return true; // can kill indestructible creatures + return (c.getKillDamage() <= -defense && !c.hasKeyword("Indestructible")); + } + }); // leaves all creatures that will be destroyed + } // -X/-X end + + return list; + } + + private boolean doTgtAI(SpellAbility sa) + { + int defense = getNumDefense(); + + String curPhase = AllZone.Phase.getPhase(); + if(curPhase.equals(Constant.Phase.Main2) && !(AF.isCurse() && defense < 0)) + return false; + + boolean goodt = false; + Card t = new Card(); + + if (AF.isCurse()) { // Curse means spells with negative effect + CardList list = getCurseCreatures(); + if (!list.isEmpty()) { + t = CardFactoryUtil.AI_getBestCreature(list); + goodt = true; + } + } + else { // no Curse means spell with positive effect + CardList list = getPumpCreatures(); + if(!list.isEmpty()) { + while(goodt == false && !list.isEmpty()) { + t = CardFactoryUtil.AI_getBestCreature(list); + if((t.getNetDefense() + defense) > 0) goodt = true; + else list.remove(t); + } + } + } + if(goodt == true) { + sa.setTargetCard(t); + return true; + } + + return false; + + } + + private void doResolve(SpellAbility sa) + { + Card tgtCard = sa.getTargetCard(); + + final Card[] creature = new Card[1]; + if (AF.isTargeted()) + { + if (!CardFactoryUtil.canTarget(hostCard, tgtCard)) + return; + else + creature[0] = tgtCard; + } + //else if equipped + + else + creature[0] = hostCard; + + if(!AllZone.GameAction.isCardInPlay(creature[0])) + return; + + final int a = getNumAttack(); + final int d = getNumDefense(); + + final Command untilEOT = new Command() { + private static final long serialVersionUID = -42244224L; + + public void execute() { + if(AllZone.GameAction.isCardInPlay(creature[0])) { + creature[0].addTempAttackBoost(-1 * a); + creature[0].addTempDefenseBoost(-1 * d); + + if(Keywords.size() > 0) + { + for (int i=0; i 0) + { + for (int i=0; i