129 lines
4.8 KiB
C#
129 lines
4.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using BrewMonster.Config;
|
|
using BrewMonster.Scripts;
|
|
using BrewMonster.Scripts.Skills;
|
|
|
|
namespace BrewMonster
|
|
{
|
|
/// <summary>
|
|
/// Resolves visible-state ids for anim-test (skill_state_action + name fallback) and applies ext-state bits locally (no server).
|
|
/// </summary>
|
|
public static class SkillVisibleStateResolver
|
|
{
|
|
const int ExtStateCount = 6;
|
|
const int BitSize = 32;
|
|
|
|
public static List<int> ResolveVisibleStateIds(int skillId)
|
|
{
|
|
var ids = new HashSet<int>();
|
|
|
|
if (CECAttacksMan.Instance != null &&
|
|
CECAttacksMan.Instance.TryGetSkillStateActions(skillId, out IReadOnlyList<SkillStateActionRow> rows))
|
|
{
|
|
for (int i = 0; i < rows.Count; i++)
|
|
ids.Add(rows[i].state);
|
|
}
|
|
|
|
SkillStub stub = SkillStub.GetStub((uint)skillId);
|
|
if (stub != null && !string.IsNullOrEmpty(stub.name))
|
|
{
|
|
foreach (KeyValuePair<int, VisibleStateImp> kv in GNET.VisibleState)
|
|
{
|
|
string visibleName = kv.Value?.GetName();
|
|
if (string.IsNullOrEmpty(visibleName))
|
|
continue;
|
|
|
|
if (string.Equals(visibleName, stub.name, StringComparison.Ordinal) ||
|
|
string.Equals(visibleName, stub.nativename, StringComparison.Ordinal))
|
|
ids.Add(kv.Key);
|
|
}
|
|
}
|
|
|
|
return new List<int>(ids);
|
|
}
|
|
|
|
public static bool TryGetConfigRows(int skillId, out IReadOnlyList<SkillStateActionRow> rows)
|
|
{
|
|
rows = null;
|
|
return CECAttacksMan.Instance != null &&
|
|
CECAttacksMan.Instance.TryGetSkillStateActions(skillId, out rows);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Simulates server UPDATE_EXT_STATE for AnimationTest: sets bits and calls ShowExtendStates via SetNewExtendStates.
|
|
/// </summary>
|
|
public static void TryApplyLocalExtStates(int skillId, CECHostPlayer hostPlayer, CECMonsterTest targetMarker)
|
|
{
|
|
List<int> stateIds = ResolveVisibleStateIds(skillId);
|
|
// #region agent log
|
|
LogPanelAnimeScene.AgentDebugLog("TryApplyLocalExtStates", "resolved state ids", "H4",
|
|
$"{{\"skillId\":{skillId},\"stateIds\":\"{string.Join(",", stateIds)}\",\"targetType\":{GetSkillTargetType((uint)skillId)}}}");
|
|
// #endregion
|
|
|
|
if (stateIds.Count == 0 || hostPlayer == null)
|
|
return;
|
|
|
|
if (!hostPlayer.IsAllResReady() && hostPlayer.IsPlayerModelReady)
|
|
hostPlayer.AnimSceneMarkResourcesReady();
|
|
|
|
uint[] nextStates = BuildExtStates(hostPlayer.m_aExtStates, stateIds);
|
|
int targetType = GetSkillTargetType((uint)skillId);
|
|
|
|
// #region agent log
|
|
LogPanelAnimeScene.AgentDebugLog("TryApplyLocalExtStates:apply", "calling SetNewExtendStates", "H5",
|
|
$"{{\"skillId\":{skillId},\"targetType\":{targetType},\"isAllResReady\":{hostPlayer.IsAllResReady().ToString().ToLower()},\"isModelReady\":{hostPlayer.IsPlayerModelReady.ToString().ToLower()},\"stateBits\":\"{string.Join(",", nextStates)}\"}}");
|
|
// #endregion
|
|
|
|
if (targetType == 0)
|
|
{
|
|
hostPlayer.SetNewExtendStates(0, nextStates, ExtStateCount);
|
|
return;
|
|
}
|
|
|
|
if (targetMarker != null)
|
|
targetMarker.SetNewExtendStates(0, nextStates, ExtStateCount);
|
|
}
|
|
|
|
static uint[] BuildExtStates(uint[] current, IEnumerable<int> stateIds)
|
|
{
|
|
var states = new uint[ExtStateCount];
|
|
if (current != null && current.Length >= ExtStateCount)
|
|
Array.Copy(current, states, ExtStateCount);
|
|
|
|
foreach (int stateId in stateIds)
|
|
{
|
|
if (stateId < 0)
|
|
continue;
|
|
|
|
int dwordIndex = stateId / BitSize;
|
|
int bit = stateId % BitSize;
|
|
if (dwordIndex < ExtStateCount)
|
|
states[dwordIndex] |= 1u << bit;
|
|
}
|
|
|
|
return states;
|
|
}
|
|
|
|
static int GetSkillTargetType(uint skillId)
|
|
{
|
|
SkillStub stub = SkillStub.GetStub(skillId);
|
|
if (stub == null)
|
|
return 1;
|
|
|
|
if (stub.restrict_corpse == 1)
|
|
return 2;
|
|
if (stub.restrict_corpse == 2)
|
|
return 3;
|
|
if (stub.type == (int)skill_type.TYPE_ATTACK || stub.type == (int)skill_type.TYPE_CURSE)
|
|
return 1;
|
|
if (stub.type == (int)skill_type.TYPE_BLESSPET)
|
|
return 4;
|
|
if (stub.GetRange().NoTarget())
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
}
|