Files
test/Assets/PerfectWorld/Scripts/Vfx/A3DSkillGfxComposerMan.cs
2026-02-26 15:01:46 +07:00

113 lines
3.4 KiB
C#

using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using BrewMonster.Network;
using BrewMonster.Scripts;
using BrewMonster.Scripts.Skills;
namespace BrewMonster
{
public class A3DSkillGfxComposerMan
{
private readonly Dictionary<int, A3DSkillGfxComposer> m_ComposerMap = new Dictionary<int, A3DSkillGfxComposer>();
/// <summary>
/// DEPRECATED: This method blocks the main thread. Use LoadOneComposerAsync instead.
/// </summary>
public bool LoadOneComposer(int nSkillID, SkillStub skillStub, string flyGFXPath, string hitGrdGFXPath, string hitGFXPath)
{
if (m_ComposerMap.ContainsKey(nSkillID))
return false;
var composer = new A3DSkillGfxComposer();
// WARNING: .Result blocks the main thread - this can cause freezing!
if (composer.Load(skillStub, flyGFXPath, hitGrdGFXPath, hitGFXPath).Status != UniTaskStatus.Succeeded)
{
// failed to load
return false;
}
// In original C++: composer->Init(g_pGame->GetGameRun()->GetWorld()->GetSkillGfxMan()->GetPtr());
// Not wired in Unity yet; keep placeholder init to allow future hookup.
composer.Init(A3DSkillGfxMan.Instance);
m_ComposerMap[nSkillID] = composer;
return true;
}
/// <summary>
/// Async version of LoadOneComposer that doesn't block the main thread.
/// </summary>
public async UniTask<bool> LoadOneComposerAsync(int nSkillID, SkillStub skillStub, string flyGFXPath, string hitGrdGFXPath, string hitGFXPath)
{
if (m_ComposerMap.ContainsKey(nSkillID))
return false;
var composer = new A3DSkillGfxComposer();
// Properly await the async Load operation
if (!await composer.Load(skillStub, flyGFXPath, hitGrdGFXPath, hitGFXPath))
{
// failed to load
return false;
}
// Load SkillStub GFX parameters (MoveMode, FlyTime, TargetMode, clusters, etc.)
// 从SkillStub加载GFX参数(移动模式、飞行时间、目标模式、群集等)
SkillStub stub = SkillStub.GetStub((uint)nSkillID);
if (stub != null)
{
composer.LoadFromSkillStub(stub);
}
// In original C++: composer->Init(g_pGame->GetGameRun()->GetWorld()->GetSkillGfxMan()->GetPtr());
composer.Init(A3DSkillGfxMan.Instance);
m_ComposerMap[nSkillID] = composer;
return true;
}
public void Release()
{
// If A3DSkillGfxComposer needs disposal later, do it here
m_ComposerMap.Clear();
}
public void Play(
int nSkillID,
int nHostID,
int nCastTargetID,
List<TARGET_DATA> Targets,
bool bIsGoblinSkill = false)
{
if (!m_ComposerMap.TryGetValue(nSkillID, out var composer) || composer == null)
{
BMLogger.LogError($"[SKILL_GFX_DEBUG] ComposerMan.Play: Composer NOT FOUND for skill {nSkillID} (map has {m_ComposerMap.Count} composers)");
return;
}
// Forward to composer (stubbed for now if Play not implemented)
try
{
// Provide a minimal default fly time estimation behavior when composer has no fly time configured
// Real effect triggering should be implemented inside composer.Play
composer.Play(nHostID, nCastTargetID, Targets, bIsGoblinSkill);
}
catch (System.MissingMethodException)
{
BMLogger.LogWarning("A3DSkillGfxComposer.Play is not implemented yet.");
}
catch (System.Exception ex)
{
BMLogger.LogError($"[SKILL_GFX_DEBUG] ComposerMan.Play: Exception in composer.Play() - {ex.Message}");
}
}
public A3DSkillGfxComposer GetSkillGfxComposer(int skill)
{
return m_ComposerMap.TryGetValue(skill, out var composer) ? composer : null;
}
}
}