516 lines
18 KiB
C#
516 lines
18 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using UnityEngine;
|
|
using static Unity.Cinemachine.CinemachineFreeLookModifier;
|
|
|
|
namespace BrewMonster
|
|
{
|
|
public enum GfxHitPos
|
|
{
|
|
enumHitCenter,
|
|
enumHitBottom
|
|
}
|
|
|
|
public enum GfxSkillEventState
|
|
{
|
|
enumWait,
|
|
enumFlying,
|
|
enumHit,
|
|
enumFinished
|
|
}
|
|
// TODO: remove singleton later
|
|
public class A3DSkillGfxMan
|
|
{
|
|
public static A3DSkillGfxMan _instance;
|
|
|
|
public static A3DSkillGfxMan Instance
|
|
{
|
|
get
|
|
{
|
|
if (_instance == null)
|
|
{
|
|
_instance = new A3DSkillGfxMan();
|
|
}
|
|
return _instance;
|
|
}
|
|
set
|
|
{
|
|
_instance = value;
|
|
}
|
|
}
|
|
|
|
public bool AddSkillGfxEvent(
|
|
A3DSkillGfxComposer pComposer,
|
|
long nHostID,
|
|
long nTargetID,
|
|
|
|
string szFlyGfx,
|
|
|
|
string szHitGfx,
|
|
uint dwFlyTimeSpan,
|
|
bool bTraceTarget,
|
|
GfxMoveMode FlyMode,
|
|
int nFlyGfxCount,
|
|
uint dwInterval,
|
|
GFX_SKILL_PARAM param,
|
|
|
|
float fFlyGfxScale,
|
|
|
|
float fHitGfxScale,
|
|
uint dwModifier,
|
|
bool bOnlyOneHit,
|
|
|
|
bool bFadeOut,
|
|
|
|
bool bIsGoblinSkill,
|
|
|
|
bool bReverse
|
|
)
|
|
{
|
|
|
|
bool bRet = true, bCluster;
|
|
uint dwDelayTime;
|
|
|
|
if (nFlyGfxCount == 1)
|
|
{
|
|
dwDelayTime = dwInterval;
|
|
bCluster = false;
|
|
}
|
|
else
|
|
{
|
|
dwDelayTime = 0;
|
|
bCluster = true;
|
|
}
|
|
for (int i = 0; i < nFlyGfxCount; i++)
|
|
{
|
|
string value = bOnlyOneHit && i != nFlyGfxCount - 1 ? "" : szHitGfx;
|
|
if (!AddOneSkillGfxEvent(
|
|
pComposer,
|
|
nHostID,
|
|
nTargetID,
|
|
szFlyGfx,
|
|
FlyMode,
|
|
dwDelayTime,
|
|
dwFlyTimeSpan,
|
|
value,
|
|
param,
|
|
bTraceTarget,
|
|
fFlyGfxScale,
|
|
fHitGfxScale,
|
|
dwModifier,
|
|
bCluster,
|
|
bFadeOut,
|
|
bIsGoblinSkill,
|
|
bReverse
|
|
))
|
|
bRet = false;
|
|
|
|
dwDelayTime += dwInterval;
|
|
}
|
|
|
|
return bRet;
|
|
|
|
}
|
|
public bool AddOneSkillGfxEvent(
|
|
A3DSkillGfxComposer pComposer,
|
|
long nHostID,
|
|
long nTargetID,
|
|
|
|
string szFlyGfx,
|
|
GfxMoveMode mode,
|
|
uint dwDelayTime,
|
|
uint dwFlyTimeSpan,
|
|
string szHitGfx,
|
|
|
|
GFX_SKILL_PARAM param,
|
|
|
|
bool bTraceTarget,
|
|
|
|
float fFlyGfxScale,
|
|
|
|
float fHitGfxScale,
|
|
uint dwModifier,
|
|
bool bCluster,
|
|
|
|
bool bFadeOut,
|
|
|
|
bool bIsGoblinSkill,
|
|
|
|
bool bReverse)
|
|
{
|
|
A3DSkillGfxEvent pEvent = SkillGfxMan.InstanceSub.GetEmptyEvent(mode);
|
|
pEvent.SetComposer(pComposer);
|
|
pEvent.SetHostID(nHostID);
|
|
pEvent.SetTargetID(nTargetID);
|
|
pEvent.SetFlyTimeSpan(dwFlyTimeSpan);
|
|
pEvent.SetDelay(dwDelayTime);
|
|
//pEvent.SetReverse(bReverse);
|
|
//if (param.value.fVal != float.MinValue) pEvent.SetParam(param);
|
|
pEvent.SetTraceTarget(bTraceTarget);
|
|
pEvent.SetModifier(dwModifier);
|
|
//pEvent.SetIsCluster(bCluster);
|
|
pEvent.SetFadeOut(bFadeOut);
|
|
pEvent.SetGoblinSkill(bIsGoblinSkill);
|
|
|
|
ECMODEL_GFX_PROPERTY Prop = new ECMODEL_GFX_PROPERTY();
|
|
if (GetPropertyById(nHostID, ref Prop))
|
|
{
|
|
pEvent.SetGfxUseLod(Prop.bGfxUseLod);
|
|
pEvent.SetDisableCamShake(Prop.bGfxDisableCamShake);
|
|
pEvent.SetHostModelCreatedByGfx(Prop.bHostECMCreatedByGfx);
|
|
}
|
|
|
|
/* if (szFlyGfx != 0)
|
|
{
|
|
A3DGFXEx pGfx = pEvent.LoadFlyGfx(m_pDevice, szFlyGfx.ToString());
|
|
if (pGfx != null)
|
|
{
|
|
pGfx.SetScale(fFlyGfxScale);
|
|
pGfx.SetDisableCamShake(pEvent.GetDisableCamShake());
|
|
pGfx.SetCreatedByGFXECM(pEvent.GetHostModelCreatedByGfx());
|
|
pGfx.SetUseLOD(pEvent.GetGfxUseLod());
|
|
pGfx.SetId(pEvent.GetHostID());
|
|
pEvent.SetFlyGfx(pGfx);
|
|
}
|
|
}*/
|
|
|
|
if (string.IsNullOrEmpty(szHitGfx))
|
|
{
|
|
/*game pGfx = pEvent.LoadHitGfx(m_pDevice, szHitGfx.ToString());
|
|
if (pGfx != null)
|
|
{
|
|
pGfx.SetScale(fHitGfxScale);
|
|
pEvent.SetHitGfx(pGfx);
|
|
}*/
|
|
}
|
|
|
|
#if !_SKILLGFXCOMPOSER
|
|
pEvent.Tick(0);
|
|
#endif
|
|
pComposer.SpawnGFX(nTargetID);
|
|
PushEvent(pEvent);
|
|
return true;
|
|
}
|
|
public virtual bool GetPropertyById(long nId, ref ECMODEL_GFX_PROPERTY pProperty) => false;
|
|
void PushEvent(A3DSkillGfxEvent pEvent) { SkillGfxMan.InstanceSub.m_EventLst.AddLast((CECSkillGfxEvent)pEvent); }
|
|
|
|
}
|
|
|
|
public class A3DSkillGfxEvent
|
|
{
|
|
protected A3DSkillGfxComposer m_pComposer;
|
|
//protected CGfxMoveBase m_pMoveMethod;
|
|
//protected A3DGFXEx m_pFlyGfx; // 飞行特效 / Fly effect
|
|
//protected A3DGFXEx m_pHitGfx; // 命中特效 / Hit effect
|
|
protected uint m_dwFlyTimeSpan; // 飞行时间 / Flight time
|
|
protected uint m_dwCurSpan;
|
|
protected uint m_dwDelayTime;
|
|
protected bool m_bTraceTarget;
|
|
protected bool m_bFadeOut;
|
|
protected long m_nHostID; // 施法者ID / Caster ID
|
|
protected long m_nTargetID; // 目标ID / Target ID
|
|
protected uint m_dwModifier; // 技能附加效果 / Skill additional effect
|
|
protected bool m_bIsGoblinSkill; // 是否为小精灵技能 / Whether it's a goblin skill
|
|
|
|
protected Vector3 m_vHostPos;
|
|
protected Vector3 m_vTargetPos;
|
|
protected Vector3 m_vTargetDir;
|
|
protected Vector3 m_vTargetUp;
|
|
protected bool m_bHostExist;
|
|
protected bool m_bTargetExist;
|
|
protected bool m_bHitGfxInfinite;
|
|
protected bool m_bTargetDirAndUpExist;
|
|
|
|
protected bool m_bGfxUseLod;
|
|
protected bool m_bGfxDisableCamShake;
|
|
protected bool m_bHostECMCreatedByGfx;
|
|
|
|
protected GfxSkillEventState m_enumState;
|
|
|
|
public A3DSkillGfxEvent(GfxMoveMode mode)
|
|
{
|
|
m_pComposer = null;
|
|
/* m_pFlyGfx = null;
|
|
m_pHitGfx = null;*/
|
|
m_nHostID = 0;
|
|
m_nTargetID = 0;
|
|
m_dwModifier = 0;
|
|
m_dwFlyTimeSpan = 0;
|
|
m_dwCurSpan = 0;
|
|
m_enumState = GfxSkillEventState.enumWait;
|
|
m_bHitGfxInfinite = false;
|
|
m_bIsGoblinSkill = false;
|
|
m_bTargetDirAndUpExist = false;
|
|
m_bGfxUseLod = true;
|
|
m_bGfxDisableCamShake = false;
|
|
m_bHostECMCreatedByGfx = false;
|
|
|
|
//m_pMoveMethod = CGfxMoveBase.CreateMoveMethod(mode);
|
|
}
|
|
|
|
~A3DSkillGfxEvent()
|
|
{
|
|
//ReleaseGfx();
|
|
// Note: m_pMoveMethod will be garbage collected
|
|
}
|
|
|
|
// Inline functions
|
|
/* protected void ReleaseFlyGfx()
|
|
{
|
|
if (m_pFlyGfx != null)
|
|
{
|
|
if (m_bFadeOut)
|
|
AfxGetGFXExMan().QueueFadeOutGfx(m_pFlyGfx, 1000);
|
|
else
|
|
{
|
|
m_pFlyGfx.Release();
|
|
// In C#, we don't need to manually delete
|
|
}
|
|
|
|
m_pFlyGfx = null;
|
|
}
|
|
}*/
|
|
|
|
/* protected void ReleaseHitGfx()
|
|
{
|
|
if (m_pHitGfx != null)
|
|
{
|
|
AfxGetGFXExMan().CacheReleasedGfx(m_pHitGfx);
|
|
m_pHitGfx = null;
|
|
}
|
|
}*/
|
|
|
|
/* protected void ReleaseGfx()
|
|
{
|
|
ReleaseFlyGfx();
|
|
ReleaseHitGfx();
|
|
}*/
|
|
|
|
// Virtual functions
|
|
protected virtual void HitTarget(Vector3 vTarget)
|
|
{
|
|
m_enumState = GfxSkillEventState.enumHit;
|
|
//ReleaseFlyGfx();
|
|
|
|
if (false /*m_pHitGfx != null*/)
|
|
{
|
|
//m_bHitGfxInfinite = m_pHitGfx.IsInfinite();
|
|
Matrix4x4 matTran;
|
|
|
|
// now try to make the hit gfx face to the attacker
|
|
if (m_bHostExist)
|
|
{
|
|
Vector3 vDir = vTarget - m_vHostPos;
|
|
vDir.y = 0;
|
|
|
|
if (vDir.magnitude < 1e-3f)
|
|
vDir = new Vector3(0, 0, 1.0f);
|
|
else
|
|
vDir.Normalize();
|
|
|
|
matTran = _build_matrix(vDir, vTarget);
|
|
}
|
|
else
|
|
{
|
|
matTran = Matrix4x4.identity;
|
|
matTran.SetColumn(3, new Vector4(vTarget.x, vTarget.y, vTarget.z, 1));
|
|
}
|
|
|
|
/* m_pHitGfx.SetParentTM(matTran);
|
|
m_pHitGfx.Start(true);
|
|
m_pHitGfx.TickAnimation(0);*/
|
|
}
|
|
}
|
|
|
|
// Public inline functions
|
|
public void SetGfxUseLod(bool b) { m_bGfxUseLod = b; }
|
|
public bool GetGfxUseLod() { return m_bGfxUseLod; }
|
|
public void SetDisableCamShake(bool b) { m_bGfxDisableCamShake = b; }
|
|
public bool GetDisableCamShake() { return m_bGfxDisableCamShake; }
|
|
public void SetHostModelCreatedByGfx(bool b) { m_bHostECMCreatedByGfx = b; }
|
|
public bool GetHostModelCreatedByGfx() { return m_bHostECMCreatedByGfx; }
|
|
public void SetComposer(A3DSkillGfxComposer pComposer) { m_pComposer = pComposer; }
|
|
//public CGfxMoveBase GetMoveMethod() { return m_pMoveMethod; }
|
|
//public GfxMoveMode GetMode() { return m_pMoveMethod.GetMode(); }
|
|
//public GfxHitPos GetHitPos() { return m_pMoveMethod.GetHitPos(); }
|
|
/* public A3DGFXEx GetFlyGfx() { return m_pFlyGfx; }
|
|
public A3DGFXEx GetHitGfx() { return m_pHitGfx; }*/
|
|
public void SetFlyTimeSpan(uint dwSpan) { m_dwFlyTimeSpan = dwSpan; }
|
|
public void SetDelay(uint dwDelay) { m_dwDelayTime = dwDelay; }
|
|
//public void SetReverse(bool bReverse) { m_pMoveMethod.SetReverse(bReverse); }
|
|
//public void SetParam(GFX_SKILL_PARAM param) { m_pMoveMethod.SetParam(param); }
|
|
//public void SetIsCluster(bool bCluster) { m_pMoveMethod.SetIsCluster(bCluster); }
|
|
public void SetTraceTarget(bool bTrace) { m_bTraceTarget = bTrace; }
|
|
public void SetFadeOut(bool bFadeOut) { m_bFadeOut = bFadeOut; }
|
|
public bool IsFinished() { return m_enumState == GfxSkillEventState.enumFinished; }
|
|
public long GetHostID() { return m_nHostID; }
|
|
public void SetHostID(long nID) { m_nHostID = nID; }
|
|
public long GetTargetID() { return m_nTargetID; }
|
|
public void SetTargetID(long nID) { m_nTargetID = nID; }
|
|
public void SetHostPos(Vector3 vPos) { m_vHostPos = vPos; }
|
|
public void SetTargetPos(Vector3 vPos) { m_vTargetPos = vPos; }
|
|
public void SetHostExist(bool bExist) { m_bHostExist = bExist; }
|
|
public void SetTargetExist(bool bExist) { m_bTargetExist = bExist; }
|
|
public void SetModifier(uint dwModifier) { m_dwModifier = dwModifier; }
|
|
public void SetGoblinSkill(bool bGoblinSkill) { m_bIsGoblinSkill = bGoblinSkill; }
|
|
public bool GetGoblinSkill() { return m_bIsGoblinSkill; }
|
|
|
|
public void Resume()
|
|
{
|
|
//ReleaseGfx();
|
|
m_enumState = GfxSkillEventState.enumWait;
|
|
m_dwCurSpan = 0;
|
|
}
|
|
|
|
// Virtual functions
|
|
/* public virtual A3DGFXEx LoadFlyGfx(A3DDevice pDev, string szPath)
|
|
{
|
|
return AfxGetGFXExMan().LoadGfx(pDev, szPath);
|
|
}
|
|
|
|
public virtual A3DGFXEx LoadHitGfx(A3DDevice pDev, string szPath)
|
|
{
|
|
return AfxGetGFXExMan().LoadGfx(pDev, szPath);
|
|
}
|
|
|
|
public virtual void SetFlyGfx(A3DGFXEx pFlyGfx)
|
|
{
|
|
m_pFlyGfx = pFlyGfx;
|
|
}
|
|
|
|
public virtual void SetHitGfx(A3DGFXEx pHitGfx)
|
|
{
|
|
m_pHitGfx = pHitGfx;
|
|
}*/
|
|
|
|
public virtual void Tick(uint dwDeltaTime)
|
|
{
|
|
m_dwCurSpan += dwDeltaTime;
|
|
|
|
if (m_enumState == GfxSkillEventState.enumFinished) return; // 结束 / Finished
|
|
else if (m_enumState == GfxSkillEventState.enumHit) // 命中 / Hit
|
|
{
|
|
/* if (m_pHitGfx == null || m_pHitGfx.GetState() == ST_STOP)
|
|
m_enumState = GfxSkillEventState.enumFinished;
|
|
else
|
|
{
|
|
if (!m_bTargetExist || (m_bHitGfxInfinite && m_pHitGfx.GetTimeElapse() > 5000)) // HIT_GFX_MAX_TIMESPAN = 5000
|
|
m_enumState = GfxSkillEventState.enumFinished;
|
|
else
|
|
{
|
|
if (m_bTraceTarget)
|
|
{
|
|
Matrix4x4 matTran = Matrix4x4.identity;
|
|
Vector3 targetCenter = GetTargetCenter();
|
|
matTran.SetColumn(3, new Vector4(targetCenter.x, targetCenter.y, targetCenter.z, 1));
|
|
//m_pHitGfx.SetParentTM(matTran);
|
|
}
|
|
|
|
//m_pHitGfx.TickAnimation(dwDeltaTime);
|
|
}
|
|
}*/
|
|
}
|
|
else if (m_dwCurSpan > m_dwFlyTimeSpan) // 飞行超时 / Flight timeout
|
|
{
|
|
if (!m_bTargetExist)
|
|
m_enumState = GfxSkillEventState.enumFinished;
|
|
/* else
|
|
HitTarget(GetTargetCenter());*/
|
|
}
|
|
else if (!m_bTargetExist)
|
|
m_enumState = GfxSkillEventState.enumFinished;
|
|
else if (m_enumState == GfxSkillEventState.enumWait)
|
|
{
|
|
if (m_dwCurSpan < m_dwDelayTime) return;
|
|
|
|
if (!m_bHostExist)
|
|
m_enumState = GfxSkillEventState.enumFinished;
|
|
else
|
|
{
|
|
m_enumState = GfxSkillEventState.enumFlying;
|
|
/* m_pMoveMethod.SetMaxFlyTime(m_dwFlyTimeSpan);
|
|
m_pMoveMethod.StartMove(m_vHostPos, m_vTargetPos);*/
|
|
|
|
/* if (m_pFlyGfx != null)
|
|
{
|
|
Vector3 vDir, vUp;
|
|
|
|
if (m_pMoveMethod.GetMode() == GfxMoveMode.enumOnTarget && m_pMoveMethod.IsReverse() && GetTargetDirAndUp(out vDir, out vUp))
|
|
m_pFlyGfx.SetParentTM(a3d_TransformMatrix(vDir, vUp, m_pMoveMethod.GetPos()));
|
|
else
|
|
m_pFlyGfx.SetParentTM(_build_matrix(m_pMoveMethod.GetMoveDir(), m_pMoveMethod.GetPos()));
|
|
|
|
m_pFlyGfx.Start(true);
|
|
m_pMoveMethod.UpdateGfxParam(m_pFlyGfx, m_vHostPos, m_vTargetPos);
|
|
m_pFlyGfx.TickAnimation(0);
|
|
}*/
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* if (m_pMoveMethod.TickMove(dwDeltaTime, m_vHostPos, m_vTargetPos)) // 目标被命中 / Target hit
|
|
HitTarget(GetTargetCenter());*/
|
|
/*else if (m_pFlyGfx != null)
|
|
{
|
|
Vector3 vDir, vUp;
|
|
|
|
if (m_pMoveMethod.GetMode() == GfxMoveMode.enumOnTarget && m_pMoveMethod.IsReverse() && GetTargetDirAndUp(out vDir, out vUp))
|
|
m_pFlyGfx.SetParentTM(a3d_TransformMatrix(vDir, vUp, m_pMoveMethod.GetPos()));
|
|
else
|
|
m_pFlyGfx.SetParentTM(_build_matrix(m_pMoveMethod.GetMoveDir(), m_pMoveMethod.GetPos()));
|
|
|
|
m_pMoveMethod.UpdateGfxParam(m_pFlyGfx, m_vHostPos, m_vTargetPos);
|
|
m_pFlyGfx.TickAnimation(dwDeltaTime);
|
|
}*/
|
|
}
|
|
}
|
|
|
|
/* public virtual void Render()
|
|
{
|
|
if (m_pFlyGfx != null) AfxGetGFXExMan().RegisterGfx(m_pFlyGfx);
|
|
if (m_pHitGfx != null) AfxGetGFXExMan().RegisterGfx(m_pHitGfx);
|
|
}
|
|
*/
|
|
public virtual Vector3 GetTargetCenter()
|
|
{
|
|
// Abstract method - must be implemented by derived class
|
|
throw new NotImplementedException("GetTargetCenter must be implemented by derived class");
|
|
}
|
|
|
|
public virtual bool GetTargetDirAndUp(out Vector3 vDir, out Vector3 vUp)
|
|
{
|
|
vDir = Vector3.zero;
|
|
vUp = Vector3.zero;
|
|
return false;
|
|
}
|
|
|
|
// Helper methods that need to be implemented elsewhere or provided by utility class
|
|
/* protected A3DGFXExMan AfxGetGFXExMan()
|
|
{
|
|
// This should return the GFX manager instance
|
|
throw new NotImplementedException("AfxGetGFXExMan needs to be implemented");
|
|
}
|
|
*/
|
|
protected Matrix4x4 _build_matrix(Vector3 dir, Vector3 pos)
|
|
{
|
|
// This should build a transformation matrix from direction and position
|
|
throw new NotImplementedException("_build_matrix needs to be implemented");
|
|
}
|
|
|
|
protected Matrix4x4 a3d_TransformMatrix(Vector3 dir, Vector3 up, Vector3 pos)
|
|
{
|
|
// This should build a transformation matrix from direction, up vector and position
|
|
throw new NotImplementedException("a3d_TransformMatrix needs to be implemented");
|
|
}
|
|
}
|
|
|
|
public struct ECMODEL_GFX_PROPERTY
|
|
{
|
|
public bool bGfxUseLod;
|
|
public bool bGfxDisableCamShake;
|
|
public bool bHostECMCreatedByGfx;
|
|
};
|
|
} |