feat(battle-engine): M1 auto-copy closure (782 battle-logic files)
Compile-driven bulk-copy loop (tools/engine-port/m1_copy_loop.py) pulled the precise reference closure of the battle-core roots, stopping at the classify god-object/View-VFX-UI boundary. 782 files; no re-explosion (M0 had estimated ~order 1000). Residual frontier = 52 shim-classified + 80 external (Unity/BCL) types to author next.
This commit is contained in:
214
SVSim.BattleEngine/Engine/Wizard/AIEmoteQuery.cs
Normal file
214
SVSim.BattleEngine/Engine/Wizard/AIEmoteQuery.cs
Normal file
@@ -0,0 +1,214 @@
|
||||
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<int> _previousEmoteQueue;
|
||||
|
||||
private Queue<int> _previousPlayerEmoteQueue;
|
||||
|
||||
private Dictionary<int, int> _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<int>(3);
|
||||
_previousPlayerEmoteQueue = new Queue<int>(3);
|
||||
_categoryIntervalDic = new Dictionary<int, int>();
|
||||
}
|
||||
|
||||
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<int>(_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<AIEmoteCmd> 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<int> 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<AIEmoteCmd> 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<AIEmoteCmd> FilterEmoteByPreviousPlayed(IEnumerable<AIEmoteCmd> emoteCmds, bool isAlly)
|
||||
{
|
||||
IList<AIEmoteCmd> list = new List<AIEmoteCmd>();
|
||||
Queue<int> 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user