diff --git a/.gitattributes b/.gitattributes index 1a49bfdc94f..af3972c64a1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -12474,7 +12474,6 @@ src/main/java/forge/card/abilityfactory/AbilityFactoryDealDamage.java svneol=nat src/main/java/forge/card/abilityfactory/AbilityFactoryDebuff.java svneol=native#text/plain src/main/java/forge/card/abilityfactory/AbilityFactoryDelayedTrigger.java svneol=native#text/plain src/main/java/forge/card/abilityfactory/AbilityFactoryDestroy.java svneol=native#text/plain -src/main/java/forge/card/abilityfactory/AbilityFactoryEffect.java svneol=native#text/plain src/main/java/forge/card/abilityfactory/AbilityFactoryEndGameCondition.java svneol=native#text/plain src/main/java/forge/card/abilityfactory/AbilityFactoryGainControl.java svneol=native#text/plain src/main/java/forge/card/abilityfactory/AbilityFactoryMana.java svneol=native#text/plain @@ -12507,6 +12506,7 @@ src/main/java/forge/card/abilityfactory/ai/DamagePreventAllAi.java -text src/main/java/forge/card/abilityfactory/ai/DiscardAi.java -text src/main/java/forge/card/abilityfactory/ai/DrainManaAi.java -text src/main/java/forge/card/abilityfactory/ai/DrawAi.java svneol=native#text/plain +src/main/java/forge/card/abilityfactory/ai/EffectAi.java -text src/main/java/forge/card/abilityfactory/ai/EndTurnAi.java -text src/main/java/forge/card/abilityfactory/ai/LifeExchangeAi.java -text src/main/java/forge/card/abilityfactory/ai/LifeGainAi.java -text @@ -12534,6 +12534,7 @@ src/main/java/forge/card/abilityfactory/effects/DamagePreventEffect.java -text src/main/java/forge/card/abilityfactory/effects/DiscardEffect.java -text src/main/java/forge/card/abilityfactory/effects/DrainManaEffect.java -text src/main/java/forge/card/abilityfactory/effects/DrawEffect.java -text +src/main/java/forge/card/abilityfactory/effects/EffectEffect.java -text src/main/java/forge/card/abilityfactory/effects/EndTurnEffect.java -text src/main/java/forge/card/abilityfactory/effects/HelperAnimate.java svneol=native#text/plain src/main/java/forge/card/abilityfactory/effects/LifeExchangeEffect.java -text diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactory.java b/src/main/java/forge/card/abilityfactory/AbilityFactory.java index f86b11c3746..7b65a41003d 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactory.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactory.java @@ -723,13 +723,8 @@ public class AbilityFactory { } else if (this.api.equals("Effect")) { - if (this.isAb) { - spellAbility = AbilityFactoryEffect.createAbilityEffect(this); - } else if (this.isSp) { - spellAbility = AbilityFactoryEffect.createSpellEffect(this); - } else if (this.isDb) { - spellAbility = AbilityFactoryEffect.createDrawbackEffect(this); - } + ai = new EffectAi(); + se = new EffectEffect(); } else if (this.api.equals("EndTurn")) { diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryEffect.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryEffect.java deleted file mode 100644 index 45c20d8c5ff..00000000000 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryEffect.java +++ /dev/null @@ -1,594 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.card.abilityfactory; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Random; - -import com.google.common.base.Predicate; - -import forge.Card; - -import forge.CardLists; -import forge.Command; -import forge.Singletons; -import forge.card.cardfactory.CardFactoryUtil; -import forge.card.cost.Cost; -import forge.card.replacement.ReplacementEffect; -import forge.card.replacement.ReplacementHandler; -import forge.card.spellability.AbilityActivated; -import forge.card.spellability.AbilitySub; -import forge.card.spellability.Spell; -import forge.card.spellability.SpellAbility; -import forge.card.spellability.Target; -import forge.card.trigger.Trigger; -import forge.card.trigger.TriggerHandler; -import forge.card.trigger.TriggerType; -import forge.game.GameState; -import forge.game.phase.CombatUtil; -import forge.game.phase.PhaseHandler; -import forge.game.phase.PhaseType; -import forge.game.player.ComputerUtil; -import forge.game.player.Player; -import forge.game.zone.ZoneType; -import forge.util.MyRandom; - - -/** - *

