remove AI class from ApiType

This commit is contained in:
Maxmtg
2014-02-09 21:01:34 +00:00
parent 0f37de9627
commit dd34a3aa9b
11 changed files with 273 additions and 160 deletions

View File

@@ -616,7 +616,7 @@ public class AiController {
return canPlaySa(((WrappedAbility) sa).getWrappedAbility());
}
if( sa.getApi() != null ) {
boolean canPlay = sa.getApi().getAi().canPlayAIWithSubs(player, sa);
boolean canPlay = SpellApiToAi.Converter.get(sa.getApi()).canPlayAIWithSubs(player, sa);
if(!canPlay)
return AiPlayDecision.CantPlayAi;
}
@@ -876,7 +876,7 @@ public class AiController {
throw new IllegalArgumentException(exMsg);
} 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) {
@@ -940,9 +940,9 @@ public class AiController {
{
boolean chance = false;
if (withoutPayingManaCost) {
chance = spell.getApi().getAi().doTriggerNoCostWithSubs(player, spell, mandatory);
chance = SpellApiToAi.Converter.get(spell.getApi()).doTriggerNoCostWithSubs(player, spell, mandatory);
} else {
chance = spell.getApi().getAi().doTriggerAI(player, spell, mandatory);
chance = SpellApiToAi.Converter.get(spell.getApi()).doTriggerAI(player, spell, mandatory);
}
if (!chance)
return AiPlayDecision.TargetingFailed;
@@ -1148,7 +1148,7 @@ public class AiController {
public boolean doTrigger(SpellAbility spell, boolean mandatory) {
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 )
return doTrigger(((WrappedAbility)spell).getWrappedAbility(), mandatory);

View File

@@ -3,6 +3,7 @@ package forge.ai;
import com.google.common.base.Predicate;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import forge.card.MagicColor;
import forge.card.mana.ManaAtom;
import forge.card.mana.ManaCost;
@@ -28,6 +29,7 @@ import forge.util.CollectionSuppliers;
import forge.util.TextUtil;
import forge.util.maps.EnumMapOfLists;
import forge.util.maps.MapOfLists;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
@@ -630,7 +632,7 @@ public class ComputerUtilMana {
// don't use abilities with dangerous drawbacks
AbilitySub sub = m.getSubAbility();
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;
}
needsLimitedResources = true; // TODO: check for good drawbacks (gainLife)
@@ -688,7 +690,7 @@ public class ComputerUtilMana {
// don't use abilities with dangerous drawbacks
AbilitySub sub = m.getSubAbility();
if (sub != null) {
if (!sub.getApi().getAi().chkDrawbackWithSubs(ai, sub)) {
if (!SpellApiToAi.Converter.get(sub.getApi()).chkDrawbackWithSubs(ai, sub)) {
continue;
}
}

View File

@@ -134,7 +134,7 @@ public class PlayerControllerAi extends PlayerController {
if (null == api) {
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
@@ -143,7 +143,7 @@ public class PlayerControllerAi extends PlayerController {
if (null == api) {
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

View File

@@ -2,6 +2,7 @@ package forge.ai;
import com.google.common.collect.Iterables;
import forge.game.GameEntity;
import forge.game.ability.SaTargetRoutines;
import forge.game.card.Card;
@@ -136,7 +137,7 @@ public abstract class SpellAbilityAi extends SaTargetRoutines {
*/
public boolean chkDrawbackWithSubs(Player aiPlayer, AbilitySub ab) {
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) {

View 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;
}
}

View File

@@ -4,6 +4,7 @@ import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import forge.ai.*;
import forge.card.MagicColor;
import forge.game.Game;
@@ -307,7 +308,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
}
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();
chance &= subAb == null || subAb.getApi().getAi().chkDrawbackWithSubs(ai, subAb);
chance &= subAb == null || SpellApiToAi.Converter.get(subAb.getApi()).chkDrawbackWithSubs(ai, subAb);
return chance;
}

View File

@@ -4,6 +4,7 @@ import forge.ai.AiController;
import forge.ai.AiPlayDecision;
import forge.ai.PlayerControllerAi;
import forge.ai.SpellAbilityAi;
import forge.ai.SpellApiToAi;
import forge.game.ability.AbilityFactory;
import forge.game.player.Player;
import forge.game.spellability.AbilitySub;
@@ -18,7 +19,7 @@ public class DelayedTriggerAi extends SpellAbilityAi {
trigsa.setActivatingPlayer(ai);
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 {
return AiPlayDecision.WillPlay == ((PlayerControllerAi)ai.getController()).getAi().canPlaySa(trigsa);
}

View File

@@ -1,6 +1,7 @@
package forge.ai.ability;
import forge.ai.SpellAbilityAi;
import forge.ai.SpellApiToAi;
import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode;
import forge.game.spellability.AbilityStatic;
@@ -32,7 +33,7 @@ public class PeekAndRevealAi extends SpellAbilityAi {
@Override
public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) {
AbilitySub subAb = sa.getSubAbility();
return subAb != null && subAb.getApi().getAi().chkDrawbackWithSubs(player, subAb);
return subAb != null && SpellApiToAi.Converter.get(subAb.getApi()).chkDrawbackWithSubs(player, subAb);
}
}

View File

@@ -1,8 +1,6 @@
package forge.game.ability;
import forge.ai.SpellAbilityAi;
import forge.ai.ability.*;
import forge.game.ability.effects.*;
import forge.util.ReflectionUtil;
@@ -14,156 +12,144 @@ import java.util.TreeMap;
*
*/
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 SpellAbilityAi instanceAi;
private final Class<? extends SpellAbilityEffect> clsEffect;
private static final Map<String, ApiType> allValues = new TreeMap<String, ApiType>(String.CASE_INSENSITIVE_ORDER);
ApiType(Class<? extends SpellAbilityEffect> clsEf, Class<? extends SpellAbilityAi> clsAi) {
this(clsEf, clsAi, true);
}
ApiType(Class<? extends SpellAbilityEffect> clsEf, Class<? extends SpellAbilityAi> clsAI, final boolean isStateLess) {
ApiType(Class<? extends SpellAbilityEffect> clsEf) { this(clsEf, true); }
ApiType(Class<? extends SpellAbilityEffect> clsEf, final boolean isStateLess) {
clsEffect = clsEf;
clsAi = clsAI;
instanceAi = isStateLess ? ReflectionUtil.makeDefaultInstanceOf(clsAi) : null;
instanceEffect = isStateLess ? ReflectionUtil.makeDefaultInstanceOf(clsEf) : null;
}
public static ApiType smartValueOf(String value) {
if (allValues.isEmpty())
for(ApiType c : ApiType.values())
allValues.put(c.toString(), c);
ApiType v = allValues.get(value);
if ( v == null )
throw new RuntimeException("Element " + value + " not found in ApiType enum");
@@ -173,9 +159,4 @@ public enum ApiType {
public SpellAbilityEffect getSpellEffect() {
return instanceEffect != null ? instanceEffect : ReflectionUtil.makeDefaultInstanceOf(clsEffect);
}
public SpellAbilityAi getAi() {
return instanceAi != null ? instanceAi : ReflectionUtil.makeDefaultInstanceOf(clsAi);
}
}