mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
remove AI class from ApiType
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -139,6 +139,7 @@ forge-game/src/main/java/forge/ai/ComputerUtilMana.java -text
|
|||||||
forge-game/src/main/java/forge/ai/LobbyPlayerAi.java -text
|
forge-game/src/main/java/forge/ai/LobbyPlayerAi.java -text
|
||||||
forge-game/src/main/java/forge/ai/PlayerControllerAi.java -text
|
forge-game/src/main/java/forge/ai/PlayerControllerAi.java -text
|
||||||
forge-game/src/main/java/forge/ai/SpellAbilityAi.java -text
|
forge-game/src/main/java/forge/ai/SpellAbilityAi.java -text
|
||||||
|
forge-game/src/main/java/forge/ai/SpellApiToAi.java -text
|
||||||
forge-game/src/main/java/forge/ai/ability/AddPhaseAi.java -text
|
forge-game/src/main/java/forge/ai/ability/AddPhaseAi.java -text
|
||||||
forge-game/src/main/java/forge/ai/ability/AddTurnAi.java svneol=native#text/plain
|
forge-game/src/main/java/forge/ai/ability/AddTurnAi.java svneol=native#text/plain
|
||||||
forge-game/src/main/java/forge/ai/ability/AlwaysPlayAi.java -text
|
forge-game/src/main/java/forge/ai/ability/AlwaysPlayAi.java -text
|
||||||
|
|||||||
@@ -616,7 +616,7 @@ public class AiController {
|
|||||||
return canPlaySa(((WrappedAbility) sa).getWrappedAbility());
|
return canPlaySa(((WrappedAbility) sa).getWrappedAbility());
|
||||||
}
|
}
|
||||||
if( sa.getApi() != null ) {
|
if( sa.getApi() != null ) {
|
||||||
boolean canPlay = sa.getApi().getAi().canPlayAIWithSubs(player, sa);
|
boolean canPlay = SpellApiToAi.Converter.get(sa.getApi()).canPlayAIWithSubs(player, sa);
|
||||||
if(!canPlay)
|
if(!canPlay)
|
||||||
return AiPlayDecision.CantPlayAi;
|
return AiPlayDecision.CantPlayAi;
|
||||||
}
|
}
|
||||||
@@ -876,7 +876,7 @@ public class AiController {
|
|||||||
throw new IllegalArgumentException(exMsg);
|
throw new IllegalArgumentException(exMsg);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
return api.getAi().confirmAction(player, sa, mode, message);
|
return SpellApiToAi.Converter.get(api).confirmAction(player, sa, mode, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean confirmStaticApplication(Card hostCard, GameEntity affected, String logic, String message) {
|
public boolean confirmStaticApplication(Card hostCard, GameEntity affected, String logic, String message) {
|
||||||
@@ -940,9 +940,9 @@ public class AiController {
|
|||||||
{
|
{
|
||||||
boolean chance = false;
|
boolean chance = false;
|
||||||
if (withoutPayingManaCost) {
|
if (withoutPayingManaCost) {
|
||||||
chance = spell.getApi().getAi().doTriggerNoCostWithSubs(player, spell, mandatory);
|
chance = SpellApiToAi.Converter.get(spell.getApi()).doTriggerNoCostWithSubs(player, spell, mandatory);
|
||||||
} else {
|
} else {
|
||||||
chance = spell.getApi().getAi().doTriggerAI(player, spell, mandatory);
|
chance = SpellApiToAi.Converter.get(spell.getApi()).doTriggerAI(player, spell, mandatory);
|
||||||
}
|
}
|
||||||
if (!chance)
|
if (!chance)
|
||||||
return AiPlayDecision.TargetingFailed;
|
return AiPlayDecision.TargetingFailed;
|
||||||
@@ -1148,7 +1148,7 @@ public class AiController {
|
|||||||
public boolean doTrigger(SpellAbility spell, boolean mandatory) {
|
public boolean doTrigger(SpellAbility spell, boolean mandatory) {
|
||||||
|
|
||||||
if ( spell.getApi() != null )
|
if ( spell.getApi() != null )
|
||||||
return spell.getApi().getAi().doTriggerAI(player, spell, mandatory);
|
return SpellApiToAi.Converter.get(spell.getApi()).doTriggerAI(player, spell, mandatory);
|
||||||
if ( spell instanceof WrappedAbility )
|
if ( spell instanceof WrappedAbility )
|
||||||
return doTrigger(((WrappedAbility)spell).getWrappedAbility(), mandatory);
|
return doTrigger(((WrappedAbility)spell).getWrappedAbility(), mandatory);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package forge.ai;
|
|||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.ArrayListMultimap;
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.card.mana.ManaAtom;
|
import forge.card.mana.ManaAtom;
|
||||||
import forge.card.mana.ManaCost;
|
import forge.card.mana.ManaCost;
|
||||||
@@ -28,6 +29,7 @@ import forge.util.CollectionSuppliers;
|
|||||||
import forge.util.TextUtil;
|
import forge.util.TextUtil;
|
||||||
import forge.util.maps.EnumMapOfLists;
|
import forge.util.maps.EnumMapOfLists;
|
||||||
import forge.util.maps.MapOfLists;
|
import forge.util.maps.MapOfLists;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -630,7 +632,7 @@ public class ComputerUtilMana {
|
|||||||
// don't use abilities with dangerous drawbacks
|
// don't use abilities with dangerous drawbacks
|
||||||
AbilitySub sub = m.getSubAbility();
|
AbilitySub sub = m.getSubAbility();
|
||||||
if (sub != null && !card.getName().equals("Pristine Talisman") && !card.getName().equals("Zhur-Taa Druid")) {
|
if (sub != null && !card.getName().equals("Pristine Talisman") && !card.getName().equals("Zhur-Taa Druid")) {
|
||||||
if (!sub.getApi().getAi().chkDrawbackWithSubs(ai, sub)) {
|
if (!SpellApiToAi.Converter.get(sub.getApi()).chkDrawbackWithSubs(ai, sub)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
needsLimitedResources = true; // TODO: check for good drawbacks (gainLife)
|
needsLimitedResources = true; // TODO: check for good drawbacks (gainLife)
|
||||||
@@ -688,7 +690,7 @@ public class ComputerUtilMana {
|
|||||||
// don't use abilities with dangerous drawbacks
|
// don't use abilities with dangerous drawbacks
|
||||||
AbilitySub sub = m.getSubAbility();
|
AbilitySub sub = m.getSubAbility();
|
||||||
if (sub != null) {
|
if (sub != null) {
|
||||||
if (!sub.getApi().getAi().chkDrawbackWithSubs(ai, sub)) {
|
if (!SpellApiToAi.Converter.get(sub.getApi()).chkDrawbackWithSubs(ai, sub)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
if (null == api) {
|
if (null == api) {
|
||||||
throw new InvalidParameterException("SA is not api-based, this is not supported yet");
|
throw new InvalidParameterException("SA is not api-based, this is not supported yet");
|
||||||
}
|
}
|
||||||
return api.getAi().chooseSingleEntity(player, sa, options, isOptional, targetedPlayer);
|
return SpellApiToAi.Converter.get(api).chooseSingleEntity(player, sa, options, isOptional, targetedPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -143,7 +143,7 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
if (null == api) {
|
if (null == api) {
|
||||||
throw new InvalidParameterException("SA is not api-based, this is not supported yet");
|
throw new InvalidParameterException("SA is not api-based, this is not supported yet");
|
||||||
}
|
}
|
||||||
return api.getAi().chooseSingleSpellAbility(player, sa, spells);
|
return SpellApiToAi.Converter.get(api).chooseSingleSpellAbility(player, sa, spells);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package forge.ai;
|
|||||||
|
|
||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
import forge.game.GameEntity;
|
import forge.game.GameEntity;
|
||||||
import forge.game.ability.SaTargetRoutines;
|
import forge.game.ability.SaTargetRoutines;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
@@ -136,7 +137,7 @@ public abstract class SpellAbilityAi extends SaTargetRoutines {
|
|||||||
*/
|
*/
|
||||||
public boolean chkDrawbackWithSubs(Player aiPlayer, AbilitySub ab) {
|
public boolean chkDrawbackWithSubs(Player aiPlayer, AbilitySub ab) {
|
||||||
final AbilitySub subAb = ab.getSubAbility();
|
final AbilitySub subAb = ab.getSubAbility();
|
||||||
return ab.getApi().getAi().chkAIDrawback(ab, aiPlayer) && (subAb == null || chkDrawbackWithSubs(aiPlayer, subAb));
|
return SpellApiToAi.Converter.get(ab.getApi()).chkAIDrawback(ab, aiPlayer) && (subAb == null || chkDrawbackWithSubs(aiPlayer, subAb));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
||||||
|
|||||||
122
forge-game/src/main/java/forge/ai/SpellApiToAi.java
Normal file
122
forge-game/src/main/java/forge/ai/SpellApiToAi.java
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
package forge.ai;
|
||||||
|
|
||||||
|
import java.util.EnumMap;
|
||||||
|
|
||||||
|
import forge.ai.ability.*;
|
||||||
|
import forge.game.ability.ApiType;
|
||||||
|
import forge.util.ReflectionUtil;
|
||||||
|
|
||||||
|
public enum SpellApiToAi {
|
||||||
|
Converter;
|
||||||
|
|
||||||
|
private final static EnumMap<ApiType, Class<? extends SpellAbilityAi>> apiToClass = new EnumMap<>(ApiType.class);
|
||||||
|
private final EnumMap<ApiType, SpellAbilityAi> apiToInstance = new EnumMap<>(ApiType.class);
|
||||||
|
|
||||||
|
static {
|
||||||
|
apiToClass.put(ApiType.DamageAll, DamageAllAi.class);
|
||||||
|
apiToClass.put(ApiType.DealDamage, DamageDealAi.class);
|
||||||
|
apiToClass.put(ApiType.Debuff, DebuffAi.class);
|
||||||
|
apiToClass.put(ApiType.DebuffAll, DebuffAllAi.class);
|
||||||
|
apiToClass.put(ApiType.DeclareCombatants, CannotPlayAi.class);
|
||||||
|
apiToClass.put(ApiType.DelayedTrigger, DelayedTriggerAi.class);
|
||||||
|
apiToClass.put(ApiType.Destroy, DestroyAi.class);
|
||||||
|
apiToClass.put(ApiType.DestroyAll, DestroyAllAi.class);
|
||||||
|
apiToClass.put(ApiType.Dig, DigAi.class);
|
||||||
|
apiToClass.put(ApiType.DigUntil, DigUntilAi.class);
|
||||||
|
apiToClass.put(ApiType.Discard, DiscardAi.class);
|
||||||
|
apiToClass.put(ApiType.DrainMana, DrainManaAi.class);
|
||||||
|
apiToClass.put(ApiType.Draw, DrawAi.class);
|
||||||
|
apiToClass.put(ApiType.EachDamage, DamageEachAi.class);
|
||||||
|
apiToClass.put(ApiType.Effect, EffectAi.class);
|
||||||
|
apiToClass.put(ApiType.Encode, EncodeAi.class);
|
||||||
|
apiToClass.put(ApiType.EndTurn, EndTurnAi.class);
|
||||||
|
apiToClass.put(ApiType.ExchangeLife, LifeExchangeAi.class);
|
||||||
|
apiToClass.put(ApiType.ExchangeControl, ControlExchangeAi.class);
|
||||||
|
apiToClass.put(ApiType.ExchangePower, PowerExchangeAi.class);
|
||||||
|
apiToClass.put(ApiType.ExchangeZone, ZoneExchangeAi.class);
|
||||||
|
apiToClass.put(ApiType.Fight, FightAi.class);
|
||||||
|
apiToClass.put(ApiType.FlipACoin, FlipACoinAi.class);
|
||||||
|
apiToClass.put(ApiType.Fog, FogAi.class);
|
||||||
|
apiToClass.put(ApiType.GainControl, ControlGainAi.class);
|
||||||
|
apiToClass.put(ApiType.GainLife, LifeGainAi.class);
|
||||||
|
apiToClass.put(ApiType.GainOwnership, CannotPlayAi.class);
|
||||||
|
apiToClass.put(ApiType.GenericChoice, ChooseGenericEffectAi.class);
|
||||||
|
apiToClass.put(ApiType.LoseLife, LifeLoseAi.class);
|
||||||
|
apiToClass.put(ApiType.LosesGame, GameLossAi.class);
|
||||||
|
apiToClass.put(ApiType.Mana, ManaEffectAi.class);
|
||||||
|
apiToClass.put(ApiType.ManaReflected, CannotPlayAi.class);
|
||||||
|
apiToClass.put(ApiType.Mill, MillAi.class);
|
||||||
|
apiToClass.put(ApiType.MoveCounter, CountersMoveAi.class);
|
||||||
|
apiToClass.put(ApiType.MultiplePiles, CannotPlayAi.class);
|
||||||
|
apiToClass.put(ApiType.MustAttack, MustAttackAi.class);
|
||||||
|
apiToClass.put(ApiType.MustBlock, MustBlockAi.class);
|
||||||
|
apiToClass.put(ApiType.NameCard, ChooseCardNameAi.class);
|
||||||
|
apiToClass.put(ApiType.PeekAndReveal, PeekAndRevealAi.class);
|
||||||
|
apiToClass.put(ApiType.PermanentCreature, PermanentCreatureAi.class);
|
||||||
|
apiToClass.put(ApiType.PermanentNoncreature, PermanentNoncreatureAi.class);
|
||||||
|
apiToClass.put(ApiType.Phases, PhasesAi.class);
|
||||||
|
apiToClass.put(ApiType.Planeswalk, AlwaysPlayAi.class);
|
||||||
|
apiToClass.put(ApiType.Play, PlayAi.class);
|
||||||
|
apiToClass.put(ApiType.Poison, PoisonAi.class);
|
||||||
|
apiToClass.put(ApiType.PreventDamage, DamagePreventAi.class);
|
||||||
|
apiToClass.put(ApiType.PreventDamageAll, DamagePreventAllAi.class);
|
||||||
|
apiToClass.put(ApiType.Proliferate, CountersProliferateAi.class);
|
||||||
|
apiToClass.put(ApiType.Protection, ProtectAi.class);
|
||||||
|
apiToClass.put(ApiType.ProtectionAll, ProtectAllAi.class);
|
||||||
|
apiToClass.put(ApiType.Pump, PumpAi.class);
|
||||||
|
apiToClass.put(ApiType.PumpAll, PumpAllAi.class);
|
||||||
|
apiToClass.put(ApiType.PutCounter, CountersPutAi.class);
|
||||||
|
apiToClass.put(ApiType.PutCounterAll, CountersPutAllAi.class);
|
||||||
|
apiToClass.put(ApiType.RearrangeTopOfLibrary, RearrangeTopOfLibraryAi.class);
|
||||||
|
apiToClass.put(ApiType.Regenerate, RegenerateAi.class);
|
||||||
|
apiToClass.put(ApiType.RegenerateAll, RegenerateAllAi.class);
|
||||||
|
apiToClass.put(ApiType.RemoveCounter, CountersRemoveAi.class);
|
||||||
|
apiToClass.put(ApiType.RemoveCounterAll, CannotPlayAi.class);
|
||||||
|
apiToClass.put(ApiType.RemoveFromCombat, RemoveFromCombatAi.class);
|
||||||
|
apiToClass.put(ApiType.ReorderZone, AlwaysPlayAi.class);
|
||||||
|
apiToClass.put(ApiType.Repeat, RepeatAi.class);
|
||||||
|
apiToClass.put(ApiType.RepeatEach, RepeatEachAi.class);
|
||||||
|
apiToClass.put(ApiType.RestartGame, RestartGameAi.class);
|
||||||
|
apiToClass.put(ApiType.Reveal, RevealAi.class);
|
||||||
|
apiToClass.put(ApiType.RevealHand, RevealHandAi.class);
|
||||||
|
apiToClass.put(ApiType.RollPlanarDice, RollPlanarDiceAi.class);
|
||||||
|
apiToClass.put(ApiType.RunSVarAbility, AlwaysPlayAi.class);
|
||||||
|
apiToClass.put(ApiType.Sacrifice, SacrificeAi.class);
|
||||||
|
apiToClass.put(ApiType.SacrificeAll, SacrificeAllAi.class);
|
||||||
|
apiToClass.put(ApiType.Scry, ScryAi.class);
|
||||||
|
apiToClass.put(ApiType.SetInMotion, AlwaysPlayAi.class);
|
||||||
|
apiToClass.put(ApiType.SetLife, LifeSetAi.class);
|
||||||
|
apiToClass.put(ApiType.SetState, SetStateAi.class);
|
||||||
|
apiToClass.put(ApiType.Shuffle, ShuffleAi.class);
|
||||||
|
apiToClass.put(ApiType.SkipTurn, CannotPlayAi.class);
|
||||||
|
apiToClass.put(ApiType.StoreSVar, StoreSVarAi.class);
|
||||||
|
apiToClass.put(ApiType.Tap, TapAi.class);
|
||||||
|
apiToClass.put(ApiType.TapAll, TapAllAi.class);
|
||||||
|
apiToClass.put(ApiType.TapOrUntap, TapOrUntapAi.class);
|
||||||
|
apiToClass.put(ApiType.TapOrUntapAll, TapOrUntapAllAi.class);
|
||||||
|
apiToClass.put(ApiType.Token, TokenAi.class);
|
||||||
|
apiToClass.put(ApiType.TwoPiles, TwoPilesAi.class);
|
||||||
|
apiToClass.put(ApiType.UnattachAll, UnattachAllAi.class);
|
||||||
|
apiToClass.put(ApiType.Untap, UntapAi.class);
|
||||||
|
apiToClass.put(ApiType.UntapAll, UntapAllAi.class);
|
||||||
|
apiToClass.put(ApiType.WinsGame, GameWinAi.class);
|
||||||
|
|
||||||
|
apiToClass.put(ApiType.InternalEtbReplacement, CanPlayAsDrawbackAi.class);
|
||||||
|
apiToClass.put(ApiType.InternalLegendaryRule, LegendaryRuleAi.class);
|
||||||
|
apiToClass.put(ApiType.InternalHaunt, HauntAi.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpellAbilityAi get(ApiType api) {
|
||||||
|
SpellAbilityAi result = apiToInstance.get(api);
|
||||||
|
if( null == result ) {
|
||||||
|
Class<? extends SpellAbilityAi> clz = apiToClass.get(api);
|
||||||
|
if(null == clz) {
|
||||||
|
System.err.println("No AI assigned for API: " + api);
|
||||||
|
clz = CannotPlayAi.class;
|
||||||
|
}
|
||||||
|
result = ReflectionUtil.makeDefaultInstanceOf(clz);
|
||||||
|
apiToInstance.put(api, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import com.google.common.base.Predicate;
|
|||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import forge.ai.*;
|
import forge.ai.*;
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
@@ -307,7 +308,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final AbilitySub subAb = sa.getSubAbility();
|
final AbilitySub subAb = sa.getSubAbility();
|
||||||
return subAb == null || subAb.getApi().getAi().chkDrawbackWithSubs(ai, subAb);
|
return subAb == null || SpellApiToAi.Converter.get(subAb.getApi()).chkDrawbackWithSubs(ai, subAb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -645,7 +646,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final AbilitySub subAb = sa.getSubAbility();
|
final AbilitySub subAb = sa.getSubAbility();
|
||||||
chance &= subAb == null || subAb.getApi().getAi().chkDrawbackWithSubs(ai, subAb);
|
chance &= subAb == null || SpellApiToAi.Converter.get(subAb.getApi()).chkDrawbackWithSubs(ai, subAb);
|
||||||
|
|
||||||
return chance;
|
return chance;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import forge.ai.AiController;
|
|||||||
import forge.ai.AiPlayDecision;
|
import forge.ai.AiPlayDecision;
|
||||||
import forge.ai.PlayerControllerAi;
|
import forge.ai.PlayerControllerAi;
|
||||||
import forge.ai.SpellAbilityAi;
|
import forge.ai.SpellAbilityAi;
|
||||||
|
import forge.ai.SpellApiToAi;
|
||||||
import forge.game.ability.AbilityFactory;
|
import forge.game.ability.AbilityFactory;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.AbilitySub;
|
import forge.game.spellability.AbilitySub;
|
||||||
@@ -18,7 +19,7 @@ public class DelayedTriggerAi extends SpellAbilityAi {
|
|||||||
trigsa.setActivatingPlayer(ai);
|
trigsa.setActivatingPlayer(ai);
|
||||||
|
|
||||||
if (trigsa instanceof AbilitySub) {
|
if (trigsa instanceof AbilitySub) {
|
||||||
return ((AbilitySub) trigsa).getApi().getAi().chkDrawbackWithSubs(ai, (AbilitySub)trigsa);
|
return SpellApiToAi.Converter.get(((AbilitySub) trigsa).getApi()).chkDrawbackWithSubs(ai, (AbilitySub)trigsa);
|
||||||
} else {
|
} else {
|
||||||
return AiPlayDecision.WillPlay == ((PlayerControllerAi)ai.getController()).getAi().canPlaySa(trigsa);
|
return AiPlayDecision.WillPlay == ((PlayerControllerAi)ai.getController()).getAi().canPlaySa(trigsa);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package forge.ai.ability;
|
package forge.ai.ability;
|
||||||
|
|
||||||
import forge.ai.SpellAbilityAi;
|
import forge.ai.SpellAbilityAi;
|
||||||
|
import forge.ai.SpellApiToAi;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.player.PlayerActionConfirmMode;
|
import forge.game.player.PlayerActionConfirmMode;
|
||||||
import forge.game.spellability.AbilityStatic;
|
import forge.game.spellability.AbilityStatic;
|
||||||
@@ -32,7 +33,7 @@ public class PeekAndRevealAi extends SpellAbilityAi {
|
|||||||
@Override
|
@Override
|
||||||
public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
||||||
AbilitySub subAb = sa.getSubAbility();
|
AbilitySub subAb = sa.getSubAbility();
|
||||||
return subAb != null && subAb.getApi().getAi().chkDrawbackWithSubs(player, subAb);
|
return subAb != null && SpellApiToAi.Converter.get(subAb.getApi()).chkDrawbackWithSubs(player, subAb);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package forge.game.ability;
|
package forge.game.ability;
|
||||||
|
|
||||||
|
|
||||||
import forge.ai.SpellAbilityAi;
|
|
||||||
import forge.ai.ability.*;
|
|
||||||
import forge.game.ability.effects.*;
|
import forge.game.ability.effects.*;
|
||||||
import forge.util.ReflectionUtil;
|
import forge.util.ReflectionUtil;
|
||||||
|
|
||||||
@@ -14,156 +12,144 @@ import java.util.TreeMap;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public enum ApiType {
|
public enum ApiType {
|
||||||
|
Abandon (AbandonEffect.class),
|
||||||
|
AddOrRemoveCounter (CountersPutOrRemoveEffect.class),
|
||||||
|
AddPhase (AddPhaseEffect.class),
|
||||||
|
AddTurn (AddTurnEffect.class),
|
||||||
|
Animate (AnimateEffect.class),
|
||||||
|
AnimateAll (AnimateAllEffect.class),
|
||||||
|
Attach (AttachEffect.class),
|
||||||
|
Balance (BalanceEffect.class),
|
||||||
|
BecomesBlocked (BecomesBlockedEffect.class),
|
||||||
|
Bond (BondEffect.class),
|
||||||
|
ChangeTargets (ChangeTargetsEffect.class),
|
||||||
|
ChangeZone (ChangeZoneEffect.class),
|
||||||
|
ChangeZoneAll (ChangeZoneAllEffect.class),
|
||||||
|
|
||||||
|
Charm (CharmEffect.class),
|
||||||
|
ChooseCard (ChooseCardEffect.class),
|
||||||
|
ChooseColor (ChooseColorEffect.class),
|
||||||
|
ChooseNumber (ChooseNumberEffect.class),
|
||||||
|
ChoosePlayer (ChoosePlayerEffect.class),
|
||||||
|
ChooseSource (ChooseSourceEffect.class),
|
||||||
|
ChooseType (ChooseTypeEffect.class),
|
||||||
|
Clash (ClashEffect.class),
|
||||||
|
Cleanup (CleanUpEffect.class),
|
||||||
|
Clone (CloneEffect.class),
|
||||||
|
CopyPermanent (CopyPermanentEffect.class),
|
||||||
|
CopySpellAbility (CopySpellAbilityEffect.class),
|
||||||
|
ControlPlayer (ControlPlayerEffect.class),
|
||||||
|
Counter (CounterEffect.class),
|
||||||
|
DamageAll (DamageAllEffect.class),
|
||||||
|
DealDamage (DamageDealEffect.class),
|
||||||
|
Debuff (DebuffEffect.class),
|
||||||
|
DebuffAll (DebuffAllEffect.class),
|
||||||
|
DeclareCombatants (DeclareCombatantsEffect.class),
|
||||||
|
DelayedTrigger (DelayedTriggerEffect.class),
|
||||||
|
Destroy (DestroyEffect.class),
|
||||||
|
DestroyAll (DestroyAllEffect.class),
|
||||||
|
Dig (DigEffect.class),
|
||||||
|
DigUntil (DigUntilEffect.class),
|
||||||
|
Discard (DiscardEffect.class),
|
||||||
|
DrainMana (DrainManaEffect.class),
|
||||||
|
Draw (DrawEffect.class),
|
||||||
|
EachDamage (DamageEachEffect.class),
|
||||||
|
Effect (EffectEffect.class),
|
||||||
|
Encode (EncodeEffect.class),
|
||||||
|
EndTurn (EndTurnEffect.class),
|
||||||
|
ExchangeLife (LifeExchangeEffect.class),
|
||||||
|
ExchangeControl (ControlExchangeEffect.class),
|
||||||
|
ExchangePower (PowerExchangeEffect.class),
|
||||||
|
ExchangeZone (ZoneExchangeEffect.class),
|
||||||
|
Fight (FightEffect.class),
|
||||||
|
FlipACoin (FlipCoinEffect.class),
|
||||||
|
Fog (FogEffect.class),
|
||||||
|
GainControl (ControlGainEffect.class),
|
||||||
|
GainLife (LifeGainEffect.class),
|
||||||
|
GainOwnership (OwnershipGainEffect.class),
|
||||||
|
GenericChoice (ChooseGenericEffect.class),
|
||||||
|
LoseLife (LifeLoseEffect.class),
|
||||||
|
LosesGame (GameLossEffect.class),
|
||||||
|
Mana (ManaEffect.class),
|
||||||
|
ManaReflected (ManaReflectedEffect.class),
|
||||||
|
Mill (MillEffect.class),
|
||||||
|
MoveCounter (CountersMoveEffect.class),
|
||||||
|
MultiplePiles (MultiplePilesEffect.class),
|
||||||
|
MustAttack (MustAttackEffect.class),
|
||||||
|
MustBlock (MustBlockEffect.class),
|
||||||
|
NameCard (ChooseCardNameEffect.class),
|
||||||
|
PeekAndReveal (PeekAndRevealEffect.class),
|
||||||
|
PermanentCreature (PermanentCreatureEffect.class),
|
||||||
|
PermanentNoncreature (PermanentNoncreatureEffect.class),
|
||||||
|
Phases (PhasesEffect.class),
|
||||||
|
Planeswalk (PlaneswalkEffect.class),
|
||||||
|
Play (PlayEffect.class),
|
||||||
|
Poison (PoisonEffect.class),
|
||||||
|
PreventDamage (DamagePreventEffect.class),
|
||||||
|
PreventDamageAll (DamagePreventAllEffect.class),
|
||||||
|
Proliferate (CountersProliferateEffect.class),
|
||||||
|
Protection (ProtectEffect.class),
|
||||||
|
ProtectionAll (ProtectAllEffect.class),
|
||||||
|
Pump (PumpEffect.class),
|
||||||
|
PumpAll (PumpAllEffect.class),
|
||||||
|
PutCounter (CountersPutEffect.class),
|
||||||
|
PutCounterAll (CountersPutAllEffect.class),
|
||||||
|
RearrangeTopOfLibrary (RearrangeTopOfLibraryEffect.class),
|
||||||
|
Regenerate (RegenerateEffect.class),
|
||||||
|
RegenerateAll (RegenerateAllEffect.class),
|
||||||
|
RemoveCounter (CountersRemoveEffect.class),
|
||||||
|
RemoveCounterAll (CountersRemoveAllEffect.class),
|
||||||
|
RemoveFromCombat (RemoveFromCombatEffect.class),
|
||||||
|
ReorderZone (ReorderZoneEffect.class),
|
||||||
|
Repeat (RepeatEffect.class),
|
||||||
|
RepeatEach (RepeatEachEffect.class),
|
||||||
|
RestartGame (RestartGameEffect.class),
|
||||||
|
Reveal (RevealEffect.class),
|
||||||
|
RevealHand (RevealHandEffect.class),
|
||||||
|
RollPlanarDice (RollPlanarDiceEffect.class),
|
||||||
|
RunSVarAbility (RunSVarAbilityEffect.class),
|
||||||
|
Sacrifice (SacrificeEffect.class),
|
||||||
|
SacrificeAll (SacrificeAllEffect.class),
|
||||||
|
Scry (ScryEffect.class),
|
||||||
|
SetInMotion (SetInMotionEffect.class),
|
||||||
|
SetLife (LifeSetEffect.class),
|
||||||
|
SetState (SetStateEffect.class),
|
||||||
|
Shuffle (ShuffleEffect.class),
|
||||||
|
SkipTurn (SkipTurnEffect.class),
|
||||||
|
StoreSVar (StoreSVarEffect.class),
|
||||||
|
Tap (TapEffect.class),
|
||||||
|
TapAll (TapAllEffect.class),
|
||||||
|
TapOrUntap (TapOrUntapEffect.class),
|
||||||
|
TapOrUntapAll (TapOrUntapAllEffect.class),
|
||||||
|
Token (TokenEffect.class, false),
|
||||||
|
TwoPiles (TwoPilesEffect.class),
|
||||||
|
UnattachAll (UnattachAllEffect.class),
|
||||||
|
Untap (UntapEffect.class),
|
||||||
|
UntapAll (UntapAllEffect.class),
|
||||||
|
WinsGame (GameWinEffect.class),
|
||||||
|
|
||||||
|
|
||||||
|
InternalEtbReplacement (ETBReplacementEffect.class),
|
||||||
|
InternalLegendaryRule (CharmEffect.class),
|
||||||
|
InternalHaunt (CharmEffect.class);
|
||||||
|
|
||||||
Abandon (AbandonEffect.class, AlwaysPlayAi.class),
|
|
||||||
AddOrRemoveCounter (CountersPutOrRemoveEffect.class, CountersPutOrRemoveAi.class),
|
|
||||||
AddPhase (AddPhaseEffect.class, AddPhaseAi.class),
|
|
||||||
AddTurn (AddTurnEffect.class, AddTurnAi.class),
|
|
||||||
Animate (AnimateEffect.class, AnimateAi.class),
|
|
||||||
AnimateAll (AnimateAllEffect.class, AnimateAllAi.class),
|
|
||||||
Attach (AttachEffect.class, AttachAi.class),
|
|
||||||
Balance (BalanceEffect.class, BalanceAi.class),
|
|
||||||
BecomesBlocked (BecomesBlockedEffect.class, BecomesBlockedAi.class),
|
|
||||||
Bond (BondEffect.class, BondAi.class),
|
|
||||||
ChangeTargets(ChangeTargetsEffect.class, ChangeTargetsAi.class),
|
|
||||||
ChangeZone(ChangeZoneEffect.class, ChangeZoneAi.class),
|
|
||||||
ChangeZoneAll(ChangeZoneAllEffect.class, ChangeZoneAllAi.class),
|
|
||||||
/** This is <b>Modal</b>, like 'choose one - ' or 'choose two - '. <br> Might be great to rename this api and update all scripts.*/
|
|
||||||
Charm(CharmEffect.class, CharmAi.class),
|
|
||||||
ChooseCard (ChooseCardEffect.class, ChooseCardAi.class),
|
|
||||||
ChooseColor (ChooseColorEffect.class, ChooseColorAi.class),
|
|
||||||
ChooseNumber (ChooseNumberEffect.class, CannotPlayAi.class),
|
|
||||||
ChoosePlayer (ChoosePlayerEffect.class, ChoosePlayerAi.class),
|
|
||||||
ChooseSource (ChooseSourceEffect.class, ChooseSourceAi.class),
|
|
||||||
ChooseType (ChooseTypeEffect.class, ChooseTypeAi.class),
|
|
||||||
Clash (ClashEffect.class, ClashAi.class),
|
|
||||||
Cleanup (CleanUpEffect.class, AlwaysPlayAi.class),
|
|
||||||
Clone (CloneEffect.class, CloneAi.class),
|
|
||||||
CopyPermanent (CopyPermanentEffect.class, CopyPermanentAi.class),
|
|
||||||
CopySpellAbility (CopySpellAbilityEffect.class, CanPlayAsDrawbackAi.class),
|
|
||||||
ControlPlayer(ControlPlayerEffect.class, CannotPlayAi.class),
|
|
||||||
Counter (CounterEffect.class, CounterAi.class),
|
|
||||||
DamageAll (DamageAllEffect.class, DamageAllAi.class),
|
|
||||||
DealDamage (DamageDealEffect.class, DamageDealAi.class),
|
|
||||||
Debuff (DebuffEffect.class, DebuffAi.class),
|
|
||||||
DebuffAll (DebuffAllEffect.class, DebuffAllAi.class),
|
|
||||||
DeclareCombatants(DeclareCombatantsEffect.class, CannotPlayAi.class),
|
|
||||||
DelayedTrigger (DelayedTriggerEffect.class, DelayedTriggerAi.class),
|
|
||||||
Destroy (DestroyEffect.class, DestroyAi.class),
|
|
||||||
DestroyAll (DestroyAllEffect.class, DestroyAllAi.class),
|
|
||||||
Dig (DigEffect.class, DigAi.class),
|
|
||||||
DigUntil (DigUntilEffect.class, DigUntilAi.class),
|
|
||||||
Discard (DiscardEffect.class, DiscardAi.class),
|
|
||||||
DrainMana (DrainManaEffect.class, DrainManaAi.class),
|
|
||||||
Draw (DrawEffect.class, DrawAi.class),
|
|
||||||
EachDamage (DamageEachEffect.class, DamageEachAi.class),
|
|
||||||
Effect (EffectEffect.class, EffectAi.class),
|
|
||||||
Encode (EncodeEffect.class, EncodeAi.class),
|
|
||||||
EndTurn (EndTurnEffect.class, EndTurnAi.class),
|
|
||||||
ExchangeLife (LifeExchangeEffect.class, LifeExchangeAi.class),
|
|
||||||
ExchangeControl (ControlExchangeEffect.class, ControlExchangeAi.class),
|
|
||||||
ExchangePower (PowerExchangeEffect.class, PowerExchangeAi.class),
|
|
||||||
ExchangeZone (ZoneExchangeEffect.class, ZoneExchangeAi.class),
|
|
||||||
Fight (FightEffect.class, FightAi.class),
|
|
||||||
FlipACoin (FlipCoinEffect.class, FlipACoinAi.class),
|
|
||||||
Fog (FogEffect.class, FogAi.class),
|
|
||||||
GainControl (ControlGainEffect.class, ControlGainAi.class),
|
|
||||||
GainLife (LifeGainEffect.class, LifeGainAi.class),
|
|
||||||
GainOwnership(OwnershipGainEffect.class, CannotPlayAi.class),
|
|
||||||
GenericChoice (ChooseGenericEffect.class, ChooseGenericEffectAi.class),
|
|
||||||
LoseLife (LifeLoseEffect.class, LifeLoseAi.class),
|
|
||||||
LosesGame (GameLossEffect.class, GameLossAi.class),
|
|
||||||
Mana (ManaEffect.class, ManaEffectAi.class),
|
|
||||||
ManaReflected (ManaReflectedEffect.class, CannotPlayAi.class),
|
|
||||||
Mill (MillEffect.class, MillAi.class),
|
|
||||||
MoveCounter (CountersMoveEffect.class, CountersMoveAi.class),
|
|
||||||
MultiplePiles (MultiplePilesEffect.class, CannotPlayAi.class),
|
|
||||||
MustAttack (MustAttackEffect.class, MustAttackAi.class),
|
|
||||||
MustBlock (MustBlockEffect.class, MustBlockAi.class),
|
|
||||||
NameCard (ChooseCardNameEffect.class, ChooseCardNameAi.class),
|
|
||||||
PeekAndReveal (PeekAndRevealEffect.class, PeekAndRevealAi.class),
|
|
||||||
PermanentCreature (PermanentCreatureEffect.class, PermanentCreatureAi.class),
|
|
||||||
PermanentNoncreature (PermanentNoncreatureEffect.class, PermanentNoncreatureAi.class),
|
|
||||||
Phases (PhasesEffect.class, PhasesAi.class),
|
|
||||||
Planeswalk(PlaneswalkEffect.class, AlwaysPlayAi.class),
|
|
||||||
Play (PlayEffect.class, PlayAi.class),
|
|
||||||
Poison (PoisonEffect.class, PoisonAi.class),
|
|
||||||
PreventDamage (DamagePreventEffect.class, DamagePreventAi.class),
|
|
||||||
PreventDamageAll (DamagePreventAllEffect.class, DamagePreventAllAi.class),
|
|
||||||
Proliferate (CountersProliferateEffect.class, CountersProliferateAi.class),
|
|
||||||
Protection (ProtectEffect.class, ProtectAi.class),
|
|
||||||
ProtectionAll (ProtectAllEffect.class, ProtectAllAi.class),
|
|
||||||
Pump (PumpEffect.class, PumpAi.class),
|
|
||||||
PumpAll (PumpAllEffect.class, PumpAllAi.class),
|
|
||||||
PutCounter (CountersPutEffect.class, CountersPutAi.class),
|
|
||||||
PutCounterAll (CountersPutAllEffect.class, CountersPutAllAi.class),
|
|
||||||
RearrangeTopOfLibrary (RearrangeTopOfLibraryEffect.class, RearrangeTopOfLibraryAi.class),
|
|
||||||
Regenerate (RegenerateEffect.class, RegenerateAi.class),
|
|
||||||
RegenerateAll (RegenerateAllEffect.class, RegenerateAllAi.class),
|
|
||||||
RemoveCounter (CountersRemoveEffect.class, CountersRemoveAi.class),
|
|
||||||
RemoveCounterAll (CountersRemoveAllEffect.class, CannotPlayAi.class),
|
|
||||||
RemoveFromCombat (RemoveFromCombatEffect.class, RemoveFromCombatAi.class),
|
|
||||||
ReorderZone (ReorderZoneEffect.class, AlwaysPlayAi.class),
|
|
||||||
Repeat (RepeatEffect.class, RepeatAi.class),
|
|
||||||
RepeatEach (RepeatEachEffect.class, RepeatEachAi.class),
|
|
||||||
RestartGame (RestartGameEffect.class, RestartGameAi.class),
|
|
||||||
Reveal (RevealEffect.class, RevealAi.class),
|
|
||||||
RevealHand (RevealHandEffect.class, RevealHandAi.class),
|
|
||||||
RollPlanarDice (RollPlanarDiceEffect.class, RollPlanarDiceAi.class),
|
|
||||||
RunSVarAbility (RunSVarAbilityEffect.class, AlwaysPlayAi.class),
|
|
||||||
Sacrifice (SacrificeEffect.class, SacrificeAi.class),
|
|
||||||
SacrificeAll (SacrificeAllEffect.class, SacrificeAllAi.class),
|
|
||||||
Scry (ScryEffect.class, ScryAi.class),
|
|
||||||
SetInMotion (SetInMotionEffect.class, AlwaysPlayAi.class),
|
|
||||||
SetLife (LifeSetEffect.class, LifeSetAi.class),
|
|
||||||
SetState (SetStateEffect.class, SetStateAi.class),
|
|
||||||
Shuffle (ShuffleEffect.class, ShuffleAi.class),
|
|
||||||
SkipTurn (SkipTurnEffect.class, CannotPlayAi.class),
|
|
||||||
StoreSVar (StoreSVarEffect.class, StoreSVarAi.class),
|
|
||||||
Tap (TapEffect.class, TapAi.class),
|
|
||||||
TapAll (TapAllEffect.class, TapAllAi.class),
|
|
||||||
TapOrUntap (TapOrUntapEffect.class, TapOrUntapAi.class),
|
|
||||||
TapOrUntapAll (TapOrUntapAllEffect.class, TapOrUntapAllAi.class),
|
|
||||||
Token (TokenEffect.class, TokenAi.class, false), // Token AI and effect classes have state, they have to be re-created on each request
|
|
||||||
TwoPiles (TwoPilesEffect.class, TwoPilesAi.class),
|
|
||||||
UnattachAll (UnattachAllEffect.class, UnattachAllAi.class),
|
|
||||||
Untap (UntapEffect.class, UntapAi.class),
|
|
||||||
UntapAll (UntapAllEffect.class, UntapAllAi.class),
|
|
||||||
WinsGame (GameWinEffect.class, GameWinAi.class),
|
|
||||||
|
|
||||||
|
|
||||||
InternalEtbReplacement(ETBReplacementEffect.class, CanPlayAsDrawbackAi.class),
|
|
||||||
InternalLegendaryRule(CharmEffect.class, LegendaryRuleAi.class), // Charm has empty resolve blocks, may act as a dummy
|
|
||||||
InternalHaunt(CharmEffect.class, HauntAi.class);
|
|
||||||
|
|
||||||
private final Class<? extends SpellAbilityEffect> clsEffect;
|
|
||||||
private final Class<? extends SpellAbilityAi> clsAi;
|
|
||||||
|
|
||||||
private final SpellAbilityEffect instanceEffect;
|
private final SpellAbilityEffect instanceEffect;
|
||||||
private final SpellAbilityAi instanceAi;
|
private final Class<? extends SpellAbilityEffect> clsEffect;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static final Map<String, ApiType> allValues = new TreeMap<String, ApiType>(String.CASE_INSENSITIVE_ORDER);
|
private static final Map<String, ApiType> allValues = new TreeMap<String, ApiType>(String.CASE_INSENSITIVE_ORDER);
|
||||||
|
|
||||||
ApiType(Class<? extends SpellAbilityEffect> clsEf, Class<? extends SpellAbilityAi> clsAi) {
|
ApiType(Class<? extends SpellAbilityEffect> clsEf) { this(clsEf, true); }
|
||||||
this(clsEf, clsAi, true);
|
ApiType(Class<? extends SpellAbilityEffect> clsEf, final boolean isStateLess) {
|
||||||
}
|
|
||||||
|
|
||||||
ApiType(Class<? extends SpellAbilityEffect> clsEf, Class<? extends SpellAbilityAi> clsAI, final boolean isStateLess) {
|
|
||||||
clsEffect = clsEf;
|
clsEffect = clsEf;
|
||||||
clsAi = clsAI;
|
|
||||||
|
|
||||||
instanceAi = isStateLess ? ReflectionUtil.makeDefaultInstanceOf(clsAi) : null;
|
|
||||||
instanceEffect = isStateLess ? ReflectionUtil.makeDefaultInstanceOf(clsEf) : null;
|
instanceEffect = isStateLess ? ReflectionUtil.makeDefaultInstanceOf(clsEf) : null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ApiType smartValueOf(String value) {
|
public static ApiType smartValueOf(String value) {
|
||||||
if (allValues.isEmpty())
|
if (allValues.isEmpty())
|
||||||
for(ApiType c : ApiType.values())
|
for(ApiType c : ApiType.values())
|
||||||
allValues.put(c.toString(), c);
|
allValues.put(c.toString(), c);
|
||||||
|
|
||||||
ApiType v = allValues.get(value);
|
ApiType v = allValues.get(value);
|
||||||
if ( v == null )
|
if ( v == null )
|
||||||
throw new RuntimeException("Element " + value + " not found in ApiType enum");
|
throw new RuntimeException("Element " + value + " not found in ApiType enum");
|
||||||
@@ -173,9 +159,4 @@ public enum ApiType {
|
|||||||
public SpellAbilityEffect getSpellEffect() {
|
public SpellAbilityEffect getSpellEffect() {
|
||||||
return instanceEffect != null ? instanceEffect : ReflectionUtil.makeDefaultInstanceOf(clsEffect);
|
return instanceEffect != null ? instanceEffect : ReflectionUtil.makeDefaultInstanceOf(clsEffect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpellAbilityAi getAi() {
|
|
||||||
return instanceAi != null ? instanceAi : ReflectionUtil.makeDefaultInstanceOf(clsAi);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import com.google.common.collect.Multimap;
|
|||||||
|
|
||||||
import forge.ai.ComputerUtil;
|
import forge.ai.ComputerUtil;
|
||||||
import forge.ai.ComputerUtilMana;
|
import forge.ai.ComputerUtilMana;
|
||||||
|
import forge.ai.SpellAbilityAi;
|
||||||
|
import forge.ai.SpellApiToAi;
|
||||||
import forge.ai.ability.ChangeZoneAi;
|
import forge.ai.ability.ChangeZoneAi;
|
||||||
import forge.ai.ability.DrawAi;
|
import forge.ai.ability.DrawAi;
|
||||||
import forge.ai.ability.GameWinAi;
|
import forge.ai.ability.GameWinAi;
|
||||||
@@ -96,10 +98,11 @@ public class PlayerControllerForTests extends PlayerController {
|
|||||||
HumanPlay.playSpellAbilityNoStack(player, effectSA, !mayChoseNewTargets);
|
HumanPlay.playSpellAbilityNoStack(player, effectSA, !mayChoseNewTargets);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
SpellAbilityAi sai = SpellApiToAi.Converter.get(effectSA.getApi());
|
||||||
if (
|
if (
|
||||||
(effectSA.getHostCard().getName().equals("Nefarious Lich") && effectSA.getApi().getAi() instanceof DrawAi) ||
|
(effectSA.getHostCard().getName().equals("Nefarious Lich") && sai instanceof DrawAi) ||
|
||||||
(effectSA.getHostCard().getName().equals("Laboratory Maniac") && effectSA.getApi().getAi() instanceof GameWinAi) ||
|
(effectSA.getHostCard().getName().equals("Laboratory Maniac") && sai instanceof GameWinAi) ||
|
||||||
(effectSA.getHostCard().getName().equals("Nefarious Lich") && effectSA.getApi().getAi() instanceof ChangeZoneAi)
|
(effectSA.getHostCard().getName().equals("Nefarious Lich") && sai instanceof ChangeZoneAi)
|
||||||
) {//test_104_3f_if_a_player_would_win_and_lose_simultaneously_he_loses
|
) {//test_104_3f_if_a_player_would_win_and_lose_simultaneously_he_loses
|
||||||
HumanPlay.playSpellAbilityNoStack(player, effectSA, !mayChoseNewTargets);
|
HumanPlay.playSpellAbilityNoStack(player, effectSA, !mayChoseNewTargets);
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user