- * AbilityFactoryEffect class. - *

- * - * @author Forge - * @version $Id$ - */ -public class AbilityFactoryEffect { - /** - *

- * createAbilityEffect. - *

- * - * @param abilityFactory - * a {@link forge.card.abilityfactory.AbilityFactory} object. - * @return a {@link forge.card.spellability.SpellAbility} object. - */ - public static SpellAbility createAbilityEffect(final AbilityFactory abilityFactory) { - class AbilityEffect extends AbilityActivated { - public AbilityEffect(final Card ca, final Cost co, final Target t) { - super(ca, co, t); - } - - @Override - public AbilityActivated getCopy() { - AbilityActivated res = new AbilityEffect(getSourceCard(), - getPayCosts(), getTarget() == null ? null : new Target(getTarget())); - CardFactoryUtil.copySpellAbility(this, res); - return res; - } - - private static final long serialVersionUID = 8869422603616247307L; - - private final AbilityFactory af = abilityFactory; - - @Override - public String getStackDescription() { - // when getStackDesc is called, just build exactly what is - // happening - return AbilityFactoryEffect.effectStackDescription(this.af, this); - } - - @Override - public boolean canPlayAI() { - return AbilityFactoryEffect.effectCanPlayAI(getActivatingPlayer(), this.af, this); - } - - @Override - public void resolve() { - AbilityFactoryEffect.effectResolve(this.af, this); - } - - @Override - public boolean doTrigger(final boolean mandatory) { - return AbilityFactoryEffect.effectDoTriggerAI(getActivatingPlayer(), this.af, this, mandatory); - } - } - final SpellAbility abEffect = new AbilityEffect(abilityFactory.getHostCard(), abilityFactory.getAbCost(), - abilityFactory.getAbTgt()); - - return abEffect; - } - - /** - *

- * createSpellEffect. - *

- * - * @param abilityFactory - * a {@link forge.card.abilityfactory.AbilityFactory} object. - * @return a {@link forge.card.spellability.SpellAbility} object. - */ - public static SpellAbility createSpellEffect(final AbilityFactory abilityFactory) { - final SpellAbility spEffect = new Spell(abilityFactory.getHostCard(), abilityFactory.getAbCost(), - abilityFactory.getAbTgt()) { - private static final long serialVersionUID = 6631124959690157874L; - - private final AbilityFactory af = abilityFactory; - - @Override - public String getStackDescription() { - // when getStackDesc is called, just build exactly what is - // happening - return AbilityFactoryEffect.effectStackDescription(this.af, this); - } - - @Override - public boolean canPlayAI() { - return AbilityFactoryEffect.effectCanPlayAI(getActivatingPlayer(), this.af, this); - } - - @Override - public void resolve() { - AbilityFactoryEffect.effectResolve(this.af, this); - } - - }; - return spEffect; - } - - /** - *

- * createDrawbackEffect. - *

- * - * @param abilityFactory - * a {@link forge.card.abilityfactory.AbilityFactory} object. - * @return a {@link forge.card.spellability.SpellAbility} object. - */ - public static SpellAbility createDrawbackEffect(final AbilityFactory abilityFactory) { - class DrawbackEffect extends AbilitySub { - public DrawbackEffect(final Card ca, final Target t) { - super(ca, t); - } - - @Override - public AbilitySub getCopy() { - AbilitySub res = new DrawbackEffect(getSourceCard(), - getTarget() == null ? null : new Target(getTarget())); - CardFactoryUtil.copySpellAbility(this, res); - return res; - } - - private static final long serialVersionUID = 6631124959690157874L; - - private final AbilityFactory af = abilityFactory; - - @Override - public String getStackDescription() { - // when getStackDesc is called, just build exactly what is - // happening - return AbilityFactoryEffect.effectStackDescription(this.af, this); - } - - @Override - public boolean canPlayAI() { - return AbilityFactoryEffect.effectCanPlayAI(getActivatingPlayer(), this.af, this); - } - - @Override - public void resolve() { - AbilityFactoryEffect.effectResolve(this.af, this); - } - - @Override - public boolean chkAIDrawback() { - return true; - } - - @Override - public boolean doTrigger(final boolean mandatory) { - return AbilityFactoryEffect.effectDoTriggerAI(getActivatingPlayer(), this.af, this, mandatory); - } - } - final SpellAbility dbEffect = new DrawbackEffect(abilityFactory.getHostCard(), abilityFactory.getAbTgt()); - - return dbEffect; - } - - /** - *

- * effectStackDescription. - *

- * - * @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. - */ - public static String effectStackDescription(final AbilityFactory af, final SpellAbility sa) { - final StringBuilder sb = new StringBuilder(); - - if (sa instanceof AbilitySub) { - sb.append(" "); - } else { - sb.append(sa.getSourceCard().getName()).append(" - "); - } - - sb.append(sa.getDescription()); - - final AbilitySub abSub = sa.getSubAbility(); - if (abSub != null) { - sb.append(abSub.getStackDescription()); - } - - return sb.toString(); - } - - /** - *

- * effectCanPlayAI. - *

- * - * @param af - * a {@link forge.card.abilityfactory.AbilityFactory} object. - * @param sa - * a {@link forge.card.spellability.SpellAbility} object. - * @return a boolean. - */ - public static boolean effectCanPlayAI(final Player ai, final AbilityFactory af, final SpellAbility sa) { - final GameState game = Singletons.getModel().getGame(); - final Random r = MyRandom.getRandom(); - final HashMap params = af.getMapParams(); - boolean randomReturn = r.nextFloat() <= .6667; - final Player opp = ai.getOpponent(); - String logic = ""; - - if (params.containsKey("AILogic")) { - logic = params.get("AILogic"); - final PhaseHandler phase = game.getPhaseHandler(); - if (logic.equals("BeginningOfOppTurn")) { - if (phase.isPlayerTurn(ai.getOpponent()) || phase.getPhase().isAfter(PhaseType.DRAW)) { - return false; - } - randomReturn = true; - } else if (logic.equals("Fog")) { - if (game.getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer())) { - return false; - } - if (!game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { - return false; - } - if (game.getStack().size() != 0) { - return false; - } - if (game.getPhaseHandler().isPreventCombatDamageThisTurn()) { - return false; - } - if (!CombatUtil.lifeInDanger(ai, game.getCombat())) { - return false; - } - final Target tgt = sa.getTarget(); - if (tgt != null) { - tgt.resetTargets(); - List list = game.getCombat().getAttackerList(); - list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard()); - list = CardLists.getTargetableCards(list, sa); - Card target = CardFactoryUtil.getBestCreatureAI(list); - if (target == null) { - return false; - } - tgt.addTarget(target); - } - randomReturn = true; - } else if (logic.equals("Always")) { - randomReturn = true; - } else if (logic.equals("Evasion")) { - List comp = ai.getCreaturesInPlay(); - List human = opp.getCreaturesInPlay(); - - // only count creatures that can attack or block - comp = CardLists.filter(comp, new Predicate() { - @Override - public boolean apply(final Card c) { - return CombatUtil.canAttack(c, opp); - } - }); - human = CardLists.filter(human, new Predicate() { - @Override - public boolean apply(final Card c) { - return CombatUtil.canBlock(c); - } - }); - if (comp.size() < 2 || human.size() < 1) { - randomReturn = false; - } - } - } else { //no AILogic - return false; - } - - final String stackable = params.get("Stackable"); - - if ((stackable != null) && stackable.equals("False")) { - String name = params.get("Name"); - if (name == null) { - name = sa.getSourceCard().getName() + "'s Effect"; - } - final List list = sa.getActivatingPlayer().getCardsIn(ZoneType.Battlefield, name); - if (list.size() != 0) { - return false; - } - } - - final Target tgt = sa.getTarget(); - if (tgt != null && tgt.canTgtPlayer()) { - tgt.resetTargets(); - if (tgt.canOnlyTgtOpponent() || logic.equals("BeginningOfOppTurn")) { - tgt.addTarget(ai.getOpponent()); - } else { - tgt.addTarget(ai); - } - } - - final AbilitySub subAb = sa.getSubAbility(); - if (subAb != null) { - randomReturn &= subAb.chkAIDrawback(); - } - - return randomReturn; - } - - /** - *

- * effectDoTriggerAI. - *

- * - * @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. - */ - public static boolean effectDoTriggerAI(final Player ai, final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { - if (!ComputerUtil.canPayCost(sa, ai) && !mandatory) { - // payment it's usually - // not mandatory - return false; - } - - // TODO: Add targeting effects - - // check SubAbilities DoTrigger? - final AbilitySub abSub = sa.getSubAbility(); - if (abSub != null) { - return abSub.doTrigger(mandatory); - } - - return true; - } - - /** - *

- * effectResolve. - *

- * - * @param af - * a {@link forge.card.abilityfactory.AbilityFactory} object. - * @param sa - * a {@link forge.card.spellability.SpellAbility} object. - */ - public static void effectResolve(final AbilityFactory af, final SpellAbility sa) { - final HashMap params = af.getMapParams(); - final Card card = af.getHostCard(); - - String[] effectAbilities = null; - String[] effectTriggers = null; - String[] effectSVars = null; - String[] effectKeywords = null; - String[] effectStaticAbilities = null; - String[] effectReplacementEffects = null; - String effectRemembered = null; - String effectImprinted = null; - Player ownerEff = null; - - if (params.containsKey("Abilities")) { - effectAbilities = params.get("Abilities").split(","); - } - - if (params.containsKey("Triggers")) { - effectTriggers = params.get("Triggers").split(","); - } - - if (params.containsKey("StaticAbilities")) { - effectStaticAbilities = params.get("StaticAbilities").split(","); - } - - if (params.containsKey("ReplacementEffects")) { - effectReplacementEffects = params.get("ReplacementEffects").split(","); - } - - if (params.containsKey("SVars")) { - effectSVars = params.get("SVars").split(","); - } - - if (params.containsKey("Keywords")) { - effectKeywords = params.get("Keywords").split(","); - } - - if (params.containsKey("RememberObjects")) { - effectRemembered = params.get("RememberObjects"); - } - - if (params.containsKey("ImprintCards")) { - effectImprinted = params.get("ImprintCards"); - } - - // Effect eff = new Effect(); - String name = params.get("Name"); - if (name == null) { - name = sa.getSourceCard().getName() + "'s Effect"; - } - - // Unique Effects shouldn't be duplicated - if (params.containsKey("Unique") && Singletons.getModel().getGame().isCardInPlay(name)) { - return; - } - - if (params.containsKey("EffectOwner")) { - ArrayList effectOwner; - effectOwner = AbilityFactory.getDefinedPlayers(sa.getSourceCard(), params.get("EffectOwner"), sa); - ownerEff = effectOwner.get(0); - } - - final Player controller = params.containsKey("EffectOwner") ? ownerEff : sa.getActivatingPlayer(); - final Card eff = new Card(); - eff.setName(name); - eff.addType("Effect"); // Or Emblem - eff.setToken(true); // Set token to true, so when leaving play it gets - // nuked - eff.addController(controller); - eff.setOwner(controller); - eff.setImageName(card.getImageName()); - eff.setColor(card.getColor()); - eff.setImmutable(true); - eff.setEffectSource(card); - if (params.containsKey("Image")) { - eff.setImageName(params.get("Image")); - } - - // Effects should be Orange or something probably - - final Card e = eff; - - // Abilities, triggers and SVars work the same as they do for Token - // Grant abilities - if (effectAbilities != null) { - for (final String s : effectAbilities) { - final AbilityFactory abFactory = new AbilityFactory(); - final String actualAbility = af.getHostCard().getSVar(s); - - final SpellAbility grantedAbility = abFactory.getAbility(actualAbility, eff); - eff.addSpellAbility(grantedAbility); - } - } - - // Grant triggers - if (effectTriggers != null) { - for (final String s : effectTriggers) { - final String actualTrigger = af.getHostCard().getSVar(s); - - final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, eff, true); - eff.addTrigger(parsedTrigger); - } - } - - // Grant static abilities - if (effectStaticAbilities != null) { - for (final String s : effectStaticAbilities) { - eff.addStaticAbility(af.getHostCard().getSVar(s)); - } - } - - // Grant replacement effects - if (effectReplacementEffects != null) { - for (final String s : effectReplacementEffects) { - final String actualReplacement = af.getHostCard().getSVar(s); - - final ReplacementEffect parsedReplacement = ReplacementHandler.parseReplacement(actualReplacement, eff); - eff.addReplacementEffect(parsedReplacement); - } - } - - // Grant SVars - if (effectSVars != null) { - for (final String s : effectSVars) { - final String actualSVar = af.getHostCard().getSVar(s); - eff.setSVar(s, actualSVar); - } - } - - // Grant Keywords - if (effectKeywords != null) { - for (final String s : effectKeywords) { - final String actualKeyword = af.getHostCard().getSVar(s); - eff.addIntrinsicKeyword(actualKeyword); - } - } - - // Set Remembered - if (effectRemembered != null) { - for (final Object o : AbilityFactory.getDefinedObjects(card, effectRemembered, sa)) { - eff.addRemembered(o); - } - } - - // Set Imprinted - if (effectImprinted != null) { - for (final Card c : AbilityFactory.getDefinedCards(card, effectImprinted, sa)) { - eff.addImprinted(c); - } - } - - // Set Chosen Color(s) - if (!card.getChosenColor().isEmpty()) { - eff.setChosenColor(card.getChosenColor()); - } - - // Remember created effect - if (params.containsKey("RememberEffect")) { - Singletons.getModel().getGame().getCardState(card).addRemembered(eff); - } - - // Duration - final String duration = params.get("Duration"); - if ((duration == null) || !duration.equals("Permanent")) { - final Command endEffect = new Command() { - private static final long serialVersionUID = -5861759814760561373L; - - @Override - public void execute() { - Singletons.getModel().getGame().getAction().exile(e); - } - }; - - if ((duration == null) || duration.equals("EndOfTurn")) { - Singletons.getModel().getGame().getEndOfTurn().addUntil(endEffect); - } - else if (duration.equals("UntilHostLeavesPlay")) { - card.addLeavesPlayCommand(endEffect); - } - else if (duration.equals("HostLeavesOrEOT")) { - Singletons.getModel().getGame().getEndOfTurn().addUntil(endEffect); - card.addLeavesPlayCommand(endEffect); - } - else if (duration.equals("UntilYourNextTurn")) { - Singletons.getModel().getGame().getCleanup().addUntilYourNextTurn(controller, endEffect); - } - } - - // TODO: Add targeting to the effect so it knows who it's dealing with - Singletons.getModel().getGame().getTriggerHandler().suppressMode(TriggerType.ChangesZone); - Singletons.getModel().getGame().getAction().moveToPlay(eff); - Singletons.getModel().getGame().getTriggerHandler().clearSuppression(TriggerType.ChangesZone); - } - -} // end class AbilityFactoryEffect diff --git a/src/main/java/forge/card/abilityfactory/ai/EffectAi.java b/src/main/java/forge/card/abilityfactory/ai/EffectAi.java new file mode 100644 index 00000000000..cc488a6da8f --- /dev/null +++ b/src/main/java/forge/card/abilityfactory/ai/EffectAi.java @@ -0,0 +1,164 @@ +package forge.card.abilityfactory.ai; + +import java.util.List; +import java.util.Random; + +import com.google.common.base.Predicate; + +import forge.Card; +import forge.CardLists; +import forge.Singletons; +import forge.card.abilityfactory.SpellAiLogic; +import forge.card.cardfactory.CardFactoryUtil; +import forge.card.spellability.AbilitySub; +import forge.card.spellability.SpellAbility; +import forge.card.spellability.Target; +import forge.game.GameState; +import forge.game.phase.CombatUtil; +import forge.game.phase.PhaseHandler; +import forge.game.phase.PhaseType; +import forge.game.player.Player; +import forge.game.zone.ZoneType; +import forge.util.MyRandom; + +public class EffectAi extends SpellAiLogic { + /** + *

+ * effectCanPlayAI. + *

+ * + * @param af + * a {@link forge.card.abilityfactory.AbilityFactory} object. + * @param sa + * a {@link forge.card.spellability.SpellAbility} object. + * @return a boolean. + */ + @Override + public boolean canPlayAI(Player ai, java.util.Map params, SpellAbility sa) { + final GameState game = Singletons.getModel().getGame(); + final Random r = MyRandom.getRandom(); + boolean randomReturn = r.nextFloat() <= .6667; + final Player opp = ai.getOpponent(); + String logic = ""; + + if (params.containsKey("AILogic")) { + logic = params.get("AILogic"); + final PhaseHandler phase = game.getPhaseHandler(); + if (logic.equals("BeginningOfOppTurn")) { + if (phase.isPlayerTurn(ai.getOpponent()) || phase.getPhase().isAfter(PhaseType.DRAW)) { + return false; + } + randomReturn = true; + } else if (logic.equals("Fog")) { + if (game.getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer())) { + return false; + } + if (!game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { + return false; + } + if (game.getStack().size() != 0) { + return false; + } + if (game.getPhaseHandler().isPreventCombatDamageThisTurn()) { + return false; + } + if (!CombatUtil.lifeInDanger(ai, game.getCombat())) { + return false; + } + final Target tgt = sa.getTarget(); + if (tgt != null) { + tgt.resetTargets(); + List list = game.getCombat().getAttackerList(); + list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard()); + list = CardLists.getTargetableCards(list, sa); + Card target = CardFactoryUtil.getBestCreatureAI(list); + if (target == null) { + return false; + } + tgt.addTarget(target); + } + randomReturn = true; + } else if (logic.equals("Always")) { + randomReturn = true; + } else if (logic.equals("Evasion")) { + List comp = ai.getCreaturesInPlay(); + List human = opp.getCreaturesInPlay(); + + // only count creatures that can attack or block + comp = CardLists.filter(comp, new Predicate() { + @Override + public boolean apply(final Card c) { + return CombatUtil.canAttack(c, opp); + } + }); + human = CardLists.filter(human, new Predicate() { + @Override + public boolean apply(final Card c) { + return CombatUtil.canBlock(c); + } + }); + if (comp.size() < 2 || human.size() < 1) { + randomReturn = false; + } + } + } else { //no AILogic + return false; + } + + final String stackable = params.get("Stackable"); + + if ((stackable != null) && stackable.equals("False")) { + String name = params.get("Name"); + if (name == null) { + name = sa.getSourceCard().getName() + "'s Effect"; + } + final List list = sa.getActivatingPlayer().getCardsIn(ZoneType.Battlefield, name); + if (list.size() != 0) { + return false; + } + } + + final Target tgt = sa.getTarget(); + if (tgt != null && tgt.canTgtPlayer()) { + tgt.resetTargets(); + if (tgt.canOnlyTgtOpponent() || logic.equals("BeginningOfOppTurn")) { + tgt.addTarget(ai.getOpponent()); + } else { + tgt.addTarget(ai); + } + } + + final AbilitySub subAb = sa.getSubAbility(); + if (subAb != null) { + randomReturn &= subAb.chkAIDrawback(); + } + + return randomReturn; + } + + /** + *

+ * effectDoTriggerAI. + *

+ * + * @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. + */ + @Override + public boolean doTriggerAINoCost(Player aiPlayer, java.util.Map params, SpellAbility sa, boolean mandatory) { + // TODO: Add targeting effects + + // check SubAbilities DoTrigger? + final AbilitySub abSub = sa.getSubAbility(); + if (abSub != null) { + return abSub.doTrigger(mandatory); + } + + return true; + } +} \ No newline at end of file diff --git a/src/main/java/forge/card/abilityfactory/effects/EffectEffect.java b/src/main/java/forge/card/abilityfactory/effects/EffectEffect.java new file mode 100644 index 00000000000..e4d1dcb350f --- /dev/null +++ b/src/main/java/forge/card/abilityfactory/effects/EffectEffect.java @@ -0,0 +1,258 @@ +package forge.card.abilityfactory.effects; + +import java.util.ArrayList; + +import forge.Card; +import forge.Command; +import forge.Singletons; +import forge.card.abilityfactory.AbilityFactory; +import forge.card.abilityfactory.SpellEffect; +import forge.card.replacement.ReplacementEffect; +import forge.card.replacement.ReplacementHandler; +import forge.card.spellability.AbilitySub; +import forge.card.spellability.SpellAbility; +import forge.card.trigger.Trigger; +import forge.card.trigger.TriggerHandler; +import forge.card.trigger.TriggerType; +import forge.game.player.Player; + +public class EffectEffect extends SpellEffect { + + /** + *

+ * effectStackDescription. + *

+ * + * @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. + */ + @Override + public String getStackDescription(java.util.Map params, SpellAbility sa) { + final StringBuilder sb = new StringBuilder(); + + if (sa instanceof AbilitySub) { + sb.append(" "); + } else { + sb.append(sa.getSourceCard().getName()).append(" - "); + } + + sb.append(sa.getDescription()); + + final AbilitySub abSub = sa.getSubAbility(); + if (abSub != null) { + sb.append(abSub.getStackDescription()); + } + + return sb.toString(); + } + + /** + *

+ * effectResolve. + *

+ * + * @param af + * a {@link forge.card.abilityfactory.AbilityFactory} object. + * @param sa + * a {@link forge.card.spellability.SpellAbility} object. + */ + + @Override + public void resolve(java.util.Map params, SpellAbility sa) { + final Card hostCard = sa.getAbilityFactory().getHostCard(); + + String[] effectAbilities = null; + String[] effectTriggers = null; + String[] effectSVars = null; + String[] effectKeywords = null; + String[] effectStaticAbilities = null; + String[] effectReplacementEffects = null; + String effectRemembered = null; + String effectImprinted = null; + Player ownerEff = null; + + if (params.containsKey("Abilities")) { + effectAbilities = params.get("Abilities").split(","); + } + + if (params.containsKey("Triggers")) { + effectTriggers = params.get("Triggers").split(","); + } + + if (params.containsKey("StaticAbilities")) { + effectStaticAbilities = params.get("StaticAbilities").split(","); + } + + if (params.containsKey("ReplacementEffects")) { + effectReplacementEffects = params.get("ReplacementEffects").split(","); + } + + if (params.containsKey("SVars")) { + effectSVars = params.get("SVars").split(","); + } + + if (params.containsKey("Keywords")) { + effectKeywords = params.get("Keywords").split(","); + } + + if (params.containsKey("RememberObjects")) { + effectRemembered = params.get("RememberObjects"); + } + + if (params.containsKey("ImprintCards")) { + effectImprinted = params.get("ImprintCards"); + } + + // Effect eff = new Effect(); + String name = params.get("Name"); + if (name == null) { + name = sa.getSourceCard().getName() + "'s Effect"; + } + + // Unique Effects shouldn't be duplicated + if (params.containsKey("Unique") && Singletons.getModel().getGame().isCardInPlay(name)) { + return; + } + + if (params.containsKey("EffectOwner")) { + ArrayList effectOwner; + effectOwner = AbilityFactory.getDefinedPlayers(sa.getSourceCard(), params.get("EffectOwner"), sa); + ownerEff = effectOwner.get(0); + } + + final Player controller = params.containsKey("EffectOwner") ? ownerEff : sa.getActivatingPlayer(); + final Card eff = new Card(); + eff.setName(name); + eff.addType("Effect"); // Or Emblem + eff.setToken(true); // Set token to true, so when leaving play it gets + // nuked + eff.addController(controller); + eff.setOwner(controller); + eff.setImageName(hostCard.getImageName()); + eff.setColor(hostCard.getColor()); + eff.setImmutable(true); + eff.setEffectSource(hostCard); + if (params.containsKey("Image")) { + eff.setImageName(params.get("Image")); + } + + // Effects should be Orange or something probably + + final Card e = eff; + + // Abilities, triggers and SVars work the same as they do for Token + // Grant abilities + if (effectAbilities != null) { + for (final String s : effectAbilities) { + final AbilityFactory abFactory = new AbilityFactory(); + final String actualAbility = hostCard.getSVar(s); + + final SpellAbility grantedAbility = abFactory.getAbility(actualAbility, eff); + eff.addSpellAbility(grantedAbility); + } + } + + // Grant triggers + if (effectTriggers != null) { + for (final String s : effectTriggers) { + final String actualTrigger = hostCard.getSVar(s); + + final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, eff, true); + eff.addTrigger(parsedTrigger); + } + } + + // Grant static abilities + if (effectStaticAbilities != null) { + for (final String s : effectStaticAbilities) { + eff.addStaticAbility(hostCard.getSVar(s)); + } + } + + // Grant replacement effects + if (effectReplacementEffects != null) { + for (final String s : effectReplacementEffects) { + final String actualReplacement = hostCard.getSVar(s); + + final ReplacementEffect parsedReplacement = ReplacementHandler.parseReplacement(actualReplacement, eff); + eff.addReplacementEffect(parsedReplacement); + } + } + + // Grant SVars + if (effectSVars != null) { + for (final String s : effectSVars) { + final String actualSVar = hostCard.getSVar(s); + eff.setSVar(s, actualSVar); + } + } + + // Grant Keywords + if (effectKeywords != null) { + for (final String s : effectKeywords) { + final String actualKeyword = hostCard.getSVar(s); + eff.addIntrinsicKeyword(actualKeyword); + } + } + + // Set Remembered + if (effectRemembered != null) { + for (final Object o : AbilityFactory.getDefinedObjects(hostCard, effectRemembered, sa)) { + eff.addRemembered(o); + } + } + + // Set Imprinted + if (effectImprinted != null) { + for (final Card c : AbilityFactory.getDefinedCards(hostCard, effectImprinted, sa)) { + eff.addImprinted(c); + } + } + + // Set Chosen Color(s) + if (!hostCard.getChosenColor().isEmpty()) { + eff.setChosenColor(hostCard.getChosenColor()); + } + + // Remember created effect + if (params.containsKey("RememberEffect")) { + Singletons.getModel().getGame().getCardState(hostCard).addRemembered(eff); + } + + // Duration + final String duration = params.get("Duration"); + if ((duration == null) || !duration.equals("Permanent")) { + final Command endEffect = new Command() { + private static final long serialVersionUID = -5861759814760561373L; + + @Override + public void execute() { + Singletons.getModel().getGame().getAction().exile(e); + } + }; + + if ((duration == null) || duration.equals("EndOfTurn")) { + Singletons.getModel().getGame().getEndOfTurn().addUntil(endEffect); + } + else if (duration.equals("UntilHostLeavesPlay")) { + hostCard.addLeavesPlayCommand(endEffect); + } + else if (duration.equals("HostLeavesOrEOT")) { + Singletons.getModel().getGame().getEndOfTurn().addUntil(endEffect); + hostCard.addLeavesPlayCommand(endEffect); + } + else if (duration.equals("UntilYourNextTurn")) { + Singletons.getModel().getGame().getCleanup().addUntilYourNextTurn(controller, endEffect); + } + } + + // TODO: Add targeting to the effect so it knows who it's dealing with + Singletons.getModel().getGame().getTriggerHandler().suppressMode(TriggerType.ChangesZone); + Singletons.getModel().getGame().getAction().moveToPlay(eff); + Singletons.getModel().getGame().getTriggerHandler().clearSuppression(TriggerType.ChangesZone); + } + +} // end class AbilityFactoryEffect \ No newline at end of file