From 5a8280199a130bf6201c05611a514729c4ca6cac Mon Sep 17 00:00:00 2001 From: slapshot5 Date: Sun, 28 Aug 2011 07:56:20 +0000 Subject: [PATCH] add an AbilityFactory for MoveCounter (doesn't support targeting. requires Source$ and Defined$ which both take Defined values.) --- .../card/abilityFactory/AbilityFactory.java | 9 + .../AbilityFactory_Counters.java | 256 ++++++++++++++++++ 2 files changed, 265 insertions(+) diff --git a/src/main/java/forge/card/abilityFactory/AbilityFactory.java b/src/main/java/forge/card/abilityFactory/AbilityFactory.java index 45920059bb8..2dfc1de3f8b 100644 --- a/src/main/java/forge/card/abilityFactory/AbilityFactory.java +++ b/src/main/java/forge/card/abilityFactory/AbilityFactory.java @@ -338,6 +338,15 @@ public class AbilityFactory { else if (isDb) SA = AbilityFactory_Counters.createDrawbackProliferate(this); } + + else if (API.equals("MoveCounter")) { + if (isAb) + SA = AbilityFactory_Counters.createAbilityMoveCounters(this); + else if (isSp) + SA = AbilityFactory_Counters.createSpellMoveCounters(this); + else if (isDb) + SA = AbilityFactory_Counters.createDrawbackMoveCounters(this); + } else if (API.equals("ChangeZone")) { if (isAb) diff --git a/src/main/java/forge/card/abilityFactory/AbilityFactory_Counters.java b/src/main/java/forge/card/abilityFactory/AbilityFactory_Counters.java index 865499f19ad..6df48259ac8 100644 --- a/src/main/java/forge/card/abilityFactory/AbilityFactory_Counters.java +++ b/src/main/java/forge/card/abilityFactory/AbilityFactory_Counters.java @@ -1636,5 +1636,261 @@ public class AbilityFactory_Counters { tgtCard.subtractCounter(Counters.valueOf(type), counterAmount); } } + + // ******************************************* + // ************ MoveCounters ***************** + // ******************************************* + + /** + *

createAbilityMoveCounters.

+ * + * @param af a {@link forge.card.abilityFactory.AbilityFactory} object. + * @return a {@link forge.card.spellability.SpellAbility} object. + */ + public static SpellAbility createAbilityMoveCounters(final AbilityFactory af) { + final SpellAbility abMoveCounter = new Ability_Activated(af.getHostCard(), af.getAbCost(), af.getAbTgt()) { + private static final long serialVersionUID = 4602375375570571305L; + + @Override + public String getStackDescription() { + return moveCounterStackDescription(af, this); + } + + @Override + public boolean canPlayAI() { + return moveCounterCanPlayAI(af, this); + } + + @Override + public void resolve() { + moveCounterResolve(af, this); + } + + @Override + public boolean doTrigger(boolean mandatory) { + return moveCounterDoTriggerAI(af, this, mandatory); + } + + }; + return abMoveCounter; + } + + /** + *

createSpellMoveCounters.

+ * + * @param af a {@link forge.card.abilityFactory.AbilityFactory} object. + * @return a {@link forge.card.spellability.SpellAbility} object. + */ + public static SpellAbility createSpellMoveCounters(final AbilityFactory af) { + final SpellAbility spMoveCounter = new Spell(af.getHostCard(), af.getAbCost(), af.getAbTgt()) { + private static final long serialVersionUID = 7987458386444373863L; + + @Override + public String getStackDescription() { + return moveCounterStackDescription(af, this); + } + + @Override + public boolean canPlayAI() { + return moveCounterCanPlayAI(af, this); + } + + @Override + public void resolve() { + moveCounterResolve(af, this); + } + + }; + return spMoveCounter; + } + + /** + *

createDrawbackMoveCounters.

+ * + * @param af a {@link forge.card.abilityFactory.AbilityFactory} object. + * @return a {@link forge.card.spellability.SpellAbility} object. + */ + public static SpellAbility createDrawbackMoveCounters(final AbilityFactory af) { + final SpellAbility dbMoveCounter = new Ability_Sub(af.getHostCard(), af.getAbTgt()) { + private static final long serialVersionUID = -9185934729634278014L; + + @Override + public String getStackDescription() { + return moveCounterStackDescription(af, this); + } + + @Override + public void resolve() { + moveCounterResolve(af, this); + } + + @Override + public boolean chkAI_Drawback() { + return moveCounterPlayDrawbackAI(af, this); + } + + @Override + public boolean doTrigger(boolean mandatory) { + return moveCounterDoTriggerAI(af, this, mandatory); + } + + }; + return dbMoveCounter; + } + + /** + *

moveCounterStackDescription.

+ * + * @param af a {@link forge.card.abilityFactory.AbilityFactory} object. + * @param sa a {@link forge.card.spellability.SpellAbility} object. + * @return a {@link java.lang.String} object. + */ + private static String moveCounterStackDescription(AbilityFactory af, SpellAbility sa) { + HashMap params = af.getMapParams(); + StringBuilder sb = new StringBuilder(); + Card host = af.getHostCard(); + + if (sa instanceof Ability_Sub) { + sb.append(" "); + } + else { + sb.append(sa.getSourceCard().getName()).append(" - "); + } + + ArrayList srcCards = AbilityFactory.getDefinedCards(host, params.get("Source"), sa); + Card source = null; + if(srcCards.size() > 0) { + source = srcCards.get(0); + } + + ArrayList destCards = AbilityFactory.getDefinedCards(host, params.get("Defined"), sa); + Card dest = null; + if(destCards.size() > 0) { + dest = destCards.get(0); + } + + Counters cType = Counters.valueOf(params.get("CounterType")); + int amount = AbilityFactory.calculateAmount(af.getHostCard(), params.get("CounterNum"), sa); + + sb.append("Move ").append(amount).append(" ").append(cType.getName()) + .append(" counter"); + if (amount != 1) sb.append("s"); + sb.append(" from "); + sb.append(source).append(" to ").append(dest); + + sb.append("."); + + Ability_Sub abSub = sa.getSubAbility(); + if (abSub != null) { + sb.append(abSub.getStackDescription()); + } + + return sb.toString(); + } + + /** + *

moveCounterCanPlayAI.

+ * + * @param af a {@link forge.card.abilityFactory.AbilityFactory} object. + * @param sa a {@link forge.card.spellability.SpellAbility} object. + * @return a boolean. + */ + private static boolean moveCounterCanPlayAI(final AbilityFactory af, final SpellAbility sa) { + // AI needs to be expanded, since this function can be pretty complex based on what the expected targets could be + HashMap params = af.getMapParams(); + Random r = MyRandom.random; + String amountStr = params.get("CounterNum"); + + // TODO handle proper calculation of X values based on Cost + int amount = AbilityFactory.calculateAmount(af.getHostCard(), amountStr, sa); + + //don't use it if no counters to add + if (amount <= 0) return false; + + // prevent run-away activations - first time will always return true + boolean chance = false; + + Ability_Sub subAb = sa.getSubAbility(); + if (subAb != null) + chance &= subAb.chkAI_Drawback(); + + if (AbilityFactory.playReusable(sa)) + return chance; + + return ((r.nextFloat() < .6667) && chance); + }//moveCounterCanPlayAI + + /** + *

moveCounterPlayDrawbackAI.

+ * + * @param af a {@link forge.card.abilityFactory.AbilityFactory} object. + * @param sa a {@link forge.card.spellability.SpellAbility} object. + * @return a boolean. + */ + private static boolean moveCounterPlayDrawbackAI(final AbilityFactory af, final SpellAbility sa) { + boolean chance = false; + + Ability_Sub subAb = sa.getSubAbility(); + if (subAb != null) + chance &= subAb.chkAI_Drawback(); + + return chance; + }//moveCounterPlayDrawbackAI + + /** + *

moveCounterDoTriggerAI.

+ * + * @param af a {@link forge.card.abilityFactory.AbilityFactory} object. + * @param sa a {@link forge.card.spellability.SpellAbility} object. + * @param mandatory a boolean. + * @return a boolean. + */ + private static boolean moveCounterDoTriggerAI(final AbilityFactory af, final SpellAbility sa, boolean mandatory) { + // if there is a cost, it's gotta be optional + if (!ComputerUtil.canPayCost(sa) && !mandatory) + return false; + + Ability_Sub subAb = sa.getSubAbility(); + if (subAb != null) { + //chance &= subAb.doTrigger(mandatory); + } + + return false; + } + + /** + *

moveCounterResolve.

+ * + * @param af a {@link forge.card.abilityFactory.AbilityFactory} object. + * @param sa a {@link forge.card.spellability.SpellAbility} object. + */ + private static void moveCounterResolve(final AbilityFactory af, final SpellAbility sa) { + HashMap params = af.getMapParams(); + Card host = af.getHostCard(); + + Counters cType = Counters.valueOf(params.get("CounterType")); + int amount = AbilityFactory.calculateAmount(af.getHostCard(), params.get("CounterNum"), sa); + + ArrayList srcCards = AbilityFactory.getDefinedCards(host, params.get("Source"), sa); + Card source = null; + if(srcCards.size() > 0) { + source = srcCards.get(0); + } + + ArrayList destCards = AbilityFactory.getDefinedCards(host, params.get("Defined"), sa); + Card dest = null; + if(destCards.size() > 0) { + dest = destCards.get(0); + } + + if(null != source && null != dest) { + if(source.getCounters(cType) >= amount) { + if(!dest.hasKeyword("CARDNAME can't have counters placed on it.")) { + dest.addCounter(cType,amount); + source.subtractCounter(cType, amount); + } + } + } + }//moveCounterResolve }//end class AbilityFactory_Counters