using System.Collections.Generic; using System.Linq; namespace Wizard; public class AIEmoteQuery { public enum Category { UnexpectedPlayResult_Good = 1, UnexpectedPlayResult_Bad = 2, LongThinking = 3, UnexpectedBattleResult = 11, ReverseDisAdv = 12, CheckMated = 13, HuntDown = 14, RemainTooPP = 15, SpellBanishOverExpected = 21, FatalAttack = 22, OpponentRemainTooPP = 31, OpponentReverseDisAdvFail = 32, OpponentGetGreatMerit = 33, OpponentPlayGiant = 34, OpponentBanishSpell_Good = 35, OpponentBanishSpell_Bad = 36, OpponentWellHealing = 37, EliminatedAllyLegion = 101, EnoughUnit = 102, Awake = 401, EnoughGrave = 501 } private EnemyAI enemyAI; private bool _isActivate = true; private AIEmoteSet _curEmoteSet; private bool _emotePermission; private bool _useInnerEmote; private Queue _previousEmoteQueue; private Queue _previousPlayerEmoteQueue; private Dictionary _categoryIntervalDic; private const int EMOTE_QUEUE_LENGTH = 3; public bool UseInnerEmote => _useInnerEmote; public AIEmoteQuery(EnemyAI ai) { enemyAI = ai; _emotePermission = true; _useInnerEmote = false; _previousEmoteQueue = new Queue(3); _previousPlayerEmoteQueue = new Queue(3); _categoryIntervalDic = new Dictionary(); } public void SetOnOffEmote(bool isActivate, bool useInnerEmote) { _isActivate = isActivate; _useInnerEmote = useInnerEmote; } public void SetEmoteSet(AIEmoteSet emoteSet) { _curEmoteSet = emoteSet; } public void UpdateCategoryInterval() { foreach (int item in new List(_categoryIntervalDic.Keys)) { int num = _categoryIntervalDic[item]; if (num > 0) { _categoryIntervalDic[item] = num - 1; } } } public void SetInterval(int emoteKey, int turnCount) { if (_categoryIntervalDic.ContainsKey(emoteKey)) { _categoryIntervalDic[emoteKey] = turnCount; } else { _categoryIntervalDic.Add(emoteKey, turnCount); } } public int GetCategoryInterval(int emoteKey) { if (!_categoryIntervalDic.ContainsKey(emoteKey)) { return 0; } return _categoryIntervalDic[emoteKey]; } public AIEmoteCmd SearchEmoteAtRandom(int emoteKey, bool isAlly = true) { if (!_isActivate) { return null; } if (_curEmoteSet == null) { return null; } if (!_curEmoteSet.EmoteCmds.Any((AIEmoteCmd c) => c.CategoryKey == emoteKey)) { return null; } if (!_emotePermission) { return null; } if (!_useInnerEmote && emoteKey <= 1000) { return null; } AIEmoteCmd aIEmoteCmd = null; IList list = FilterEmoteByPreviousPlayed(_curEmoteSet.EmoteCmds.Where((AIEmoteCmd c) => c.CategoryKey == emoteKey), isAlly); int count = list.Count; if (count <= 0) { return null; } if (count > 1) { int index = enemyAI.AIStableRandom() % count; aIEmoteCmd = list[index]; } else { aIEmoteCmd = list[0]; } if (aIEmoteCmd != null) { Queue queue = (isAlly ? _previousEmoteQueue : _previousPlayerEmoteQueue); if (queue.Count == 3) { queue.Dequeue(); } queue.Enqueue(aIEmoteCmd.ID); aIEmoteCmd.isAI = isAlly; } return aIEmoteCmd; } public AIEmoteCmd SearchEmoteByID(int emoteID) { if (_curEmoteSet == null) { return null; } if (!_curEmoteSet.EmoteCmds.Any((AIEmoteCmd c) => c.ID == emoteID)) { return null; } return _curEmoteSet.EmoteCmds.First((AIEmoteCmd c) => c.ID == emoteID); } public IEnumerable SearchEmoteByCategory(int emoteCategory) { if (_curEmoteSet == null) { return null; } if (!_curEmoteSet.EmoteCmds.Any((AIEmoteCmd c) => c.CategoryKey == emoteCategory)) { return null; } return _curEmoteSet.EmoteCmds.Where((AIEmoteCmd c) => c.CategoryKey == emoteCategory); } public void OnOperation() { _emotePermission = true; } public void OnCardPlayEmotion() { _emotePermission = false; } private IList FilterEmoteByPreviousPlayed(IEnumerable emoteCmds, bool isAlly) { IList list = new List(); Queue queue = (isAlly ? _previousEmoteQueue : _previousPlayerEmoteQueue); foreach (AIEmoteCmd emoteCmd in emoteCmds) { if (queue.Contains(emoteCmd.ID)) { if (enemyAI.AIStableRandom() % 4 == 0) { list.Add(emoteCmd); } } else { list.Add(emoteCmd); } } return list; } }