mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
refactor AF:Effect (wish I knew what it is)
This commit is contained in:
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -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
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* AbilityFactoryEffect class.
|
||||
* </p>
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AbilityFactoryEffect {
|
||||
/**
|
||||
* <p>
|
||||
* createAbilityEffect.
|
||||
* </p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* createSpellEffect.
|
||||
* </p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* createDrawbackEffect.
|
||||
* </p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* effectStackDescription.
|
||||
* </p>
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* effectCanPlayAI.
|
||||
* </p>
|
||||
*
|
||||
* @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<String, String> 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<Card> 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<Card> comp = ai.getCreaturesInPlay();
|
||||
List<Card> human = opp.getCreaturesInPlay();
|
||||
|
||||
// only count creatures that can attack or block
|
||||
comp = CardLists.filter(comp, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return CombatUtil.canAttack(c, opp);
|
||||
}
|
||||
});
|
||||
human = CardLists.filter(human, new Predicate<Card>() {
|
||||
@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<Card> 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* effectDoTriggerAI.
|
||||
* </p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* effectResolve.
|
||||
* </p>
|
||||
*
|
||||
* @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<String, String> 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<Player> 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
|
||||
164
src/main/java/forge/card/abilityfactory/ai/EffectAi.java
Normal file
164
src/main/java/forge/card/abilityfactory/ai/EffectAi.java
Normal file
@@ -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 {
|
||||
/**
|
||||
* <p>
|
||||
* effectCanPlayAI.
|
||||
* </p>
|
||||
*
|
||||
* @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<String,String> 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<Card> 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<Card> comp = ai.getCreaturesInPlay();
|
||||
List<Card> human = opp.getCreaturesInPlay();
|
||||
|
||||
// only count creatures that can attack or block
|
||||
comp = CardLists.filter(comp, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return CombatUtil.canAttack(c, opp);
|
||||
}
|
||||
});
|
||||
human = CardLists.filter(human, new Predicate<Card>() {
|
||||
@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<Card> 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* effectDoTriggerAI.
|
||||
* </p>
|
||||
*
|
||||
* @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<String,String> 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;
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* effectStackDescription.
|
||||
* </p>
|
||||
*
|
||||
* @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<String,String> 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* effectResolve.
|
||||
* </p>
|
||||
*
|
||||
* @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<String,String> 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<Player> 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
|
||||
Reference in New Issue
Block a user