Commit f386dc0e authored by 苍蓝's avatar 苍蓝

Update DefaultExecutor.cs

parent f35f444e
Pipeline #5911 passed with stage
in 1 minute and 10 seconds
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using YGOSharp.OCGWrapper.Enums; using YGOSharp.OCGWrapper.Enums;
using WindBot; using WindBot;
using WindBot.Game; using WindBot.Game;
using WindBot.Game.AI; using WindBot.Game.AI;
namespace WindBot.Game.AI namespace WindBot.Game.AI
{ {
public abstract class DefaultExecutor : Executor public abstract class DefaultExecutor : Executor
{ {
protected class _CardId protected class _CardId
{ {
public const int JizukirutheStarDestroyingKaiju = 63941210; public const int JizukirutheStarDestroyingKaiju = 63941210;
public const int ThunderKingtheLightningstrikeKaiju = 48770333; public const int ThunderKingtheLightningstrikeKaiju = 48770333;
public const int DogorantheMadFlameKaiju = 93332803; public const int DogorantheMadFlameKaiju = 93332803;
public const int RadiantheMultidimensionalKaiju = 28674152; public const int RadiantheMultidimensionalKaiju = 28674152;
public const int GadarlatheMysteryDustKaiju = 36956512; public const int GadarlatheMysteryDustKaiju = 36956512;
public const int KumongoustheStickyStringKaiju = 29726552; public const int KumongoustheStickyStringKaiju = 29726552;
public const int GamecieltheSeaTurtleKaiju = 55063751; public const int GamecieltheSeaTurtleKaiju = 55063751;
public const int SuperAntiKaijuWarMachineMechaDogoran = 84769941; public const int SuperAntiKaijuWarMachineMechaDogoran = 84769941;
public const int SandaionTheTimelord = 33015627; public const int SandaionTheTimelord = 33015627;
public const int GabrionTheTimelord = 6616912; public const int GabrionTheTimelord = 6616912;
public const int MichionTheTimelord = 7733560; public const int MichionTheTimelord = 7733560;
public const int ZaphionTheTimelord = 28929131; public const int ZaphionTheTimelord = 28929131;
public const int HailonTheTimelord = 34137269; public const int HailonTheTimelord = 34137269;
public const int RaphionTheTimelord = 60222213; public const int RaphionTheTimelord = 60222213;
public const int SadionTheTimelord = 65314286; public const int SadionTheTimelord = 65314286;
public const int MetaionTheTimelord = 74530899; public const int MetaionTheTimelord = 74530899;
public const int KamionTheTimelord = 91712985; public const int KamionTheTimelord = 91712985;
public const int LazionTheTimelord = 92435533; public const int LazionTheTimelord = 92435533;
public const int LeftArmofTheForbiddenOne = 7902349; public const int LeftArmofTheForbiddenOne = 7902349;
public const int RightLegofTheForbiddenOne = 8124921; public const int RightLegofTheForbiddenOne = 8124921;
public const int LeftLegofTheForbiddenOne = 44519536; public const int LeftLegofTheForbiddenOne = 44519536;
public const int RightArmofTheForbiddenOne = 70903634; public const int RightArmofTheForbiddenOne = 70903634;
public const int ExodiaTheForbiddenOne = 33396948; public const int ExodiaTheForbiddenOne = 33396948;
public const int UltimateConductorTytanno = 18940556; public const int UltimateConductorTytanno = 18940556;
public const int ElShaddollConstruct = 20366274; public const int ElShaddollConstruct = 20366274;
public const int AllyOfJusticeCatastor = 26593852; public const int AllyOfJusticeCatastor = 26593852;
public const int DupeFrog = 46239604; public const int DupeFrog = 46239604;
public const int MaraudingCaptain = 2460565; public const int MaraudingCaptain = 2460565;
public const int BlackRoseDragon = 73580471; public const int BlackRoseDragon = 73580471;
public const int JudgmentDragon = 57774843; public const int JudgmentDragon = 57774843;
public const int TopologicTrisbaena = 72529749; public const int TopologicTrisbaena = 72529749;
public const int EvilswarmExcitonKnight = 46772449; public const int EvilswarmExcitonKnight = 46772449;
public const int HarpiesFeatherDuster = 18144506; public const int HarpiesFeatherDuster = 18144506;
public const int DarkMagicAttack = 2314238; public const int DarkMagicAttack = 2314238;
public const int MysticalSpaceTyphoon = 5318639; public const int MysticalSpaceTyphoon = 5318639;
public const int CosmicCyclone = 8267140; public const int CosmicCyclone = 8267140;
public const int GalaxyCyclone = 5133471; public const int GalaxyCyclone = 5133471;
public const int BookOfMoon = 14087893; public const int BookOfMoon = 14087893;
public const int CompulsoryEvacuationDevice = 94192409; public const int CompulsoryEvacuationDevice = 94192409;
public const int CallOfTheHaunted = 97077563; public const int CallOfTheHaunted = 97077563;
public const int Scapegoat = 73915051; public const int Scapegoat = 73915051;
public const int BreakthroughSkill = 78474168; public const int BreakthroughSkill = 78474168;
public const int SolemnJudgment = 41420027; public const int SolemnJudgment = 41420027;
public const int SolemnWarning = 84749824; public const int SolemnWarning = 84749824;
public const int SolemnStrike = 40605147; public const int SolemnStrike = 40605147;
public const int TorrentialTribute = 53582587; public const int TorrentialTribute = 53582587;
public const int HeavyStorm = 19613556; public const int HeavyStorm = 19613556;
public const int HammerShot = 26412047; public const int HammerShot = 26412047;
public const int DarkHole = 53129443; public const int DarkHole = 53129443;
public const int Raigeki = 12580477; public const int Raigeki = 12580477;
public const int SmashingGround = 97169186; public const int SmashingGround = 97169186;
public const int PotOfDesires = 35261759; public const int PotOfDesires = 35261759;
public const int AllureofDarkness = 1475311; public const int AllureofDarkness = 1475311;
public const int DimensionalBarrier = 83326048; public const int DimensionalBarrier = 83326048;
public const int InterruptedKaijuSlumber = 99330325; public const int InterruptedKaijuSlumber = 99330325;
public const int ChickenGame = 67616300; public const int ChickenGame = 67616300;
public const int SantaClaws = 46565218; public const int SantaClaws = 46565218;
public const int CastelTheSkyblasterMusketeer = 82633039; public const int CastelTheSkyblasterMusketeer = 82633039;
public const int CrystalWingSynchroDragon = 50954680; public const int CrystalWingSynchroDragon = 50954680;
public const int NumberS39UtopiaTheLightning = 56832966; public const int NumberS39UtopiaTheLightning = 56832966;
public const int Number39Utopia = 84013237; public const int Number39Utopia = 84013237;
public const int UltimayaTzolkin = 1686814; public const int UltimayaTzolkin = 1686814;
public const int MekkKnightCrusadiaAstram = 21887175; public const int MekkKnightCrusadiaAstram = 21887175;
public const int HamonLordofStrikingThunder = 32491822; public const int HamonLordofStrikingThunder = 32491822;
public const int MoonMirrorShield = 19508728; public const int MoonMirrorShield = 19508728;
public const int PhantomKnightsFogBlade = 25542642; public const int PhantomKnightsFogBlade = 25542642;
public const int VampireFraeulein = 6039967; public const int VampireFraeulein = 6039967;
public const int InjectionFairyLily = 79575620; public const int InjectionFairyLily = 79575620;
public const int BlueEyesChaosMAXDragon = 55410871; public const int BlueEyesChaosMAXDragon = 55410871;
public const int AshBlossom = 14558127; public const int AshBlossom = 14558127;
public const int MaxxC = 23434538; public const int MaxxC = 23434538;
public const int LockBird = 94145021; public const int LockBird = 94145021;
public const int GhostOgreAndSnowRabbit = 59438930; public const int GhostOgreAndSnowRabbit = 59438930;
public const int GhostBelle = 73642296; public const int GhostBelle = 73642296;
public const int EffectVeiler = 97268402; public const int EffectVeiler = 97268402;
public const int ArtifactLancea = 34267821; public const int ArtifactLancea = 34267821;
public const int CalledByTheGrave = 24224830; public const int CalledByTheGrave = 24224830;
public const int InfiniteImpermanence = 10045474; public const int InfiniteImpermanence = 10045474;
public const int GalaxySoldier = 46659709; public const int GalaxySoldier = 46659709;
public const int MacroCosmos = 30241314; public const int MacroCosmos = 30241314;
public const int UpstartGoblin = 70368879; public const int UpstartGoblin = 70368879;
public const int CyberEmergency = 60600126; public const int CyberEmergency = 60600126;
public const int EaterOfMillions = 63845230; public const int EaterOfMillions = 63845230;
public const int InvokedPurgatrio = 12307878; public const int InvokedPurgatrio = 12307878;
public const int ChaosAncientGearGiant = 51788412; public const int ChaosAncientGearGiant = 51788412;
public const int UltimateAncientGearGolem = 12652643; public const int UltimateAncientGearGolem = 12652643;
public const int RedDragonArchfiend = 70902743; public const int RedDragonArchfiend = 70902743;
public const int ImperialOrder = 61740673; public const int ImperialOrder = 61740673;
public const int RoyalDecreel = 51452091; public const int RoyalDecreel = 51452091;
public const int NaturiaBeast = 33198837; public const int NaturiaBeast = 33198837;
public const int AntiSpellFragrance = 58921041; public const int AntiSpellFragrance = 58921041;
} }
protected DefaultExecutor(GameAI ai, Duel duel) protected DefaultExecutor(GameAI ai, Duel duel)
: base(ai, duel) : base(ai, duel)
{ {
AddExecutor(ExecutorType.Activate, _CardId.ChickenGame, DefaultChickenGame); AddExecutor(ExecutorType.Activate, _CardId.ChickenGame, DefaultChickenGame);
AddExecutor(ExecutorType.Activate, _CardId.SantaClaws); AddExecutor(ExecutorType.Activate, _CardId.SantaClaws);
} }
/// <summary> /// <summary>
/// Decide which card should the attacker attack. /// Decide which card should the attacker attack.
/// </summary> /// </summary>
/// <param name="attacker">Card that attack.</param> /// <param name="attacker">Card that attack.</param>
/// <param name="defenders">Cards that defend.</param> /// <param name="defenders">Cards that defend.</param>
/// <returns>BattlePhaseAction including the target, or null (in this situation, GameAI will check the next attacker)</returns> /// <returns>BattlePhaseAction including the target, or null (in this situation, GameAI will check the next attacker)</returns>
public override BattlePhaseAction OnSelectAttackTarget(ClientCard attacker, IList<ClientCard> defenders) public override BattlePhaseAction OnSelectAttackTarget(ClientCard attacker, IList<ClientCard> defenders)
{ {
foreach (ClientCard defender in defenders) foreach (ClientCard defender in defenders)
{ {
attacker.RealPower = attacker.Attack; attacker.RealPower = attacker.Attack;
defender.RealPower = defender.GetDefensePower(); defender.RealPower = defender.GetDefensePower();
if (!OnPreBattleBetween(attacker, defender)) if (!OnPreBattleBetween(attacker, defender))
continue; continue;
if (attacker.RealPower > defender.RealPower || (attacker.RealPower >= defender.RealPower && attacker.IsLastAttacker && defender.IsAttack())) if (attacker.RealPower > defender.RealPower || (attacker.RealPower >= defender.RealPower && attacker.IsLastAttacker && defender.IsAttack()))
return AI.Attack(attacker, defender); return AI.Attack(attacker, defender);
} }
if (attacker.CanDirectAttack) if (attacker.CanDirectAttack)
return AI.Attack(attacker, null); return AI.Attack(attacker, null);
return null; return null;
} }
/// <summary> /// <summary>
/// Decide whether to declare attack between attacker and defender. /// Decide whether to declare attack between attacker and defender.
/// Can be overrided to update the RealPower of attacker for cards like Honest. /// Can be overrided to update the RealPower of attacker for cards like Honest.
/// </summary> /// </summary>
/// <param name="attacker">Card that attack.</param> /// <param name="attacker">Card that attack.</param>
/// <param name="defender">Card that defend.</param> /// <param name="defender">Card that defend.</param>
/// <returns>false if the attack shouldn't be done.</returns> /// <returns>false if the attack shouldn't be done.</returns>
public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender) public override bool OnPreBattleBetween(ClientCard attacker, ClientCard defender)
{ {
if (!attacker.IsMonsterHasPreventActivationEffectInBattle()) if (!attacker.IsMonsterHasPreventActivationEffectInBattle())
{ {
if (defender.IsMonsterInvincible() && defender.IsDefense()) if (defender.IsMonsterInvincible() && defender.IsDefense())
return false; return false;
if (defender.IsMonsterDangerous()) if (defender.IsMonsterDangerous())
{ {
bool canIgnoreIt = !attacker.IsDisabled() && ( bool canIgnoreIt = !attacker.IsDisabled() && (
attacker.IsCode(_CardId.UltimateConductorTytanno) && defender.IsDefense() || attacker.IsCode(_CardId.UltimateConductorTytanno) && defender.IsDefense() ||
attacker.IsCode(_CardId.ElShaddollConstruct) && defender.IsSpecialSummoned || attacker.IsCode(_CardId.ElShaddollConstruct) && defender.IsSpecialSummoned ||
attacker.IsCode(_CardId.AllyOfJusticeCatastor) && !defender.HasAttribute(CardAttribute.Dark)); attacker.IsCode(_CardId.AllyOfJusticeCatastor) && !defender.HasAttribute(CardAttribute.Dark));
if (!canIgnoreIt) if (!canIgnoreIt)
return false; return false;
} }
foreach (ClientCard equip in defender.EquipCards) foreach (ClientCard equip in defender.EquipCards)
{ {
if (equip.IsCode(_CardId.MoonMirrorShield) && !equip.IsDisabled()) if (equip.IsCode(_CardId.MoonMirrorShield) && !equip.IsDisabled())
{ {
return false; return false;
} }
} }
if (!defender.IsDisabled()) if (!defender.IsDisabled())
{ {
if (defender.IsCode(_CardId.MekkKnightCrusadiaAstram) && defender.IsAttack() && attacker.IsSpecialSummoned) if (defender.IsCode(_CardId.MekkKnightCrusadiaAstram) && defender.IsAttack() && attacker.IsSpecialSummoned)
return false; return false;
if (defender.IsCode(_CardId.CrystalWingSynchroDragon) && defender.IsAttack() && attacker.Level >= 5) if (defender.IsCode(_CardId.CrystalWingSynchroDragon) && defender.IsAttack() && attacker.Level >= 5)
return false; return false;
if (defender.IsCode(_CardId.AllyOfJusticeCatastor) && !attacker.HasAttribute(CardAttribute.Dark)) if (defender.IsCode(_CardId.AllyOfJusticeCatastor) && !attacker.HasAttribute(CardAttribute.Dark))
return false; return false;
if (defender.IsCode(_CardId.NumberS39UtopiaTheLightning) && defender.IsAttack() && defender.HasXyzMaterial(2, _CardId.Number39Utopia)) if (defender.IsCode(_CardId.NumberS39UtopiaTheLightning) && defender.IsAttack() && defender.HasXyzMaterial(2, _CardId.Number39Utopia))
defender.RealPower = 5000; defender.RealPower = 5000;
if (defender.IsCode(_CardId.VampireFraeulein)) if (defender.IsCode(_CardId.VampireFraeulein))
defender.RealPower += (Enemy.LifePoints > 3000) ? 3000 : (Enemy.LifePoints - 100); defender.RealPower += (Enemy.LifePoints > 3000) ? 3000 : (Enemy.LifePoints - 100);
if (defender.IsCode(_CardId.InjectionFairyLily) && Enemy.LifePoints > 2000) if (defender.IsCode(_CardId.InjectionFairyLily) && Enemy.LifePoints > 2000)
defender.RealPower += 3000; defender.RealPower += 3000;
} }
} }
if (!defender.IsMonsterHasPreventActivationEffectInBattle()) if (!defender.IsMonsterHasPreventActivationEffectInBattle())
{ {
if (attacker.IsCode(_CardId.NumberS39UtopiaTheLightning) && !attacker.IsDisabled() && attacker.HasXyzMaterial(2, _CardId.Number39Utopia)) if (attacker.IsCode(_CardId.NumberS39UtopiaTheLightning) && !attacker.IsDisabled() && attacker.HasXyzMaterial(2, _CardId.Number39Utopia))
attacker.RealPower = 5000; attacker.RealPower = 5000;
if (attacker.IsCode(_CardId.EaterOfMillions) && !attacker.IsDisabled()) if (attacker.IsCode(_CardId.EaterOfMillions) && !attacker.IsDisabled())
attacker.RealPower = 9999; attacker.RealPower = 9999;
if (attacker.IsMonsterInvincible()) if (attacker.IsMonsterInvincible())
attacker.RealPower = 9999; attacker.RealPower = 9999;
foreach (ClientCard equip in attacker.EquipCards) foreach (ClientCard equip in attacker.EquipCards)
{ {
if (equip.IsCode(_CardId.MoonMirrorShield) && !equip.IsDisabled()) if (equip.IsCode(_CardId.MoonMirrorShield) && !equip.IsDisabled())
{ {
attacker.RealPower = defender.RealPower + 100; attacker.RealPower = defender.RealPower + 100;
} }
} }
} }
if (Enemy.HasInMonstersZone(_CardId.MekkKnightCrusadiaAstram, true) && !(defender).IsCode(_CardId.MekkKnightCrusadiaAstram)) if (Enemy.HasInMonstersZone(_CardId.MekkKnightCrusadiaAstram, true) && !(defender).IsCode(_CardId.MekkKnightCrusadiaAstram))
return false; return false;
if (Enemy.HasInMonstersZone(_CardId.DupeFrog, true) && !(defender).IsCode(_CardId.DupeFrog)) if (Enemy.HasInMonstersZone(_CardId.DupeFrog, true) && !(defender).IsCode(_CardId.DupeFrog))
return false; return false;
if (Enemy.HasInMonstersZone(_CardId.MaraudingCaptain, true) && !defender.IsCode(_CardId.MaraudingCaptain) && defender.Race == (int)CardRace.Warrior) if (Enemy.HasInMonstersZone(_CardId.MaraudingCaptain, true) && !defender.IsCode(_CardId.MaraudingCaptain) && defender.Race == (int)CardRace.Warrior)
return false; return false;
if (defender.IsCode(_CardId.UltimayaTzolkin) && !defender.IsDisabled() && Enemy.GetMonsters().Any(monster => !monster.Equals(defender) && monster.HasType(CardType.Synchro))) if (defender.IsCode(_CardId.UltimayaTzolkin) && !defender.IsDisabled() && Enemy.GetMonsters().Any(monster => !monster.Equals(defender) && monster.HasType(CardType.Synchro)))
return false; return false;
if (Enemy.GetMonsters().Any(monster => !monster.Equals(defender) && monster.IsCode(_CardId.HamonLordofStrikingThunder) && !monster.IsDisabled() && monster.IsDefense())) if (Enemy.GetMonsters().Any(monster => !monster.Equals(defender) && monster.IsCode(_CardId.HamonLordofStrikingThunder) && !monster.IsDisabled() && monster.IsDefense()))
return false; return false;
if (defender.OwnTargets.Any(card => card.IsCode(_CardId.PhantomKnightsFogBlade) && !card.IsDisabled())) if (defender.OwnTargets.Any(card => card.IsCode(_CardId.PhantomKnightsFogBlade) && !card.IsDisabled()))
return false; return false;
return true; return true;
} }
public override bool OnPreActivate(ClientCard card) public override bool OnPreActivate(ClientCard card)
{ {
ClientCard LastChainCard = Util.GetLastChainCard(); ClientCard LastChainCard = Util.GetLastChainCard();
if (LastChainCard != null && Duel.Phase == DuelPhase.Standby && if (LastChainCard != null && Duel.Phase == DuelPhase.Standby &&
LastChainCard.IsCode( LastChainCard.IsCode(
_CardId.SandaionTheTimelord, _CardId.SandaionTheTimelord,
_CardId.GabrionTheTimelord, _CardId.GabrionTheTimelord,
_CardId.MichionTheTimelord, _CardId.MichionTheTimelord,
_CardId.ZaphionTheTimelord, _CardId.ZaphionTheTimelord,
_CardId.HailonTheTimelord, _CardId.HailonTheTimelord,
_CardId.RaphionTheTimelord, _CardId.RaphionTheTimelord,
_CardId.SadionTheTimelord, _CardId.SadionTheTimelord,
_CardId.MetaionTheTimelord, _CardId.MetaionTheTimelord,
_CardId.KamionTheTimelord, _CardId.KamionTheTimelord,
_CardId.LazionTheTimelord _CardId.LazionTheTimelord
)) ))
return false; return false;
if ((card.Location == CardLocation.Hand || card.Location == CardLocation.SpellZone && card.IsFacedown()) && if ((card.Location == CardLocation.Hand || card.Location == CardLocation.SpellZone && card.IsFacedown()) &&
(card.IsSpell() && DefaultSpellWillBeNegated() || card.IsTrap() && DefaultTrapWillBeNegated())) (card.IsSpell() && DefaultSpellWillBeNegated() || card.IsTrap() && DefaultTrapWillBeNegated()))
return false; return false;
return true; return true;
} }
/// <summary> /// <summary>
/// Called when the AI has to select a card position. /// Called when the AI has to select a card position.
/// </summary> /// </summary>
/// <param name="cardId">Id of the card to position on the field.</param> /// <param name="cardId">Id of the card to position on the field.</param>
/// <param name="positions">List of available positions.</param> /// <param name="positions">List of available positions.</param>
/// <returns>Selected position, or 0 if no position is set for this card.</returns> /// <returns>Selected position, or 0 if no position is set for this card.</returns>
public override CardPosition OnSelectPosition(int cardId, IList<CardPosition> positions) public override CardPosition OnSelectPosition(int cardId, IList<CardPosition> positions)
{ {
YGOSharp.OCGWrapper.NamedCard cardData = YGOSharp.OCGWrapper.NamedCard.Get(cardId); YGOSharp.OCGWrapper.NamedCard cardData = YGOSharp.OCGWrapper.NamedCard.Get(cardId);
if (cardData != null) if (cardData != null)
{ {
if (cardData.Attack == 0) if (cardData.Attack == 0)
return CardPosition.FaceUpDefence; return CardPosition.FaceUpDefence;
} }
return 0; return 0;
} }
public override bool OnSelectBattleReplay() public override bool OnSelectBattleReplay()
{ {
if (Bot.BattlingMonster == null) if (Bot.BattlingMonster == null)
return false; return false;
List<ClientCard> defenders = new List<ClientCard>(Duel.Fields[1].GetMonsters()); List<ClientCard> defenders = new List<ClientCard>(Duel.Fields[1].GetMonsters());
defenders.Sort(CardContainer.CompareDefensePower); defenders.Sort(CardContainer.CompareDefensePower);
defenders.Reverse(); defenders.Reverse();
BattlePhaseAction result = OnSelectAttackTarget(Bot.BattlingMonster, defenders); BattlePhaseAction result = OnSelectAttackTarget(Bot.BattlingMonster, defenders);
if (result != null && result.Action == BattlePhaseAction.BattleAction.Attack) if (result != null && result.Action == BattlePhaseAction.BattleAction.Attack)
{ {
return true; return true;
} }
return false; return false;
} }
/// <summary> /// <summary>
/// Set when this card can't beat the enemies /// Set when this card can't beat the enemies
/// </summary> /// </summary>
public override bool OnSelectMonsterSummonOrSet(ClientCard card) public override bool OnSelectMonsterSummonOrSet(ClientCard card)
{ {
return card.Level <= 4 && Bot.GetMonsters().Count(m => m.IsFaceup()) == 0 && Util.IsAllEnemyBetterThanValue(card.Attack, true); return card.Level <= 4 && Bot.GetMonsters().Count(m => m.IsFaceup()) == 0 && Util.IsAllEnemyBetterThanValue(card.Attack, true);
} }
/// <summary> /// <summary>
/// Destroy face-down cards first, in our turn. /// Destroy face-down cards first, in our turn.
/// </summary> /// </summary>
protected bool DefaultMysticalSpaceTyphoon() protected bool DefaultMysticalSpaceTyphoon()
{ {
if (Duel.CurrentChain.Any(card => card.IsCode(_CardId.MysticalSpaceTyphoon))) if (Duel.CurrentChain.Any(card => card.IsCode(_CardId.MysticalSpaceTyphoon)))
{ {
return false; return false;
} }
List<ClientCard> spells = Enemy.GetSpells(); List<ClientCard> spells = Enemy.GetSpells();
if (spells.Count == 0) if (spells.Count == 0)
return false; return false;
ClientCard selected = Enemy.SpellZone.GetFloodgate(); ClientCard selected = Enemy.SpellZone.GetFloodgate();
if (selected == null) if (selected == null)
{ {
if (Duel.Player == 0) if (Duel.Player == 0)
selected = spells.FirstOrDefault(card => card.IsFacedown()); selected = spells.FirstOrDefault(card => card.IsFacedown());
if (Duel.Player == 1) if (Duel.Player == 1)
selected = spells.FirstOrDefault(card => card.HasType(CardType.Continuous) || card.HasType(CardType.Equip) || card.HasType(CardType.Field)); selected = spells.FirstOrDefault(card => card.HasType(CardType.Continuous) || card.HasType(CardType.Equip) || card.HasType(CardType.Field));
} }
if (selected == null) if (selected == null)
return false; return false;
AI.SelectCard(selected); AI.SelectCard(selected);
return true; return true;
} }
/// <summary> /// <summary>
/// Destroy face-down cards first, in our turn. /// Destroy face-down cards first, in our turn.
/// </summary> /// </summary>
protected bool DefaultCosmicCyclone() protected bool DefaultCosmicCyclone()
{ {
foreach (ClientCard card in Duel.CurrentChain) foreach (ClientCard card in Duel.CurrentChain)
if (card.IsCode(_CardId.CosmicCyclone)) if (card.IsCode(_CardId.CosmicCyclone))
return false; return false;
return (Bot.LifePoints > 1000) && DefaultMysticalSpaceTyphoon(); return (Bot.LifePoints > 1000) && DefaultMysticalSpaceTyphoon();
} }
/// <summary> /// <summary>
/// Activate if avail. /// Activate if avail.
/// </summary> /// </summary>
protected bool DefaultGalaxyCyclone() protected bool DefaultGalaxyCyclone()
{ {
List<ClientCard> spells = Enemy.GetSpells(); List<ClientCard> spells = Enemy.GetSpells();
if (spells.Count == 0) if (spells.Count == 0)
return false; return false;
ClientCard selected = null; ClientCard selected = null;
if (Card.Location == CardLocation.Grave) if (Card.Location == CardLocation.Grave)
{ {
selected = Util.GetBestEnemySpell(true); selected = Util.GetBestEnemySpell(true);
} }
else else
{ {
selected = spells.FirstOrDefault(card => card.IsFacedown()); selected = spells.FirstOrDefault(card => card.IsFacedown());
} }
if (selected == null) if (selected == null)
return false; return false;
AI.SelectCard(selected); AI.SelectCard(selected);
return true; return true;
} }
/// <summary> /// <summary>
/// Set the highest ATK level 4+ effect enemy monster. /// Set the highest ATK level 4+ effect enemy monster.
/// </summary> /// </summary>
protected bool DefaultBookOfMoon() protected bool DefaultBookOfMoon()
{ {
if (Util.IsAllEnemyBetter(true)) if (Util.IsAllEnemyBetter(true))
{ {
ClientCard monster = Enemy.GetMonsters().GetHighestAttackMonster(true); ClientCard monster = Enemy.GetMonsters().GetHighestAttackMonster(true);
if (monster != null && monster.HasType(CardType.Effect) && !monster.HasType(CardType.Link) && (monster.HasType(CardType.Xyz) || monster.Level > 4)) if (monster != null && monster.HasType(CardType.Effect) && !monster.HasType(CardType.Link) && (monster.HasType(CardType.Xyz) || monster.Level > 4))
{ {
AI.SelectCard(monster); AI.SelectCard(monster);
return true; return true;
} }
} }
return false; return false;
} }
/// <summary> /// <summary>
/// Return problematic monster, and if this card become target, return any enemy monster. /// Return problematic monster, and if this card become target, return any enemy monster.
/// </summary> /// </summary>
protected bool DefaultCompulsoryEvacuationDevice() protected bool DefaultCompulsoryEvacuationDevice()
{ {
ClientCard target = Util.GetProblematicEnemyMonster(0, true); ClientCard target = Util.GetProblematicEnemyMonster(0, true);
if (target != null) if (target != null)
{ {
AI.SelectCard(target); AI.SelectCard(target);
return true; return true;
} }
if (Util.IsChainTarget(Card)) if (Util.IsChainTarget(Card))
{ {
ClientCard monster = Util.GetBestEnemyMonster(false, true); ClientCard monster = Util.GetBestEnemyMonster(false, true);
if (monster != null) if (monster != null)
{ {
AI.SelectCard(monster); AI.SelectCard(monster);
return true; return true;
} }
} }
return false; return false;
} }
/// <summary> /// <summary>
/// Revive the best monster when we don't have better one in field. /// Revive the best monster when we don't have better one in field.
/// </summary> /// </summary>
protected bool DefaultCallOfTheHaunted() protected bool DefaultCallOfTheHaunted()
{ {
if (!Util.IsAllEnemyBetter(true)) if (!Util.IsAllEnemyBetter(true))
return false; return false;
ClientCard selected = Bot.Graveyard.GetMatchingCards(card => card.IsCanRevive()).OrderByDescending(card => card.Attack).FirstOrDefault(); ClientCard selected = Bot.Graveyard.GetMatchingCards(card => card.IsCanRevive()).OrderByDescending(card => card.Attack).FirstOrDefault();
AI.SelectCard(selected); AI.SelectCard(selected);
return true; return true;
} }
/// <summary> /// <summary>
/// Default Scapegoat effect /// Default Scapegoat effect
/// </summary> /// </summary>
protected bool DefaultScapegoat() protected bool DefaultScapegoat()
{ {
if (DefaultSpellWillBeNegated()) return false; if (DefaultSpellWillBeNegated()) return false;
if (Duel.Player == 0) return false; if (Duel.Player == 0) return false;
if (Duel.Phase == DuelPhase.End) return true; if (Duel.Phase == DuelPhase.End) return true;
if (DefaultOnBecomeTarget()) return true; if (DefaultOnBecomeTarget()) return true;
if (Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2) if (Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2)
{ {
if (Enemy.HasInMonstersZone(new[] if (Enemy.HasInMonstersZone(new[]
{ {
_CardId.UltimateConductorTytanno, _CardId.UltimateConductorTytanno,
_CardId.InvokedPurgatrio, _CardId.InvokedPurgatrio,
_CardId.ChaosAncientGearGiant, _CardId.ChaosAncientGearGiant,
_CardId.UltimateAncientGearGolem, _CardId.UltimateAncientGearGolem,
_CardId.RedDragonArchfiend _CardId.RedDragonArchfiend
}, true)) return false; }, true)) return false;
if (Util.GetTotalAttackingMonsterAttack(1) >= Bot.LifePoints) return true; if (Util.GetTotalAttackingMonsterAttack(1) >= Bot.LifePoints) return true;
} }
return false; return false;
} }
/// <summary> /// <summary>
/// Always active in opponent's turn. /// Always active in opponent's turn.
/// </summary> /// </summary>
protected bool DefaultMaxxC() protected bool DefaultMaxxC()
{ {
return Duel.Player == 1; return Duel.Player == 1;
} }
/// <summary> /// <summary>
/// Always disable opponent's effect except some cards like UpstartGoblin /// Always disable opponent's effect except some cards like UpstartGoblin
/// </summary> /// </summary>
protected bool DefaultAshBlossomAndJoyousSpring() protected bool DefaultAshBlossomAndJoyousSpring()
{ {
int[] ignoreList = { int[] ignoreList = {
_CardId.MacroCosmos, _CardId.MacroCosmos,
_CardId.UpstartGoblin, _CardId.UpstartGoblin,
_CardId.CyberEmergency _CardId.CyberEmergency
}; };
if (Util.GetLastChainCard().IsCode(ignoreList)) if (Util.GetLastChainCard().IsCode(ignoreList))
return false; return false;
if (Util.GetLastChainCard().HasSetcode(0x11e) && Util.GetLastChainCard().Location == CardLocation.Hand) // Danger! archtype hand effect if (Util.GetLastChainCard().HasSetcode(0x11e) && Util.GetLastChainCard().Location == CardLocation.Hand) // Danger! archtype hand effect
return false; return false;
return Duel.LastChainPlayer == 1; return Duel.LastChainPlayer == 1;
} }
/// <summary> /// <summary>
/// Always activate unless the activating card is disabled /// Always activate unless the activating card is disabled
/// </summary> /// </summary>
protected bool DefaultGhostOgreAndSnowRabbit() protected bool DefaultGhostOgreAndSnowRabbit()
{ {
if (Util.GetLastChainCard() != null && Util.GetLastChainCard().IsDisabled()) if (Util.GetLastChainCard() != null && Util.GetLastChainCard().IsDisabled())
return false; return false;
return DefaultTrap(); return DefaultTrap();
} }
/// <summary> /// <summary>
/// Always disable opponent's effect /// Always disable opponent's effect
/// </summary> /// </summary>
protected bool DefaultGhostBelleAndHauntedMansion() protected bool DefaultGhostBelleAndHauntedMansion()
{ {
return DefaultTrap(); return DefaultTrap();
} }
/// <summary> /// <summary>
/// Same as DefaultBreakthroughSkill /// Same as DefaultBreakthroughSkill
/// </summary> /// </summary>
protected bool DefaultEffectVeiler() protected bool DefaultEffectVeiler()
{ {
if (Util.GetLastChainCard() != null && Util.GetLastChainCard().IsCode(_CardId.GalaxySoldier) && Enemy.Hand.Count >= 3) return false; if (Util.GetLastChainCard() != null && Util.GetLastChainCard().IsCode(_CardId.GalaxySoldier) && Enemy.Hand.Count >= 3) return false;
if (Util.ChainContainsCard(_CardId.EffectVeiler)) if (Util.ChainContainsCard(_CardId.EffectVeiler))
return false; return false;
return DefaultBreakthroughSkill(); return DefaultBreakthroughSkill();
} }
/// <summary> /// <summary>
/// Chain common hand traps /// Chain common hand traps
/// </summary> /// </summary>
protected bool DefaultCalledByTheGrave() protected bool DefaultCalledByTheGrave()
{ {
int[] targetList = int[] targetList =
{ {
_CardId.MaxxC, _CardId.MaxxC,
_CardId.LockBird, _CardId.LockBird,
_CardId.GhostOgreAndSnowRabbit, _CardId.GhostOgreAndSnowRabbit,
_CardId.AshBlossom, _CardId.AshBlossom,
_CardId.GhostBelle, _CardId.GhostBelle,
_CardId.EffectVeiler, _CardId.EffectVeiler,
_CardId.ArtifactLancea _CardId.ArtifactLancea
}; };
if (Duel.LastChainPlayer == 1) if (Duel.LastChainPlayer == 1)
{ {
foreach (int id in targetList) foreach (int id in targetList)
{ {
if (Util.GetLastChainCard().IsCode(id)) if (Util.GetLastChainCard().IsCode(id))
{ {
AI.SelectCard(id); AI.SelectCard(id);
return UniqueFaceupSpell(); return UniqueFaceupSpell();
} }
} }
} }
return false; return false;
} }
/// <summary> /// <summary>
/// Default InfiniteImpermanence effect /// Default InfiniteImpermanence effect
/// </summary> /// </summary>
protected bool DefaultInfiniteImpermanence() protected bool DefaultInfiniteImpermanence()
{ {
// TODO: disable s & t // TODO: disable s & t
if (!DefaultUniqueTrap()) if (!DefaultUniqueTrap())
return false; return false;
return DefaultDisableMonster(); return DefaultDisableMonster();
} }
/// <summary> /// <summary>
/// Chain the enemy monster, or disable monster like Rescue Rabbit. /// Chain the enemy monster, or disable monster like Rescue Rabbit.
/// </summary> /// </summary>
protected bool DefaultBreakthroughSkill() protected bool DefaultBreakthroughSkill()
{ {
if (!DefaultUniqueTrap()) if (!DefaultUniqueTrap())
return false; return false;
return DefaultDisableMonster(); return DefaultDisableMonster();
} }
/// <summary> /// <summary>
/// Chain the enemy monster, or disable monster like Rescue Rabbit. /// Chain the enemy monster, or disable monster like Rescue Rabbit.
/// </summary> /// </summary>
protected bool DefaultDisableMonster() protected bool DefaultDisableMonster()
{ {
if (Duel.Player == 1) if (Duel.Player == 1)
{ {
ClientCard target = Enemy.MonsterZone.GetShouldBeDisabledBeforeItUseEffectMonster(); ClientCard target = Enemy.MonsterZone.GetShouldBeDisabledBeforeItUseEffectMonster();
if (target != null) if (target != null)
{ {
AI.SelectCard(target); AI.SelectCard(target);
return true; return true;
} }
} }
ClientCard LastChainCard = Util.GetLastChainCard(); ClientCard LastChainCard = Util.GetLastChainCard();
if (LastChainCard != null && LastChainCard.Controller == 1 && LastChainCard.Location == CardLocation.MonsterZone && if (LastChainCard != null && LastChainCard.Controller == 1 && LastChainCard.Location == CardLocation.MonsterZone &&
!LastChainCard.IsDisabled() && !LastChainCard.IsShouldNotBeTarget() && !LastChainCard.IsShouldNotBeSpellTrapTarget()) !LastChainCard.IsDisabled() && !LastChainCard.IsShouldNotBeTarget() && !LastChainCard.IsShouldNotBeSpellTrapTarget())
{ {
AI.SelectCard(LastChainCard); AI.SelectCard(LastChainCard);
return true; return true;
} }
if (Bot.BattlingMonster != null && Enemy.BattlingMonster != null) if (Bot.BattlingMonster != null && Enemy.BattlingMonster != null)
{ {
if (!Enemy.BattlingMonster.IsDisabled() && Enemy.BattlingMonster.IsCode(_CardId.EaterOfMillions)) if (!Enemy.BattlingMonster.IsDisabled() && Enemy.BattlingMonster.IsCode(_CardId.EaterOfMillions))
{ {
AI.SelectCard(Enemy.BattlingMonster); AI.SelectCard(Enemy.BattlingMonster);
return true; return true;
} }
} }
if (Duel.Phase == DuelPhase.BattleStart && Duel.Player == 1 && if (Duel.Phase == DuelPhase.BattleStart && Duel.Player == 1 &&
Enemy.HasInMonstersZone(_CardId.NumberS39UtopiaTheLightning, true)) Enemy.HasInMonstersZone(_CardId.NumberS39UtopiaTheLightning, true))
{ {
AI.SelectCard(_CardId.NumberS39UtopiaTheLightning); AI.SelectCard(_CardId.NumberS39UtopiaTheLightning);
return true; return true;
} }
return false; return false;
} }
/// <summary> /// <summary>
/// Activate only except this card is the target or we summon monsters. /// Activate only except this card is the target or we summon monsters.
/// </summary> /// </summary>
protected bool DefaultSolemnJudgment() protected bool DefaultSolemnJudgment()
{ {
return !Util.IsChainTargetOnly(Card) && !(Duel.Player == 0 && Duel.LastChainPlayer == -1) && DefaultTrap(); return !Util.IsChainTargetOnly(Card) && !(Duel.Player == 0 && Duel.LastChainPlayer == -1) && DefaultTrap();
} }
/// <summary> /// <summary>
/// Activate only except we summon monsters. /// Activate only except we summon monsters.
/// </summary> /// </summary>
protected bool DefaultSolemnWarning() protected bool DefaultSolemnWarning()
{ {
return (Bot.LifePoints > 2000) && !(Duel.Player == 0 && Duel.LastChainPlayer == -1) && DefaultTrap(); return (Bot.LifePoints > 2000) && !(Duel.Player == 0 && Duel.LastChainPlayer == -1) && DefaultTrap();
} }
/// <summary> /// <summary>
/// Activate only except we summon monsters. /// Activate only except we summon monsters.
/// </summary> /// </summary>
protected bool DefaultSolemnStrike() protected bool DefaultSolemnStrike()
{ {
return (Bot.LifePoints > 1500) && !(Duel.Player == 0 && Duel.LastChainPlayer == -1) && DefaultTrap(); return (Bot.LifePoints > 1500) && !(Duel.Player == 0 && Duel.LastChainPlayer == -1) && DefaultTrap();
} }
/// <summary> /// <summary>
/// Activate when all enemy monsters have better ATK. /// Activate when all enemy monsters have better ATK.
/// </summary> /// </summary>
protected bool DefaultTorrentialTribute() protected bool DefaultTorrentialTribute()
{ {
return !Util.HasChainedTrap(0) && Util.IsAllEnemyBetter(true); return !Util.HasChainedTrap(0) && Util.IsAllEnemyBetter(true);
} }
/// <summary> /// <summary>
/// Activate enemy have more S&T. /// Activate enemy have more S&T.
/// </summary> /// </summary>
protected bool DefaultHeavyStorm() protected bool DefaultHeavyStorm()
{ {
return Bot.GetSpellCount() < Enemy.GetSpellCount(); return Bot.GetSpellCount() < Enemy.GetSpellCount();
} }
/// <summary> /// <summary>
/// Activate before other winds, if enemy have more than 2 S&T. /// Activate before other winds, if enemy have more than 2 S&T.
/// </summary> /// </summary>
protected bool DefaultHarpiesFeatherDusterFirst() protected bool DefaultHarpiesFeatherDusterFirst()
{ {
return Enemy.GetSpellCount() >= 2; return Enemy.GetSpellCount() >= 2;
} }
/// <summary> /// <summary>
/// Activate when one enemy monsters have better ATK. /// Activate when one enemy monsters have better ATK.
/// </summary> /// </summary>
protected bool DefaultHammerShot() protected bool DefaultHammerShot()
{ {
return Util.IsOneEnemyBetter(true); return Util.IsOneEnemyBetter(true);
} }
/// <summary> /// <summary>
/// Activate when one enemy monsters have better ATK or DEF. /// Activate when one enemy monsters have better ATK or DEF.
/// </summary> /// </summary>
protected bool DefaultDarkHole() protected bool DefaultDarkHole()
{ {
return Util.IsOneEnemyBetter(); return Util.IsOneEnemyBetter();
} }
/// <summary> /// <summary>
/// Activate when one enemy monsters have better ATK or DEF. /// Activate when one enemy monsters have better ATK or DEF.
/// </summary> /// </summary>
protected bool DefaultRaigeki() protected bool DefaultRaigeki()
{ {
return Util.IsOneEnemyBetter(); return Util.IsOneEnemyBetter();
} }
/// <summary> /// <summary>
/// Activate when one enemy monsters have better ATK or DEF. /// Activate when one enemy monsters have better ATK or DEF.
/// </summary> /// </summary>
protected bool DefaultSmashingGround() protected bool DefaultSmashingGround()
{ {
return Util.IsOneEnemyBetter(); return Util.IsOneEnemyBetter();
} }
/// <summary> /// <summary>
/// Activate when we have more than 15 cards in deck. /// Activate when we have more than 15 cards in deck.
/// </summary> /// </summary>
protected bool DefaultPotOfDesires() protected bool DefaultPotOfDesires()
{ {
return Bot.Deck.Count > 15; return Bot.Deck.Count > 15;
} }
/// <summary> /// <summary>
/// Set traps only and avoid block the activation of other cards. /// Set traps only and avoid block the activation of other cards.
/// </summary> /// </summary>
protected bool DefaultSpellSet() protected bool DefaultSpellSet()
{ {
return (Card.IsTrap() || Card.HasType(CardType.QuickPlay) || DefaultSpellMustSetFirst()) && Bot.GetSpellCountWithoutField() < 4; return (Card.IsTrap() || Card.HasType(CardType.QuickPlay) || DefaultSpellMustSetFirst()) && Bot.GetSpellCountWithoutField() < 4;
} }
/// <summary> /// <summary>
/// Summon with no tribute, or with tributes ATK lower. /// Summon with no tribute, or with tributes ATK lower.
/// </summary> /// </summary>
protected bool DefaultMonsterSummon() protected bool DefaultMonsterSummon()
{ {
if (Card.Level <= 4) if (Card.Level <= 4)
return true; return true;
//if (!UniqueFaceupMonster()) //if (!UniqueFaceupMonster())
// return false; // return false;
int tributecount = (int)Math.Ceiling((Card.Level - 4.0d) / 2.0d); int tributecount = (int)Math.Ceiling((Card.Level - 4.0d) / 2.0d);
for (int j = 0; j < 7; ++j) for (int j = 0; j < 7; ++j)
{ {
ClientCard tributeCard = Bot.MonsterZone[j]; ClientCard tributeCard = Bot.MonsterZone[j];
if (tributeCard == null) continue; if (tributeCard == null) continue;
// if (tributeCard.GetDefensePower() +400 < Card.Attack) // if (tributeCard.GetDefensePower() +400 < Card.Attack)
if (tributeCard.Level +1 < Card.Level) if ((tributeCard.Level +1) < Card.Level)
tributecount--; tributecount--;
} }
return tributecount <= 0; return tributecount <= 0;
} }
/// <summary> /// <summary>
/// Activate when we have no field. /// Activate when we have no field.
/// </summary> /// </summary>
protected bool DefaultField() protected bool DefaultField()
{ {
return Bot.SpellZone[5] == null; return Bot.SpellZone[5] == null;
} }
/// <summary> /// <summary>
/// Turn if all enemy is better. /// Turn if all enemy is better.
/// </summary> /// </summary>
protected bool DefaultMonsterRepos() protected bool DefaultMonsterRepos()
{ {
if (Card.IsMonsterInvincible()) if (Card.IsMonsterInvincible())
return Card.IsDefense(); return Card.IsDefense();
if (Card.Attack == 0) if (Card.Attack == 0)
{ {
if (Card.IsFaceup() && Card.IsAttack()) if (Card.IsFaceup() && Card.IsAttack())
return true; return true;
if (Card.IsFaceup() && Card.IsDefense()) if (Card.IsFaceup() && Card.IsDefense())
return false; return false;
} }
if (Enemy.HasInMonstersZone(_CardId.BlueEyesChaosMAXDragon, true) && if (Enemy.HasInMonstersZone(_CardId.BlueEyesChaosMAXDragon, true) &&
Card.IsAttack() && (4000 - Card.Defense) * 2 > (4000 - Card.Attack)) Card.IsAttack() && (4000 - Card.Defense) * 2 > (4000 - Card.Attack))
return false; return false;
if (Enemy.HasInMonstersZone(_CardId.BlueEyesChaosMAXDragon, true) && if (Enemy.HasInMonstersZone(_CardId.BlueEyesChaosMAXDragon, true) &&
Card.IsDefense() && Card.IsFaceup() && Card.IsDefense() && Card.IsFaceup() &&
(4000 - Card.Defense) * 2 > (4000 - Card.Attack)) (4000 - Card.Defense) * 2 > (4000 - Card.Attack))
return true; return true;
bool enemyBetter = Util.IsAllEnemyBetter(); bool enemyBetter = Util.IsAllEnemyBetter();
if (Card.IsAttack() && enemyBetter) if (Card.IsAttack() && enemyBetter)
return true; return true;
if (Card.IsDefense() && !enemyBetter && (Card.Attack >= Card.Defense || Card.Attack >= Util.GetBestPower(Enemy))) if (Card.IsDefense() && !enemyBetter && (Card.Attack >= Card.Defense || Card.Attack >= Util.GetBestPower(Enemy)))
return true; return true;
return false; return false;
} }
/// <summary> /// <summary>
/// If spell will be negated /// If spell will be negated
/// </summary> /// </summary>
protected bool DefaultSpellWillBeNegated() protected bool DefaultSpellWillBeNegated()
{ {
return (Bot.HasInSpellZone(_CardId.ImperialOrder, true, true) || Enemy.HasInSpellZone(_CardId.ImperialOrder, true)) && !Util.ChainContainsCard(_CardId.ImperialOrder); return (Bot.HasInSpellZone(_CardId.ImperialOrder, true, true) || Enemy.HasInSpellZone(_CardId.ImperialOrder, true)) && !Util.ChainContainsCard(_CardId.ImperialOrder);
} }
/// <summary> /// <summary>
/// If trap will be negated /// If trap will be negated
/// </summary> /// </summary>
protected bool DefaultTrapWillBeNegated() protected bool DefaultTrapWillBeNegated()
{ {
return (Bot.HasInSpellZone(_CardId.RoyalDecreel, true, true) || Enemy.HasInSpellZone(_CardId.RoyalDecreel, true)) && !Util.ChainContainsCard(_CardId.RoyalDecreel); return (Bot.HasInSpellZone(_CardId.RoyalDecreel, true, true) || Enemy.HasInSpellZone(_CardId.RoyalDecreel, true)) && !Util.ChainContainsCard(_CardId.RoyalDecreel);
} }
/// <summary> /// <summary>
/// If spell must set first to activate /// If spell must set first to activate
/// </summary> /// </summary>
protected bool DefaultSpellMustSetFirst() protected bool DefaultSpellMustSetFirst()
{ {
return Bot.HasInSpellZone(_CardId.AntiSpellFragrance, true, true) || Enemy.HasInSpellZone(_CardId.AntiSpellFragrance, true); return Bot.HasInSpellZone(_CardId.AntiSpellFragrance, true, true) || Enemy.HasInSpellZone(_CardId.AntiSpellFragrance, true);
} }
/// <summary> /// <summary>
/// if spell/trap is the target or enermy activate HarpiesFeatherDuster /// if spell/trap is the target or enermy activate HarpiesFeatherDuster
/// </summary> /// </summary>
protected bool DefaultOnBecomeTarget() protected bool DefaultOnBecomeTarget()
{ {
if (Util.IsChainTarget(Card)) return true; if (Util.IsChainTarget(Card)) return true;
int[] destroyAllList = int[] destroyAllList =
{ {
_CardId.EvilswarmExcitonKnight, _CardId.EvilswarmExcitonKnight,
_CardId.BlackRoseDragon, _CardId.BlackRoseDragon,
_CardId.JudgmentDragon, _CardId.JudgmentDragon,
_CardId.TopologicTrisbaena _CardId.TopologicTrisbaena
}; };
int[] destroyAllOpponentList = int[] destroyAllOpponentList =
{ {
_CardId.HarpiesFeatherDuster, _CardId.HarpiesFeatherDuster,
_CardId.DarkMagicAttack _CardId.DarkMagicAttack
}; };
if (Util.ChainContainsCard(destroyAllList)) return true; if (Util.ChainContainsCard(destroyAllList)) return true;
if (Enemy.HasInSpellZone(destroyAllOpponentList, true)) return true; if (Enemy.HasInSpellZone(destroyAllOpponentList, true)) return true;
// TODO: ChainContainsCard(id, player) // TODO: ChainContainsCard(id, player)
return false; return false;
} }
/// <summary> /// <summary>
/// Chain enemy activation or summon. /// Chain enemy activation or summon.
/// </summary> /// </summary>
protected bool DefaultTrap() protected bool DefaultTrap()
{ {
return (Duel.LastChainPlayer == -1 && Duel.LastSummonPlayer != 0) || Duel.LastChainPlayer == 1; return (Duel.LastChainPlayer == -1 && Duel.LastSummonPlayer != 0) || Duel.LastChainPlayer == 1;
} }
/// <summary> /// <summary>
/// Activate when avail and no other our trap card in this chain or face-up. /// Activate when avail and no other our trap card in this chain or face-up.
/// </summary> /// </summary>
protected bool DefaultUniqueTrap() protected bool DefaultUniqueTrap()
{ {
if (Util.HasChainedTrap(0)) if (Util.HasChainedTrap(0))
return false; return false;
return UniqueFaceupSpell(); return UniqueFaceupSpell();
} }
/// <summary> /// <summary>
/// Check no other our spell or trap card with same name face-up. /// Check no other our spell or trap card with same name face-up.
/// </summary> /// </summary>
protected bool UniqueFaceupSpell() protected bool UniqueFaceupSpell()
{ {
return !Bot.GetSpells().Any(card => card.IsCode(Card.Id) && card.IsFaceup()); return !Bot.GetSpells().Any(card => card.IsCode(Card.Id) && card.IsFaceup());
} }
/// <summary> /// <summary>
/// Check no other our monster card with same name face-up. /// Check no other our monster card with same name face-up.
/// </summary> /// </summary>
protected bool UniqueFaceupMonster() protected bool UniqueFaceupMonster()
{ {
return !Bot.GetMonsters().Any(card => card.IsCode(Card.Id) && card.IsFaceup()); return !Bot.GetMonsters().Any(card => card.IsCode(Card.Id) && card.IsFaceup());
} }
/// <summary> /// <summary>
/// Dumb way to avoid the bot chain in mess. /// Dumb way to avoid the bot chain in mess.
/// </summary> /// </summary>
protected bool DefaultDontChainMyself() protected bool DefaultDontChainMyself()
{ {
if (Type != ExecutorType.Activate) if (Type != ExecutorType.Activate)
return true; return true;
if (Executors.Any(exec => exec.Type == Type && exec.CardId == Card.Id)) if (Executors.Any(exec => exec.Type == Type && exec.CardId == Card.Id))
return false; return false;
return Duel.LastChainPlayer != 0; return Duel.LastChainPlayer != 0;
} }
/// <summary> /// <summary>
/// Draw when we have lower LP, or destroy it. Can be overrided. /// Draw when we have lower LP, or destroy it. Can be overrided.
/// </summary> /// </summary>
protected bool DefaultChickenGame() protected bool DefaultChickenGame()
{ {
if (Executors.Count(exec => exec.Type == Type && exec.CardId == Card.Id) > 1) if (Executors.Count(exec => exec.Type == Type && exec.CardId == Card.Id) > 1)
return false; return false;
if (Card.IsFacedown()) if (Card.IsFacedown())
return true; return true;
if (Bot.LifePoints <= 1000) if (Bot.LifePoints <= 1000)
return false; return false;
if (Bot.LifePoints <= Enemy.LifePoints && ActivateDescription == Util.GetStringId(_CardId.ChickenGame, 0)) if (Bot.LifePoints <= Enemy.LifePoints && ActivateDescription == Util.GetStringId(_CardId.ChickenGame, 0))
return true; return true;
if (Bot.LifePoints > Enemy.LifePoints && ActivateDescription == Util.GetStringId(_CardId.ChickenGame, 1)) if (Bot.LifePoints > Enemy.LifePoints && ActivateDescription == Util.GetStringId(_CardId.ChickenGame, 1))
return true; return true;
return false; return false;
} }
/// <summary> /// <summary>
/// Draw when we have Dark monster in hand,and banish random one. Can be overrided. /// Draw when we have Dark monster in hand,and banish random one. Can be overrided.
/// </summary> /// </summary>
protected bool DefaultAllureofDarkness() protected bool DefaultAllureofDarkness()
{ {
ClientCard target = Bot.Hand.FirstOrDefault(card => card.HasAttribute(CardAttribute.Dark)); ClientCard target = Bot.Hand.FirstOrDefault(card => card.HasAttribute(CardAttribute.Dark));
return target != null; return target != null;
} }
/// <summary> /// <summary>
/// Clever enough. /// Clever enough.
/// </summary> /// </summary>
protected bool DefaultDimensionalBarrier() protected bool DefaultDimensionalBarrier()
{ {
const int RITUAL = 0; const int RITUAL = 0;
const int FUSION = 1; const int FUSION = 1;
const int SYNCHRO = 2; const int SYNCHRO = 2;
const int XYZ = 3; const int XYZ = 3;
const int PENDULUM = 4; const int PENDULUM = 4;
if (Duel.Player != 0) if (Duel.Player != 0)
{ {
List<ClientCard> monsters = Enemy.GetMonsters(); List<ClientCard> monsters = Enemy.GetMonsters();
int[] levels = new int[13]; int[] levels = new int[13];
bool tuner = false; bool tuner = false;
bool nontuner = false; bool nontuner = false;
foreach (ClientCard monster in monsters) foreach (ClientCard monster in monsters)
{ {
if (monster.HasType(CardType.Tuner)) if (monster.HasType(CardType.Tuner))
tuner = true; tuner = true;
else if (!monster.HasType(CardType.Xyz) && !monster.HasType(CardType.Link)) else if (!monster.HasType(CardType.Xyz) && !monster.HasType(CardType.Link))
{ {
nontuner = true; nontuner = true;
levels[monster.Level] = levels[monster.Level] + 1; levels[monster.Level] = levels[monster.Level] + 1;
} }
if (monster.IsOneForXyz()) if (monster.IsOneForXyz())
{ {
AI.SelectOption(XYZ); AI.SelectOption(XYZ);
return true; return true;
} }
} }
if (tuner && nontuner) if (tuner && nontuner)
{ {
AI.SelectOption(SYNCHRO); AI.SelectOption(SYNCHRO);
return true; return true;
} }
for (int i=1; i<=12; i++) for (int i=1; i<=12; i++)
{ {
if (levels[i]>1) if (levels[i]>1)
{ {
AI.SelectOption(XYZ); AI.SelectOption(XYZ);
return true; return true;
} }
} }
ClientCard l = Enemy.SpellZone[6]; ClientCard l = Enemy.SpellZone[6];
ClientCard r = Enemy.SpellZone[7]; ClientCard r = Enemy.SpellZone[7];
if (l != null && r != null && l.LScale != r.RScale) if (l != null && r != null && l.LScale != r.RScale)
{ {
AI.SelectOption(PENDULUM); AI.SelectOption(PENDULUM);
return true; return true;
} }
} }
ClientCard lastchaincard = Util.GetLastChainCard(); ClientCard lastchaincard = Util.GetLastChainCard();
if (Duel.LastChainPlayer == 1 && lastchaincard != null && !lastchaincard.IsDisabled()) if (Duel.LastChainPlayer == 1 && lastchaincard != null && !lastchaincard.IsDisabled())
{ {
if (lastchaincard.HasType(CardType.Ritual)) if (lastchaincard.HasType(CardType.Ritual))
{ {
AI.SelectOption(RITUAL); AI.SelectOption(RITUAL);
return true; return true;
} }
if (lastchaincard.HasType(CardType.Fusion)) if (lastchaincard.HasType(CardType.Fusion))
{ {
AI.SelectOption(FUSION); AI.SelectOption(FUSION);
return true; return true;
} }
if (lastchaincard.HasType(CardType.Synchro)) if (lastchaincard.HasType(CardType.Synchro))
{ {
AI.SelectOption(SYNCHRO); AI.SelectOption(SYNCHRO);
return true; return true;
} }
if (lastchaincard.HasType(CardType.Xyz)) if (lastchaincard.HasType(CardType.Xyz))
{ {
AI.SelectOption(XYZ); AI.SelectOption(XYZ);
return true; return true;
} }
if (lastchaincard.IsFusionSpell()) if (lastchaincard.IsFusionSpell())
{ {
AI.SelectOption(FUSION); AI.SelectOption(FUSION);
return true; return true;
} }
} }
if (Util.IsChainTarget(Card)) if (Util.IsChainTarget(Card))
{ {
AI.SelectOption(XYZ); AI.SelectOption(XYZ);
return true; return true;
} }
return false; return false;
} }
/// <summary> /// <summary>
/// Clever enough /// Clever enough
/// </summary> /// </summary>
protected bool DefaultInterruptedKaijuSlumber() protected bool DefaultInterruptedKaijuSlumber()
{ {
if (Card.Location == CardLocation.Grave) if (Card.Location == CardLocation.Grave)
{ {
AI.SelectCard( AI.SelectCard(
_CardId.GamecieltheSeaTurtleKaiju, _CardId.GamecieltheSeaTurtleKaiju,
_CardId.KumongoustheStickyStringKaiju, _CardId.KumongoustheStickyStringKaiju,
_CardId.GadarlatheMysteryDustKaiju, _CardId.GadarlatheMysteryDustKaiju,
_CardId.RadiantheMultidimensionalKaiju, _CardId.RadiantheMultidimensionalKaiju,
_CardId.DogorantheMadFlameKaiju, _CardId.DogorantheMadFlameKaiju,
_CardId.ThunderKingtheLightningstrikeKaiju, _CardId.ThunderKingtheLightningstrikeKaiju,
_CardId.JizukirutheStarDestroyingKaiju _CardId.JizukirutheStarDestroyingKaiju
); );
return true; return true;
} }
if (DefaultDarkHole()) if (DefaultDarkHole())
{ {
AI.SelectCard( AI.SelectCard(
_CardId.JizukirutheStarDestroyingKaiju, _CardId.JizukirutheStarDestroyingKaiju,
_CardId.ThunderKingtheLightningstrikeKaiju, _CardId.ThunderKingtheLightningstrikeKaiju,
_CardId.DogorantheMadFlameKaiju, _CardId.DogorantheMadFlameKaiju,
_CardId.RadiantheMultidimensionalKaiju, _CardId.RadiantheMultidimensionalKaiju,
_CardId.GadarlatheMysteryDustKaiju, _CardId.GadarlatheMysteryDustKaiju,
_CardId.KumongoustheStickyStringKaiju, _CardId.KumongoustheStickyStringKaiju,
_CardId.GamecieltheSeaTurtleKaiju _CardId.GamecieltheSeaTurtleKaiju
); );
AI.SelectNextCard( AI.SelectNextCard(
_CardId.SuperAntiKaijuWarMachineMechaDogoran, _CardId.SuperAntiKaijuWarMachineMechaDogoran,
_CardId.GamecieltheSeaTurtleKaiju, _CardId.GamecieltheSeaTurtleKaiju,
_CardId.KumongoustheStickyStringKaiju, _CardId.KumongoustheStickyStringKaiju,
_CardId.GadarlatheMysteryDustKaiju, _CardId.GadarlatheMysteryDustKaiju,
_CardId.RadiantheMultidimensionalKaiju, _CardId.RadiantheMultidimensionalKaiju,
_CardId.DogorantheMadFlameKaiju, _CardId.DogorantheMadFlameKaiju,
_CardId.ThunderKingtheLightningstrikeKaiju _CardId.ThunderKingtheLightningstrikeKaiju
); );
return true; return true;
} }
return false; return false;
} }
/// <summary> /// <summary>
/// Clever enough. /// Clever enough.
/// </summary> /// </summary>
protected bool DefaultKaijuSpsummon() protected bool DefaultKaijuSpsummon()
{ {
IList<int> kaijus = new[] { IList<int> kaijus = new[] {
_CardId.JizukirutheStarDestroyingKaiju, _CardId.JizukirutheStarDestroyingKaiju,
_CardId.GadarlatheMysteryDustKaiju, _CardId.GadarlatheMysteryDustKaiju,
_CardId.GamecieltheSeaTurtleKaiju, _CardId.GamecieltheSeaTurtleKaiju,
_CardId.RadiantheMultidimensionalKaiju, _CardId.RadiantheMultidimensionalKaiju,
_CardId.KumongoustheStickyStringKaiju, _CardId.KumongoustheStickyStringKaiju,
_CardId.ThunderKingtheLightningstrikeKaiju, _CardId.ThunderKingtheLightningstrikeKaiju,
_CardId.DogorantheMadFlameKaiju, _CardId.DogorantheMadFlameKaiju,
_CardId.SuperAntiKaijuWarMachineMechaDogoran _CardId.SuperAntiKaijuWarMachineMechaDogoran
}; };
foreach (ClientCard monster in Enemy.GetMonsters()) foreach (ClientCard monster in Enemy.GetMonsters())
{ {
if (monster.IsCode(kaijus)) if (monster.IsCode(kaijus))
return Card.GetDefensePower() > monster.GetDefensePower(); return Card.GetDefensePower() > monster.GetDefensePower();
} }
ClientCard card = Enemy.MonsterZone.GetFloodgate(); ClientCard card = Enemy.MonsterZone.GetFloodgate();
if (card != null) if (card != null)
{ {
AI.SelectCard(card); AI.SelectCard(card);
return true; return true;
} }
card = Enemy.MonsterZone.GetDangerousMonster(); card = Enemy.MonsterZone.GetDangerousMonster();
if (card != null) if (card != null)
{ {
AI.SelectCard(card); AI.SelectCard(card);
return true; return true;
} }
card = Util.GetOneEnemyBetterThanValue(Card.GetDefensePower()); card = Util.GetOneEnemyBetterThanValue(Card.GetDefensePower());
if (card != null) if (card != null)
{ {
AI.SelectCard(card); AI.SelectCard(card);
return true; return true;
} }
return false; return false;
} }
/// <summary> /// <summary>
/// Summon when we don't have monster attack higher than enemy's. /// Summon when we don't have monster attack higher than enemy's.
/// </summary> /// </summary>
protected bool DefaultNumberS39UtopiaTheLightningSummon() protected bool DefaultNumberS39UtopiaTheLightningSummon()
{ {
int bestBotAttack = Util.GetBestAttack(Bot); int bestBotAttack = Util.GetBestAttack(Bot);
return Util.IsOneEnemyBetterThanValue(bestBotAttack, false); return Util.IsOneEnemyBetterThanValue(bestBotAttack, false);
} }
/// <summary> /// <summary>
/// Activate if the card is attack pos, and its attack is below 5000, when the enemy monster is attack pos or not useless faceup defense pos /// Activate if the card is attack pos, and its attack is below 5000, when the enemy monster is attack pos or not useless faceup defense pos
/// </summary> /// </summary>
protected bool DefaultNumberS39UtopiaTheLightningEffect() protected bool DefaultNumberS39UtopiaTheLightningEffect()
{ {
return Card.IsAttack() && Card.Attack < 5000 && (Enemy.BattlingMonster.IsAttack() || Enemy.BattlingMonster.IsFacedown() || Enemy.BattlingMonster.GetDefensePower() >= Card.Attack); return Card.IsAttack() && Card.Attack < 5000 && (Enemy.BattlingMonster.IsAttack() || Enemy.BattlingMonster.IsFacedown() || Enemy.BattlingMonster.GetDefensePower() >= Card.Attack);
} }
/// <summary> /// <summary>
/// Summon when it can and should use effect. /// Summon when it can and should use effect.
/// </summary> /// </summary>
protected bool DefaultEvilswarmExcitonKnightSummon() protected bool DefaultEvilswarmExcitonKnightSummon()
{ {
int selfCount = Bot.GetMonsterCount() + Bot.GetSpellCount() + Bot.GetHandCount(); int selfCount = Bot.GetMonsterCount() + Bot.GetSpellCount() + Bot.GetHandCount();
int oppoCount = Enemy.GetMonsterCount() + Enemy.GetSpellCount() + Enemy.GetHandCount(); int oppoCount = Enemy.GetMonsterCount() + Enemy.GetSpellCount() + Enemy.GetHandCount();
return (selfCount - 1 < oppoCount) && DefaultEvilswarmExcitonKnightEffect(); return (selfCount - 1 < oppoCount) && DefaultEvilswarmExcitonKnightEffect();
} }
/// <summary> /// <summary>
/// Activate when we have less cards than enemy's, or the atk sum of we is lower than enemy's. /// Activate when we have less cards than enemy's, or the atk sum of we is lower than enemy's.
/// </summary> /// </summary>
protected bool DefaultEvilswarmExcitonKnightEffect() protected bool DefaultEvilswarmExcitonKnightEffect()
{ {
int selfCount = Bot.GetMonsterCount() + Bot.GetSpellCount(); int selfCount = Bot.GetMonsterCount() + Bot.GetSpellCount();
int oppoCount = Enemy.GetMonsterCount() + Enemy.GetSpellCount(); int oppoCount = Enemy.GetMonsterCount() + Enemy.GetSpellCount();
if (selfCount < oppoCount) if (selfCount < oppoCount)
return true; return true;
int selfAttack = Bot.GetMonsters().Sum(monster => (int?)monster.GetDefensePower()) ?? 0; int selfAttack = Bot.GetMonsters().Sum(monster => (int?)monster.GetDefensePower()) ?? 0;
int oppoAttack = Enemy.GetMonsters().Sum(monster => (int?)monster.GetDefensePower()) ?? 0; int oppoAttack = Enemy.GetMonsters().Sum(monster => (int?)monster.GetDefensePower()) ?? 0;
return selfAttack < oppoAttack; return selfAttack < oppoAttack;
} }
/// <summary> /// <summary>
/// Summon in main2, or when the attack of we is lower than enemy's, but not when enemy have monster higher than 2500. /// Summon in main2, or when the attack of we is lower than enemy's, but not when enemy have monster higher than 2500.
/// </summary> /// </summary>
protected bool DefaultStardustDragonSummon() protected bool DefaultStardustDragonSummon()
{ {
int selfBestAttack = Util.GetBestAttack(Bot); int selfBestAttack = Util.GetBestAttack(Bot);
int oppoBestAttack = Util.GetBestPower(Enemy); int oppoBestAttack = Util.GetBestPower(Enemy);
return (selfBestAttack <= oppoBestAttack && oppoBestAttack <= 2500) || Util.IsTurn1OrMain2(); return (selfBestAttack <= oppoBestAttack && oppoBestAttack <= 2500) || Util.IsTurn1OrMain2();
} }
/// <summary> /// <summary>
/// Negate enemy's destroy effect, and revive from grave. /// Negate enemy's destroy effect, and revive from grave.
/// </summary> /// </summary>
protected bool DefaultStardustDragonEffect() protected bool DefaultStardustDragonEffect()
{ {
return (Card.Location == CardLocation.Grave) || Duel.LastChainPlayer == 1; return (Card.Location == CardLocation.Grave) || Duel.LastChainPlayer == 1;
} }
/// <summary> /// <summary>
/// Summon when enemy have card which we must solve. /// Summon when enemy have card which we must solve.
/// </summary> /// </summary>
protected bool DefaultCastelTheSkyblasterMusketeerSummon() protected bool DefaultCastelTheSkyblasterMusketeerSummon()
{ {
return Util.GetProblematicEnemyCard() != null; return Util.GetProblematicEnemyCard() != null;
} }
/// <summary> /// <summary>
/// Bounce the problematic enemy card. Ignore the 1st effect. /// Bounce the problematic enemy card. Ignore the 1st effect.
/// </summary> /// </summary>
protected bool DefaultCastelTheSkyblasterMusketeerEffect() protected bool DefaultCastelTheSkyblasterMusketeerEffect()
{ {
if (ActivateDescription == Util.GetStringId(_CardId.CastelTheSkyblasterMusketeer, 0)) if (ActivateDescription == Util.GetStringId(_CardId.CastelTheSkyblasterMusketeer, 0))
return false; return false;
ClientCard target = Util.GetProblematicEnemyCard(); ClientCard target = Util.GetProblematicEnemyCard();
if (target != null) if (target != null)
{ {
AI.SelectCard(0); AI.SelectCard(0);
AI.SelectNextCard(target); AI.SelectNextCard(target);
return true; return true;
} }
return false; return false;
} }
/// <summary> /// <summary>
/// Summon when it should use effect, or when the attack of we is lower than enemy's, but not when enemy have monster higher than 3000. /// Summon when it should use effect, or when the attack of we is lower than enemy's, but not when enemy have monster higher than 3000.
/// </summary> /// </summary>
protected bool DefaultScarlightRedDragonArchfiendSummon() protected bool DefaultScarlightRedDragonArchfiendSummon()
{ {
int selfBestAttack = Util.GetBestAttack(Bot); int selfBestAttack = Util.GetBestAttack(Bot);
int oppoBestAttack = Util.GetBestPower(Enemy); int oppoBestAttack = Util.GetBestPower(Enemy);
return (selfBestAttack <= oppoBestAttack && oppoBestAttack <= 3000) || DefaultScarlightRedDragonArchfiendEffect(); return (selfBestAttack <= oppoBestAttack && oppoBestAttack <= 3000) || DefaultScarlightRedDragonArchfiendEffect();
} }
protected bool DefaultTimelordSummon() protected bool DefaultTimelordSummon()
{ {
return Bot.GetMonsterCount() == 0; return Bot.GetMonsterCount() == 0;
} }
/// <summary> /// <summary>
/// Activate when we have less monsters than enemy, or when enemy have more than 3 monsters. /// Activate when we have less monsters than enemy, or when enemy have more than 3 monsters.
/// </summary> /// </summary>
protected bool DefaultScarlightRedDragonArchfiendEffect() protected bool DefaultScarlightRedDragonArchfiendEffect()
{ {
int selfCount = Bot.GetMonsters().Count(monster => !monster.Equals(Card) && monster.IsSpecialSummoned && monster.HasType(CardType.Effect) && monster.Attack <= Card.Attack); int selfCount = Bot.GetMonsters().Count(monster => !monster.Equals(Card) && monster.IsSpecialSummoned && monster.HasType(CardType.Effect) && monster.Attack <= Card.Attack);
int oppoCount = Enemy.GetMonsters().Count(monster => monster.IsSpecialSummoned && monster.HasType(CardType.Effect) && monster.Attack <= Card.Attack); int oppoCount = Enemy.GetMonsters().Count(monster => monster.IsSpecialSummoned && monster.HasType(CardType.Effect) && monster.Attack <= Card.Attack);
return selfCount <= oppoCount && oppoCount > 0 || oppoCount >= 3; return selfCount <= oppoCount && oppoCount > 0 || oppoCount >= 3;
} }
/// <summary> /// <summary>
/// Clever enough. /// Clever enough.
/// </summary> /// </summary>
protected bool DefaultHonestEffect() protected bool DefaultHonestEffect()
{ {
if (Card.Location == CardLocation.Hand) if (Card.Location == CardLocation.Hand)
{ {
return Bot.BattlingMonster.IsAttack() && return Bot.BattlingMonster.IsAttack() &&
(((Bot.BattlingMonster.Attack < Enemy.BattlingMonster.Attack) || Bot.BattlingMonster.Attack >= Enemy.LifePoints) (((Bot.BattlingMonster.Attack < Enemy.BattlingMonster.Attack) || Bot.BattlingMonster.Attack >= Enemy.LifePoints)
|| ((Bot.BattlingMonster.Attack < Enemy.BattlingMonster.Defense) && (Bot.BattlingMonster.Attack + Enemy.BattlingMonster.Attack > Enemy.BattlingMonster.Defense))); || ((Bot.BattlingMonster.Attack < Enemy.BattlingMonster.Defense) && (Bot.BattlingMonster.Attack + Enemy.BattlingMonster.Attack > Enemy.BattlingMonster.Defense)));
} }
return Util.IsTurn1OrMain2(); return Util.IsTurn1OrMain2();
} }
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment