diff --git a/src/main/java/forge/card/abilityFactory/AbilityFactory.java b/src/main/java/forge/card/abilityFactory/AbilityFactory.java index 3f2a26fbcaf..b1de257619d 100644 --- a/src/main/java/forge/card/abilityFactory/AbilityFactory.java +++ b/src/main/java/forge/card/abilityFactory/AbilityFactory.java @@ -471,6 +471,16 @@ public class AbilityFactory { SA = AbilityFactory_AlterLife.createDrawbackSetLife(this); } } + + else if (API.equals("ExchangeLife")) { + if (isAb) { + SA = AbilityFactory_AlterLife.createAbilityExchangeLife(this); + } else if (isSp) { + SA = AbilityFactory_AlterLife.createSpellExchangeLife(this); + } else if (isDb) { + SA = AbilityFactory_AlterLife.createDrawbackExchangeLife(this); + } + } else if (API.equals("Poison")) { if (isAb) { diff --git a/src/main/java/forge/card/abilityFactory/AbilityFactory_AlterLife.java b/src/main/java/forge/card/abilityFactory/AbilityFactory_AlterLife.java index 4cf5a129c2a..21fc434ef0d 100644 --- a/src/main/java/forge/card/abilityFactory/AbilityFactory_AlterLife.java +++ b/src/main/java/forge/card/abilityFactory/AbilityFactory_AlterLife.java @@ -1243,4 +1243,267 @@ public class AbilityFactory_AlterLife { } } + // ************************************************************************* + // ************************ EXCHANGE LIFE ********************************** + // ************************************************************************* + + /** + *
createAbilityExchangeLife.
+ * + * @param af a {@link forge.card.abilityFactory.AbilityFactory} object. + * @return a {@link forge.card.spellability.SpellAbility} object. + */ + public static SpellAbility createAbilityExchangeLife(final AbilityFactory af) { + final SpellAbility abExLife = new Ability_Activated(af.getHostCard(), af.getAbCost(), af.getAbTgt()) { + private static final long serialVersionUID = 212548821691286311L; + + @Override + public String getStackDescription() { + return exchangeLifeStackDescription(af, this); + } + + @Override + public boolean canPlayAI() { + return exchangeLifeCanPlayAI(af, this); + } + + @Override + public void resolve() { + exchangeLifeResolve(af, this); + } + + @Override + public boolean doTrigger(final boolean mandatory) { + return exchangeLifeDoTriggerAI(af, this, mandatory); + } + + }; + return abExLife; + } + + /** + *createSpellExchangeLife.
+ * + * @param af a {@link forge.card.abilityFactory.AbilityFactory} object. + * @return a {@link forge.card.spellability.SpellAbility} object. + */ + public static SpellAbility createSpellExchangeLife(final AbilityFactory af) { + final SpellAbility spExLife = new Spell(af.getHostCard(), af.getAbCost(), af.getAbTgt()) { + private static final long serialVersionUID = 3512136004868367924L; + + @Override + public String getStackDescription() { + return exchangeLifeStackDescription(af, this); + } + + public boolean canPlayAI() { + return exchangeLifeCanPlayAI(af, this); + } + + @Override + public void resolve() { + exchangeLifeResolve(af, this); + } + + }; + return spExLife; + } + + /** + *createDrawbackExchangeLife.
+ * + * @param af a {@link forge.card.abilityFactory.AbilityFactory} object. + * @return a {@link forge.card.spellability.SpellAbility} object. + */ + public static SpellAbility createDrawbackExchangeLife(final AbilityFactory af) { + final SpellAbility dbExLife = new Ability_Sub(af.getHostCard(), af.getAbTgt()) { + private static final long serialVersionUID = 6951913863491173483L; + + @Override + public String getStackDescription() { + return exchangeLifeStackDescription(af, this); + } + + @Override + public boolean canPlayAI() { + return exchangeLifeCanPlayAI(af, this); + } + + @Override + public void resolve() { + exchangeLifeResolve(af, this); + } + + @Override + public boolean chkAI_Drawback() { + return true; + } + + @Override + public boolean doTrigger(final boolean mandatory) { + return exchangeLifeDoTriggerAI(af, this, mandatory); + } + + }; + return dbExLife; + } + + /** + *exchangeLifeStackDescription.
+ * + * @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 exchangeLifeStackDescription(final AbilityFactory af, final SpellAbility sa) { + HashMapexchangeLifeCanPlayAI.
+ * + * @param af a {@link forge.card.abilityFactory.AbilityFactory} object. + * @param sa a {@link forge.card.spellability.SpellAbility} object. + * @return a boolean. + */ + private static boolean exchangeLifeCanPlayAI(final AbilityFactory af, final SpellAbility sa) { + Random r = MyRandom.random; + int life = AllZone.getComputerPlayer().getLife(); + int hLife = AllZone.getHumanPlayer().getLife(); + + if (!AllZone.getComputerPlayer().canGainLife()) { + return false; + } + + // prevent run-away activations - first time will always return true + boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn()); + + /* + * TODO - There is one card that takes two targets (Soul Conduit) + * and one card that has a conditional (Psychic Transfer) that are not currently handled + */ + Target tgt = sa.getTarget(); + if (tgt != null) { + tgt.resetTargets(); + if (AllZone.getHumanPlayer().canTarget(sa)) { + //never target self, that would be silly for exchange + tgt.addTarget(AllZone.getHumanPlayer()); + if (!AllZone.getHumanPlayer().canLoseLife()) { + return false; + } + } + } + + //if life is in danger, always activate + if (life < 5 && hLife > life) { + return true; + } + + //cost includes sacrifice probably, so make sure it's worth it + chance &= (hLife > (life + 8)); + + return ((r.nextFloat() < .6667) && chance); + } + + /** + *exchangeLifeDoTriggerAI.
+ * + * @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 exchangeLifeDoTriggerAI(final AbilityFactory af, final SpellAbility sa, + final boolean mandatory) + { + //this can pretty much return false for now since nothing of this type triggers + return false; + } + + /** + *exchangeLifeResolve.
+ * + * @param af a {@link forge.card.abilityFactory.AbilityFactory} object. + * @param sa a {@link forge.card.spellability.SpellAbility} object. + */ + private static void exchangeLifeResolve(final AbilityFactory af, final SpellAbility sa) { + HashMap