From 0bb5b9fe2d9c4555bba878a20ffe70cce8b90da3 Mon Sep 17 00:00:00 2001 From: slapshot5 Date: Sun, 6 Nov 2011 06:43:13 +0000 Subject: [PATCH] add an AF_EachDamage (it's a little different than others to get your head around, since it loops over source as well as targets. It's not completely generalized, but works for the cards that currently use it.) --- .../card/abilityfactory/AbilityFactory.java | 17 +- .../AbilityFactoryDealDamage.java | 320 +++++++++++++++--- 2 files changed, 296 insertions(+), 41 deletions(-) diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactory.java b/src/main/java/forge/card/abilityfactory/AbilityFactory.java index 32ad51bb798..1e69b380fa6 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactory.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactory.java @@ -352,11 +352,11 @@ public class AbilityFactory { final AbilityFactoryDealDamage dd = new AbilityFactoryDealDamage(this); if (this.isAb) { - spellAbility = dd.getAbility(); + spellAbility = dd.getAbilityDealDamage(); } else if (this.isSp) { - spellAbility = dd.getSpell(); + spellAbility = dd.getSpellDealDamage(); } else if (this.isDb) { - spellAbility = dd.getDrawback(); + spellAbility = dd.getDrawbackDealDamage(); } } @@ -371,6 +371,17 @@ public class AbilityFactory { } } + else if (this.api.equals("EachDamage")) { + final AbilityFactoryDealDamage dd = new AbilityFactoryDealDamage(this); + if (this.isAb) { + spellAbility = dd.getAbilityEachDamage(); + } else if (this.isSp) { + spellAbility = dd.getSpellEachDamage(); + } else if (this.isDb) { + spellAbility = dd.getDrawbackEachDamage(); + } + } + else if (this.api.equals("PutCounter")) { if (this.isAb) { spellAbility = AbilityFactoryCounters.createAbilityPutCounters(this); diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryDealDamage.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryDealDamage.java index e2a0897cd67..eb6e6076c36 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryDealDamage.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryDealDamage.java @@ -49,46 +49,42 @@ public class AbilityFactoryDealDamage { this.abilityFactory = newAF; this.damage = this.abilityFactory.getMapParams().get("NumDmg"); - - // Note: TgtOpp should not be used, Please use ValidTgts$ Opponent - // instead } - // ****************************************************************************************************** - // ***************************** DAMAGE - // ***************************************************************** - // ****************************************************************************************************** + // ************************************************************************* + // ***************************** DealDamage ******************************** + // ************************************************************************* /** *

- * getAbility. + * getAbilitDealDamagey. *

* * @return a {@link forge.card.spellability.SpellAbility} object. */ - public final SpellAbility getAbility() { + public final SpellAbility getAbilityDealDamage() { final SpellAbility abDamage = new AbilityActivated(this.abilityFactory.getHostCard(), this.abilityFactory.getAbCost(), this.abilityFactory.getAbTgt()) { private static final long serialVersionUID = -7560349014757367722L; @Override public boolean canPlayAI() { - return AbilityFactoryDealDamage.this.doCanPlayAI(this); + return AbilityFactoryDealDamage.this.dealDamageCanPlayAI(this); } @Override public String getStackDescription() { - return AbilityFactoryDealDamage.this.damageStackDescription(AbilityFactoryDealDamage.this.abilityFactory, this); + return AbilityFactoryDealDamage.this.dealDamageStackDescription(AbilityFactoryDealDamage.this.abilityFactory, this); } @Override public void resolve() { - AbilityFactoryDealDamage.this.doResolve(this); + AbilityFactoryDealDamage.this.dealDamageResolve(this); } @Override public boolean doTrigger(final boolean mandatory) { - return AbilityFactoryDealDamage.this.damageDoTriggerAI(AbilityFactoryDealDamage.this.abilityFactory, this, + return AbilityFactoryDealDamage.this.dealDamageDoTriggerAI(AbilityFactoryDealDamage.this.abilityFactory, this, mandatory); } }; // Ability_Activated @@ -98,29 +94,29 @@ public class AbilityFactoryDealDamage { /** *

- * getSpell. + * getSpellDealDamage. *

* * @return a {@link forge.card.spellability.SpellAbility} object. */ - public final SpellAbility getSpell() { + public final SpellAbility getSpellDealDamage() { final SpellAbility spDealDamage = new Spell(this.abilityFactory.getHostCard(), this.abilityFactory.getAbCost(), this.abilityFactory.getAbTgt()) { private static final long serialVersionUID = 7239608350643325111L; @Override public boolean canPlayAI() { - return AbilityFactoryDealDamage.this.doCanPlayAI(this); + return AbilityFactoryDealDamage.this.dealDamageCanPlayAI(this); } @Override public String getStackDescription() { - return AbilityFactoryDealDamage.this.damageStackDescription(AbilityFactoryDealDamage.this.abilityFactory, this); + return AbilityFactoryDealDamage.this.dealDamageStackDescription(AbilityFactoryDealDamage.this.abilityFactory, this); } @Override public void resolve() { - AbilityFactoryDealDamage.this.doResolve(this); + AbilityFactoryDealDamage.this.dealDamageResolve(this); } }; // Spell @@ -130,12 +126,12 @@ public class AbilityFactoryDealDamage { /** *

- * getDrawback. + * getDrawbackDealDamage. *

* * @return a {@link forge.card.spellability.SpellAbility} object. */ - public final SpellAbility getDrawback() { + public final SpellAbility getDrawbackDealDamage() { final SpellAbility dbDealDamage = new AbilitySub(this.abilityFactory.getHostCard(), this.abilityFactory.getAbTgt()) { private static final long serialVersionUID = 7239608350643325111L; @@ -147,17 +143,17 @@ public class AbilityFactoryDealDamage { @Override public String getStackDescription() { - return AbilityFactoryDealDamage.this.damageStackDescription(AbilityFactoryDealDamage.this.abilityFactory, this); + return AbilityFactoryDealDamage.this.dealDamageStackDescription(AbilityFactoryDealDamage.this.abilityFactory, this); } @Override public void resolve() { - AbilityFactoryDealDamage.this.doResolve(this); + AbilityFactoryDealDamage.this.dealDamageResolve(this); } @Override public boolean doTrigger(final boolean mandatory) { - return AbilityFactoryDealDamage.this.damageDoTriggerAI(AbilityFactoryDealDamage.this.abilityFactory, this, + return AbilityFactoryDealDamage.this.dealDamageDoTriggerAI(AbilityFactoryDealDamage.this.abilityFactory, this, mandatory); } @@ -177,7 +173,7 @@ public class AbilityFactoryDealDamage { * a {@link forge.card.spellability.SpellAbility} object. * @return a {@link java.lang.String} object. */ - private String damageStackDescription(final AbilityFactory af, final SpellAbility sa) { + private String dealDamageStackDescription(final AbilityFactory af, final SpellAbility sa) { // when damageStackDescription is called, just build exactly what is // happening final StringBuilder sb = new StringBuilder(); @@ -280,14 +276,14 @@ public class AbilityFactoryDealDamage { /** *

- * doCanPlayAI. + * dealDamageCanPlayAI. *

* * @param saMe * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - private boolean doCanPlayAI(final SpellAbility saMe) { + private boolean dealDamageCanPlayAI(final SpellAbility saMe) { final Cost abCost = this.abilityFactory.getAbCost(); final Card source = saMe.getSourceCard(); @@ -419,7 +415,7 @@ public class AbilityFactoryDealDamage { /** *

- * chooseTgtC. + * dealDamageChooseTgtC. *

* * @param d @@ -432,7 +428,7 @@ public class AbilityFactoryDealDamage { * a boolean. * @return a {@link forge.Card} object. */ - private Card chooseTgtC(final int d, final boolean noPrevention, final Player pl, final boolean mandatory) { + private Card dealDamageChooseTgtC(final int d, final boolean noPrevention, final Player pl, final boolean mandatory) { final Target tgt = this.abilityFactory.getAbTgt(); final Card source = this.abilityFactory.getHostCard(); CardList hPlay = pl.getCardsIn(Zone.Battlefield); @@ -534,7 +530,7 @@ public class AbilityFactoryDealDamage { } } - final Card c = this.chooseTgtC(dmg, noPrevention, AllZone.getHumanPlayer(), mandatory); + final Card c = this.dealDamageChooseTgtC(dmg, noPrevention, AllZone.getHumanPlayer(), mandatory); if (c != null) { tgt.addTarget(c); continue; @@ -553,7 +549,7 @@ public class AbilityFactoryDealDamage { continue; } } else if (tgt.canTgtCreature()) { - final Card c = this.chooseTgtC(dmg, noPrevention, AllZone.getHumanPlayer(), mandatory); + final Card c = this.dealDamageChooseTgtC(dmg, noPrevention, AllZone.getHumanPlayer(), mandatory); if (c != null) { tgt.addTarget(c); continue; @@ -647,7 +643,7 @@ public class AbilityFactoryDealDamage { while (tgt.getNumTargeted() < tgt.getMinTargets(saMe.getSourceCard(), saMe)) { // TODO: Consider targeting the planeswalker if (tgt.canTgtCreature()) { - final Card c = this.chooseTgtC(dmg, noPrevention, AllZone.getComputerPlayer(), mandatory); + final Card c = this.dealDamageChooseTgtC(dmg, noPrevention, AllZone.getComputerPlayer(), mandatory); if (c != null) { tgt.addTarget(c); continue; @@ -680,7 +676,7 @@ public class AbilityFactoryDealDamage { * a boolean. * @return a boolean. */ - private boolean damageDoTriggerAI(final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { + private boolean dealDamageDoTriggerAI(final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { if (!ComputerUtil.canPayCost(sa) && !mandatory) { return false; } @@ -737,7 +733,7 @@ public class AbilityFactoryDealDamage { * @param saMe * a {@link forge.card.spellability.SpellAbility} object. */ - private void doResolve(final SpellAbility saMe) { + private void dealDamageResolve(final SpellAbility saMe) { final HashMap params = this.abilityFactory.getMapParams(); final int dmg = this.getNumDamage(saMe); @@ -798,10 +794,9 @@ public class AbilityFactoryDealDamage { } } - // ****************************************************************************************************** - // ***************************** DAMAGEALL - // ************************************************************** - // ****************************************************************************************************** + // ************************************************************************* + // ***************************** DamageAll ********************************* + // ************************************************************************* /** *

* getAbilityDamageAll. @@ -1212,4 +1207,253 @@ public class AbilityFactoryDealDamage { targetPlayer.addDamage(dmg, card); } } -} + + // ************************************************************************* + // ***************************** EachDamage ******************************** + // ************************************************************************* + /** + *

+ * getAbilityEachDamage. + *

+ * + * @return a {@link forge.card.spellability.SpellAbility} object. + */ + public final SpellAbility getAbilityEachDamage() { + + final SpellAbility abEachDamage = new AbilityActivated(this.abilityFactory.getHostCard(), this.abilityFactory.getAbCost(), + this.abilityFactory.getAbTgt()) { + private static final long serialVersionUID = -1831356710492849854L; + private final AbilityFactory af = AbilityFactoryDealDamage.this.abilityFactory; + + @Override + public String getStackDescription() { + return AbilityFactoryDealDamage.this.eachDamageStackDescription(this.af, this); + } + + @Override + public boolean canPlayAI() { + return AbilityFactoryDealDamage.this.eachDamageCanPlayAI(this.af, this); + } + + @Override + public void resolve() { + AbilityFactoryDealDamage.this.eachDamageResolve(this.af, this); + } + + @Override + public boolean doTrigger(final boolean mandatory) { + return AbilityFactoryDealDamage.this.eachDamageDoTriggerAI(AbilityFactoryDealDamage.this.abilityFactory, this, + mandatory); + } + + }; + return abEachDamage; + } + + /** + *

+ * getSpellEachDamage. + *

+ * + * @return a {@link forge.card.spellability.SpellAbility} object. + */ + public final SpellAbility getSpellEachDamage() { + final SpellAbility spEachDamage = new Spell(this.abilityFactory.getHostCard(), this.abilityFactory.getAbCost(), this.abilityFactory.getAbTgt()) { + private static final long serialVersionUID = 8004957182752984818L; + private final AbilityFactory af = AbilityFactoryDealDamage.this.abilityFactory; + private final HashMap params = this.af.getMapParams(); + + @Override + public String getStackDescription() { + if (this.params.containsKey("SpellDescription")) { + return AbilityFactoryDealDamage.this.abilityFactory.getHostCard().getName() + " - " + + this.params.get("SpellDescription"); + } else { + return AbilityFactoryDealDamage.this.eachDamageStackDescription(this.af, this); + } + } + + @Override + public boolean canPlayAI() { + return AbilityFactoryDealDamage.this.eachDamageCanPlayAI(this.af, this); + } + + @Override + public void resolve() { + AbilityFactoryDealDamage.this.eachDamageResolve(this.af, this); + } + + }; + return spEachDamage; + } + + /** + *

+ * getDrawbackEachDamage. + *

+ * + * @return a {@link forge.card.spellability.SpellAbility} object. + */ + public final SpellAbility getDrawbackEachDamage() { + final SpellAbility dbEachDamage = new AbilitySub(this.abilityFactory.getHostCard(), this.abilityFactory.getAbTgt()) { + private static final long serialVersionUID = -6169562107675964474L; + private final AbilityFactory af = AbilityFactoryDealDamage.this.abilityFactory; + + @Override + public String getStackDescription() { + return AbilityFactoryDealDamage.this.eachDamageStackDescription(this.af, this); + } + + @Override + public void resolve() { + AbilityFactoryDealDamage.this.eachDamageResolve(this.af, this); + } + + @Override + public boolean chkAIDrawback() { + // check AI life before playing this drawback? + return true; + } + + @Override + public boolean doTrigger(final boolean mandatory) { + return AbilityFactoryDealDamage.this.eachDamageDoTriggerAI(AbilityFactoryDealDamage.this.abilityFactory, this, + mandatory); + } + + }; + return dbEachDamage; + } + + /** + *

+ * eachDamageStackDescription. + *

+ * + * @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 String eachDamageStackDescription(final AbilityFactory af, final SpellAbility sa) { + final StringBuilder sb = new StringBuilder(); + final HashMap params = af.getMapParams(); + + if (sa instanceof AbilitySub) { + sb.append(" "); + } else { + sb.append(sa.getSourceCard()).append(" - "); + } + + ArrayList tgtPlayers; + + Target tgt = af.getAbTgt(); + if (tgt != null) { + tgtPlayers = tgt.getTargetPlayers(); + } else { + tgtPlayers = AbilityFactory.getDefinedPlayers(sa.getSourceCard(), params.get("DefinedPlayers"), sa); + } + + String desc = params.get("ValidCards"); + if (params.containsKey("ValidDescription")) { + desc = params.get("ValidDescription"); + } + + String dmg = ""; + if (params.containsKey("DamageDesc")) { + dmg = params.get("DamageDesc"); + } else { + dmg += getNumDamage(sa) + " damage"; + } + + sb.append("Each ").append(desc).append(" deals ").append(dmg).append(" to "); + for (Player p : tgtPlayers) { + sb.append(p); + } + if (params.containsKey("DefinedCards")) { + if (params.get("DefinedCards").equals("Self")) { + sb.append(" itself"); + } + } + sb.append("."); + + final AbilitySub abSub = sa.getSubAbility(); + if (abSub != null) { + sb.append(abSub.getStackDescription()); + } + + return sb.toString(); + } + + private boolean eachDamageCanPlayAI(final AbilityFactory af, final SpellAbility sa) { + + final Target tgt = sa.getTarget(); + + if (sa.getTarget() != null) { + tgt.resetTargets(); + sa.getTarget().addTarget(AllZone.getHumanPlayer()); + } + + return shouldTgtP(sa, getNumDamage(sa), false); + } + + private boolean eachDamageDoTriggerAI(final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { + if (!ComputerUtil.canPayCost(sa) && !mandatory) { + return false; + } + + if (sa.getSubAbility() != null) { + return sa.getSubAbility().doTrigger(mandatory); + } + + return eachDamageCanPlayAI(af, sa); + } + + private void eachDamageResolve(final AbilityFactory af, final SpellAbility sa) { + final HashMap params = af.getMapParams(); + final Card card = sa.getSourceCard(); + + CardList sources = AllZoneUtil.getCardsIn(Zone.Battlefield); + if (params.containsKey("ValidCards")) { + sources = sources.getValidCards(params.get("ValidCards"), card.getController(), card); + } + + ArrayList tgts = new ArrayList(); + if (sa.getTarget() == null) { + tgts = AbilityFactory.getDefinedObjects(sa.getSourceCard(), params.get("DefinedPlayers"), sa); + } else { + tgts = sa.getTarget().getTargets(); + } + + final boolean targeted = (this.abilityFactory.getAbTgt() != null); + + for (final Object o : tgts) { + for (Card source : sources) { + int dmg = CardFactoryUtil.xCount(source, card.getSVar("X")); + System.out.println(source+" deals "+dmg+" damage to "+o.toString()); + if (o instanceof Card) { + final Card c = (Card) o; + if (AllZoneUtil.isCardInPlay(c) && (!targeted || CardFactoryUtil.canTarget(this.abilityFactory.getHostCard(), c))) { + c.addDamage(dmg, source); + } + + } else if (o instanceof Player) { + final Player p = (Player) o; + if (!targeted || p.canTarget(sa)) { + p.addDamage(dmg, source); + } + } + } + } + + if (params.containsKey("DefinedCards") && params.get("DefinedCards").equals("Self")) { + for (Card source : sources) { + int dmg = CardFactoryUtil.xCount(source, card.getSVar("X")); + System.out.println(source+" deals "+dmg+" damage to "+source); + source.addDamage(dmg, source); + } + } + } + +} //end class AbilityFactoryDealDamage