skill pos processing
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
using CSNetwork.GPDataType;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
public class A3DAABB
|
||||
{
|
||||
public A3DVECTOR3 Center;
|
||||
public A3DVECTOR3 Extents;
|
||||
public A3DVECTOR3 Mins;
|
||||
public A3DVECTOR3 Maxs;
|
||||
|
||||
public A3DAABB() { }
|
||||
|
||||
public A3DAABB(A3DAABB aabb)
|
||||
{
|
||||
Center = aabb.Center;
|
||||
Extents = aabb.Extents;
|
||||
Mins = aabb.Mins;
|
||||
Maxs = aabb.Maxs;
|
||||
}
|
||||
|
||||
public A3DAABB(A3DVECTOR3 mins, A3DVECTOR3 maxs)
|
||||
{
|
||||
Mins = mins;
|
||||
Maxs = maxs;
|
||||
Center = (mins + maxs) * 0.5f;
|
||||
Extents = maxs - Center;
|
||||
}
|
||||
|
||||
// Reset AABB về trạng thái rỗng
|
||||
public void Clear()
|
||||
{
|
||||
Mins = new A3DVECTOR3(999999f, 999999f, 999999f);
|
||||
Maxs = new A3DVECTOR3(-999999f, -999999f, -999999f);
|
||||
Center = new A3DVECTOR3(0f, 0f, 0f);
|
||||
Extents = new A3DVECTOR3(0f, 0f, 0f);
|
||||
}
|
||||
|
||||
// Thêm 1 điểm vào AABB
|
||||
public void AddVertex(A3DVECTOR3 v)
|
||||
{
|
||||
if (v.x < Mins.x) Mins.x = v.x;
|
||||
if (v.y < Mins.y) Mins.y = v.y;
|
||||
if (v.z < Mins.z) Mins.z = v.z;
|
||||
|
||||
if (v.x > Maxs.x) Maxs.x = v.x;
|
||||
if (v.y > Maxs.y) Maxs.y = v.y;
|
||||
if (v.z > Maxs.z) Maxs.z = v.z;
|
||||
|
||||
CompleteCenterExts();
|
||||
}
|
||||
|
||||
// Hợp nhất 2 AABB
|
||||
public void Merge(A3DAABB subAABB)
|
||||
{
|
||||
if (subAABB.Mins.x < Mins.x) Mins.x = subAABB.Mins.x;
|
||||
if (subAABB.Mins.y < Mins.y) Mins.y = subAABB.Mins.y;
|
||||
if (subAABB.Mins.z < Mins.z) Mins.z = subAABB.Mins.z;
|
||||
|
||||
if (subAABB.Maxs.x > Maxs.x) Maxs.x = subAABB.Maxs.x;
|
||||
if (subAABB.Maxs.y > Maxs.y) Maxs.y = subAABB.Maxs.y;
|
||||
if (subAABB.Maxs.z > Maxs.z) Maxs.z = subAABB.Maxs.z;
|
||||
|
||||
CompleteCenterExts();
|
||||
}
|
||||
|
||||
// Cập nhật Mins, Maxs từ Center + Extents
|
||||
public void CompleteMinsMaxs()
|
||||
{
|
||||
Mins = Center - Extents;
|
||||
Maxs = Center + Extents;
|
||||
}
|
||||
|
||||
// Cập nhật Center + Extents từ Mins, Maxs
|
||||
public void CompleteCenterExts()
|
||||
{
|
||||
Center = (Mins + Maxs) * 0.5f;
|
||||
Extents = Maxs - Center;
|
||||
}
|
||||
|
||||
// Kiểm tra điểm có nằm trong AABB không
|
||||
public bool IsPointIn(A3DVECTOR3 v)
|
||||
{
|
||||
return !(v.x > Maxs.x || v.x < Mins.x ||
|
||||
v.y > Maxs.y || v.y < Mins.y ||
|
||||
v.z > Maxs.z || v.z < Mins.z);
|
||||
}
|
||||
|
||||
// Kiểm tra 1 AABB khác có nằm trong AABB này không
|
||||
public bool IsAABBIn(A3DAABB aabb)
|
||||
{
|
||||
return (aabb.Mins.x >= Mins.x && aabb.Maxs.x <= Maxs.x &&
|
||||
aabb.Mins.y >= Mins.y && aabb.Maxs.y <= Maxs.y &&
|
||||
aabb.Mins.z >= Mins.z && aabb.Maxs.z <= Maxs.z);
|
||||
}
|
||||
|
||||
// Xây AABB từ một tập vertices
|
||||
public void Build(A3DVECTOR3[] vertices)
|
||||
{
|
||||
Clear();
|
||||
foreach (var v in vertices)
|
||||
AddVertex(v);
|
||||
}
|
||||
|
||||
// Lấy các vertices (8 điểm) của AABB
|
||||
public A3DVECTOR3[] GetVertices()
|
||||
{
|
||||
A3DVECTOR3[] verts = new A3DVECTOR3[8];
|
||||
|
||||
verts[0] = new A3DVECTOR3(Mins.x, Mins.y, Mins.z);
|
||||
verts[1] = new A3DVECTOR3(Maxs.x, Mins.y, Mins.z);
|
||||
verts[2] = new A3DVECTOR3(Maxs.x, Maxs.y, Mins.z);
|
||||
verts[3] = new A3DVECTOR3(Mins.x, Maxs.y, Mins.z);
|
||||
|
||||
verts[4] = new A3DVECTOR3(Mins.x, Mins.y, Maxs.z);
|
||||
verts[5] = new A3DVECTOR3(Maxs.x, Mins.y, Maxs.z);
|
||||
verts[6] = new A3DVECTOR3(Maxs.x, Maxs.y, Maxs.z);
|
||||
verts[7] = new A3DVECTOR3(Mins.x, Maxs.y, Maxs.z);
|
||||
|
||||
return verts;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a6824a3d5ac15a4e8deab66a3ceaae2
|
||||
@@ -761,7 +761,10 @@ namespace BrewMonster
|
||||
public CECConfigs()
|
||||
{
|
||||
m_fCurPVRadius = m_fSevActiveRad;
|
||||
m_gs = default;
|
||||
DefaultUserSettings(ref m_ss, ref m_vs, ref m_gs, ref m_bs, ref m_cas);
|
||||
m_gs.bAtk_NoWhite = true;
|
||||
m_gs.bAtk_NoForce = true;
|
||||
}
|
||||
|
||||
public bool Init(string szCfgFile, string szClientIDFile, string szSSFile)
|
||||
|
||||
@@ -103,6 +103,7 @@ namespace BrewMonster.Network
|
||||
if (m_pTaskMan == null) m_pTaskMan = new ATaskTemplMan();
|
||||
|
||||
m_pTaskMan.Init(m_pElementDataMan);
|
||||
m_pConfigs = new CECConfigs(); /*ElementClient.g_GameCfgs*/;
|
||||
if (!m_pTaskMan.InitStorageTask())
|
||||
{
|
||||
BMLogger.LogError("[Dat]- CECGame::Init, Storage task Init Failed!");
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
public static class ElementClient
|
||||
{
|
||||
public static CECConfigs g_GameCfgs;
|
||||
|
||||
public static bool _InitGameApp()
|
||||
{
|
||||
g_GameCfgs = new CECConfigs();
|
||||
if (!g_GameCfgs.Init("Configs\\element_client.cfg", "client_id.cfg", "userdata\\SystemSettings.ini"))
|
||||
{
|
||||
BMLogger.LogError("_InitGameApp(), Failed to load configs file");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5b3f9ba4c8ff457408f56fef6c34c7bd
|
||||
@@ -120,3 +120,4 @@ namespace BrewMonster.Managers
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace BrewMonster
|
||||
|
||||
static LayerMask UsedMask_Ground() => BrushMask | TerrainMask;
|
||||
|
||||
public static bool CollideWithEnv(env_trace_t pEnvTrc)
|
||||
public static bool CollideWithEnv(ref env_trace_t pEnvTrc)
|
||||
{
|
||||
pEnvTrc.fFraction = 100.0f;
|
||||
pEnvTrc.bStartSolid = false;
|
||||
|
||||
@@ -1,11 +1,370 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using BrewMonster.Scripts;
|
||||
using CSNetwork.GPDataType;
|
||||
using UnityEngine;
|
||||
|
||||
using CombinedActMap = System.Collections.Generic.Dictionary<string, object>;
|
||||
using CoGfxMap = System.Collections.Generic.Dictionary<string, object>;
|
||||
using ConvexHullDataArray = System.Collections.Generic.List<object>;
|
||||
using ECModelHookMap = System.Collections.Generic.Dictionary<string, object>;
|
||||
using BrewMonster;
|
||||
|
||||
public enum ECMScript
|
||||
{
|
||||
enumECMScriptStartAction = 0,
|
||||
enumECMScriptEndActioin,
|
||||
enumECMScriptInit,
|
||||
enumECMScriptRelease,
|
||||
enumECMScriptModelLoaded,
|
||||
enumECMScriptChangeEquip,
|
||||
enumECMScriptChangeEquipTableInit,
|
||||
enumECMScriptPhysBreak,
|
||||
enumECMScriptCount
|
||||
}
|
||||
|
||||
public enum ECMScriptVar
|
||||
{
|
||||
enumECMVarModel = 0,
|
||||
enumECMVarActName,
|
||||
enumECMVarActChannel,
|
||||
enumECMVarEquipId,
|
||||
enumECMVarEquipFlag,
|
||||
enumECMVarFashionMode,
|
||||
enumECMVarPathId,
|
||||
enumECMVarId,
|
||||
enumECMVarEquipIndex,
|
||||
enumECMVarBreakOffsetX,
|
||||
enumECMVarBreakOffsetY,
|
||||
enumECMVarBreakOffsetZ,
|
||||
enumECMVarCasterId,
|
||||
enumECMVarCastTargetId,
|
||||
enumECMVarSelf,
|
||||
enumECMVarCount
|
||||
}
|
||||
|
||||
public static class CECModelConstants
|
||||
{
|
||||
public const int ECM_SCRIPT_MAX_VAR_COUNT = 8;
|
||||
public const int OUTER_DATA_COUNT = 8;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct ECM_SCRIPT_VAR
|
||||
{
|
||||
[MarshalAs(UnmanagedType.I4)]
|
||||
public int var_count;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = CECModelConstants.ECM_SCRIPT_MAX_VAR_COUNT)]
|
||||
public int[] var_index;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct BoneScale
|
||||
{
|
||||
public int m_nIndex;
|
||||
public int m_nType;
|
||||
public A3DVECTOR3 m_vScale;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct BoneScaleEx
|
||||
{
|
||||
public int m_nIndex;
|
||||
public float m_fLenFactor;
|
||||
public float m_fThickFactor;
|
||||
public float m_fWholeFactor;
|
||||
}
|
||||
|
||||
public class ActChannelInfo
|
||||
{
|
||||
public List<string> bone_names = new List<string>();
|
||||
public List<int> joint_indices = new List<int>();
|
||||
|
||||
public ActChannelInfo Clone()
|
||||
{
|
||||
return new ActChannelInfo
|
||||
{
|
||||
bone_names = new List<string>(bone_names),
|
||||
joint_indices = new List<int>(joint_indices)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public enum A3DBLEND
|
||||
{
|
||||
A3DBLEND_SRCALPHA,
|
||||
A3DBLEND_INVSRCALPHA
|
||||
}
|
||||
|
||||
public struct A3DSHADER
|
||||
{
|
||||
public A3DBLEND SrcBlend;
|
||||
public A3DBLEND DestBlend;
|
||||
}
|
||||
|
||||
public class CECModelStaticData
|
||||
{
|
||||
private string m_strFilePath = string.Empty;
|
||||
private string m_strSkinModelPath = string.Empty;
|
||||
private bool m_bAutoUpdate = true;
|
||||
private bool m_bActMapped;
|
||||
private readonly CombinedActMap m_ActionMap = new CombinedActMap();
|
||||
private uint m_dwVersion;
|
||||
private string m_strHook = string.Empty;
|
||||
private string m_strCCName = string.Empty;
|
||||
private readonly List<BoneScale> m_BoneScales = new List<BoneScale>();
|
||||
private readonly List<BoneScaleEx> m_BoneScaleExArr = new List<BoneScaleEx>();
|
||||
private string m_strScaleBaseBone = string.Empty;
|
||||
private uint m_OrgColor = 0xFFFFFFFF;
|
||||
private uint m_EmissiveColor = 0;
|
||||
private float m_fDefPlaySpeed = 1.0f;
|
||||
private A3DSHADER m_BlendMode = new A3DSHADER
|
||||
{
|
||||
SrcBlend = A3DBLEND.A3DBLEND_SRCALPHA,
|
||||
DestBlend = A3DBLEND.A3DBLEND_INVSRCALPHA
|
||||
};
|
||||
private readonly float[] m_OuterData = new float[CECModelConstants.OUTER_DATA_COUNT];
|
||||
private bool m_bCanCastShadow = true;
|
||||
private bool m_bRenderSkinModel = true;
|
||||
private bool m_bRenderEdge = true;
|
||||
private readonly CoGfxMap m_CoGfxMap = new CoGfxMap();
|
||||
private readonly ConvexHullDataArray m_ConvexHullDataArr = new ConvexHullDataArray();
|
||||
private readonly A3DAABB m_CHAABB = new A3DAABB();
|
||||
private readonly Dictionary<int, ActChannelInfo> m_ChannelInfoDict = new Dictionary<int, ActChannelInfo>();
|
||||
private readonly Dictionary<int, uint> m_EventMasks = new Dictionary<int, uint>();
|
||||
private readonly string[] m_Scripts = new string[(int)ECMScript.enumECMScriptCount];
|
||||
private readonly bool[] m_ScriptEnable = new bool[(int)ECMScript.enumECMScriptCount];
|
||||
private readonly CLuaMemTbl m_ScriptMemTbl = new CLuaMemTbl();
|
||||
private bool m_bInitGlobalScript;
|
||||
private string m_strGlobalScriptName = string.Empty;
|
||||
|
||||
public class ChildInfo
|
||||
{
|
||||
public string m_strName = string.Empty;
|
||||
public string m_strPath = string.Empty;
|
||||
public string m_strHHName = string.Empty;
|
||||
public string m_strCCName = string.Empty;
|
||||
}
|
||||
|
||||
private readonly List<ChildInfo> m_ChildInfoArray = new List<ChildInfo>();
|
||||
private readonly List<string> m_AdditionalSkinLst = new List<string>();
|
||||
private string m_strPhysFileName = string.Empty;
|
||||
private object m_pPhysSyncData;
|
||||
private readonly ECModelHookMap m_ECModelHookMap = new ECModelHookMap();
|
||||
private string m_strPixelShader = string.Empty;
|
||||
private string m_strShaderTex = string.Empty;
|
||||
private readonly List<object> m_vecPSConsts = new List<object>();
|
||||
|
||||
public CECModelStaticData()
|
||||
{
|
||||
ResetOuterData();
|
||||
m_CHAABB.Clear();
|
||||
}
|
||||
|
||||
public bool LoadData(string szModelFile, bool bLoadAdditionalSkin)
|
||||
{
|
||||
throw new NotImplementedException("CECModelStaticData.LoadData requires the legacy AFile system to be ported.");
|
||||
}
|
||||
|
||||
public bool Save(string szFile, CECModel pModel)
|
||||
{
|
||||
throw new NotImplementedException("CECModelStaticData.Save requires the legacy serialization pipeline to be ported.");
|
||||
}
|
||||
|
||||
public bool SaveBoneScaleInfo(string szFile)
|
||||
{
|
||||
throw new NotImplementedException("CECModelStaticData.SaveBoneScaleInfo is not yet implemented.");
|
||||
}
|
||||
|
||||
public void Release()
|
||||
{
|
||||
m_BoneScales.Clear();
|
||||
m_BoneScaleExArr.Clear();
|
||||
m_CoGfxMap.Clear();
|
||||
m_ActionMap.Clear();
|
||||
m_AdditionalSkinLst.Clear();
|
||||
m_ChildInfoArray.Clear();
|
||||
m_ConvexHullDataArr.Clear();
|
||||
m_ChannelInfoDict.Clear();
|
||||
m_EventMasks.Clear();
|
||||
Array.Clear(m_Scripts, 0, m_Scripts.Length);
|
||||
Array.Clear(m_ScriptEnable, 0, m_ScriptEnable.Length);
|
||||
m_ECModelHookMap.Clear();
|
||||
m_vecPSConsts.Clear();
|
||||
m_bInitGlobalScript = false;
|
||||
m_strGlobalScriptName = string.Empty;
|
||||
m_pPhysSyncData = null;
|
||||
m_CHAABB.Clear();
|
||||
ResetOuterData();
|
||||
}
|
||||
|
||||
public ConvexHullDataArray GetConvexHullData() => m_ConvexHullDataArr;
|
||||
|
||||
public bool HasCHAABB() => m_ConvexHullDataArr.Count != 0;
|
||||
|
||||
public A3DAABB GetCHAABB() => m_CHAABB;
|
||||
|
||||
public bool UpdateScript(int index, string strScript, bool bCompileOnly)
|
||||
{
|
||||
if (index < 0 || index >= (int)ECMScript.enumECMScriptCount)
|
||||
return false;
|
||||
|
||||
if (!bCompileOnly)
|
||||
m_Scripts[index] = strScript ?? string.Empty;
|
||||
|
||||
m_ScriptEnable[index] = !string.IsNullOrEmpty(m_Scripts[index]);
|
||||
return m_ScriptEnable[index];
|
||||
}
|
||||
|
||||
public CoGfxMap GetCoGfxMap() => m_CoGfxMap;
|
||||
|
||||
public CombinedActMap GetCombinedActMap() => m_ActionMap;
|
||||
|
||||
public string GetPhysFileName() => m_strPhysFileName;
|
||||
|
||||
public void SetPhysFileName(string szFile) => m_strPhysFileName = szFile ?? string.Empty;
|
||||
|
||||
public object GetPhysSyncData() => m_pPhysSyncData;
|
||||
|
||||
public void SetPhysSyncData(object p) => m_pPhysSyncData = p;
|
||||
|
||||
public uint GetVersion() => m_dwVersion;
|
||||
|
||||
public string GetPixelShaderPath() => m_strPixelShader;
|
||||
|
||||
public void SetPixelShaderPath(string szPath) => m_strPixelShader = szPath ?? string.Empty;
|
||||
|
||||
public string GetShaderTexture() => m_strShaderTex;
|
||||
|
||||
public void SetShaderTexture(string szPath) => m_strShaderTex = szPath ?? string.Empty;
|
||||
|
||||
public IList<object> GetPSConstVec() => m_vecPSConsts;
|
||||
|
||||
public void SetActionEventMask(int nChannel, uint dwMask) => m_EventMasks[nChannel] = dwMask;
|
||||
|
||||
public uint GetActionEventMask(int nChannel)
|
||||
{
|
||||
return m_EventMasks.TryGetValue(nChannel, out uint mask) ? mask : uint.MaxValue;
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<int, uint> GetActionEventMaskSnapshot() => m_EventMasks;
|
||||
|
||||
public void OnScriptEndAction(CECModel pModel, int nChannel, string szActName)
|
||||
{
|
||||
if (!IsScriptEnabled(ECMScript.enumECMScriptEndActioin))
|
||||
return;
|
||||
|
||||
Debug.LogWarning($"CECModelStaticData.OnScriptEndAction invoked for {szActName}, scripting runtime not yet ported.");
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
m_OrgColor = 0xFFFFFFFF;
|
||||
m_EmissiveColor = 0;
|
||||
m_fDefPlaySpeed = 1.0f;
|
||||
m_BlendMode = new A3DSHADER
|
||||
{
|
||||
SrcBlend = A3DBLEND.A3DBLEND_SRCALPHA,
|
||||
DestBlend = A3DBLEND.A3DBLEND_INVSRCALPHA
|
||||
};
|
||||
|
||||
ResetOuterData();
|
||||
m_BoneScales.Clear();
|
||||
m_BoneScaleExArr.Clear();
|
||||
m_strScaleBaseBone = string.Empty;
|
||||
m_ChannelInfoDict.Clear();
|
||||
m_strPhysFileName = string.Empty;
|
||||
}
|
||||
|
||||
public void AddScriptMethod(int index, string szScript)
|
||||
{
|
||||
if (index < 0 || index >= (int)ECMScript.enumECMScriptCount)
|
||||
return;
|
||||
|
||||
m_ScriptEnable[index] = !string.IsNullOrEmpty(szScript);
|
||||
}
|
||||
|
||||
public void OnScriptPlayAction(CECModel pModel, int nChannel, string szActName)
|
||||
{
|
||||
if (!IsScriptEnabled(ECMScript.enumECMScriptStartAction))
|
||||
return;
|
||||
|
||||
Debug.LogWarning($"CECModelStaticData.OnScriptPlayAction triggered for {szActName}, scripting runtime not available.");
|
||||
}
|
||||
|
||||
public void OnScriptChangeEquip(CECModel pModel, int nEquipId, int nEquipFlag, bool bFashionMode, int nPathId, int nEquipIndex)
|
||||
{
|
||||
if (!IsScriptEnabled(ECMScript.enumECMScriptChangeEquip))
|
||||
return;
|
||||
|
||||
Debug.LogWarning("CECModelStaticData.OnScriptChangeEquip called, scripting runtime not available.");
|
||||
}
|
||||
|
||||
public void OnScriptPhysBreak(CECModel pModel, float fBreakOffsetX, float fBreakOffsetY, float fBreakOffsetZ)
|
||||
{
|
||||
if (!IsScriptEnabled(ECMScript.enumECMScriptPhysBreak))
|
||||
return;
|
||||
|
||||
Debug.LogWarning("CECModelStaticData.OnScriptPhysBreak called, scripting runtime not available.");
|
||||
}
|
||||
|
||||
public void InitGlobalScript()
|
||||
{
|
||||
if (m_bInitGlobalScript)
|
||||
return;
|
||||
|
||||
if (!IsScriptEnabled(ECMScript.enumECMScriptInit))
|
||||
return;
|
||||
|
||||
m_bInitGlobalScript = true;
|
||||
m_strGlobalScriptName = $"GlobalScriptFunc_{DateTime.UtcNow.Ticks}";
|
||||
}
|
||||
|
||||
public bool LoadAdditionalSkin(object pFile, uint dwVersion, bool bLoadAdditionalSkin)
|
||||
{
|
||||
Debug.LogWarning("CECModelStaticData.LoadAdditionalSkin stub invoked.");
|
||||
return true;
|
||||
}
|
||||
|
||||
public IList<string> GetAdditionalSkinList() => m_AdditionalSkinLst;
|
||||
|
||||
public IList<ChildInfo> GetChildInfoArray() => m_ChildInfoArray;
|
||||
|
||||
public float[] GetOuterData() => m_OuterData;
|
||||
|
||||
public bool CanCastShadow => m_bCanCastShadow;
|
||||
public bool CanRenderSkinModel => m_bRenderSkinModel;
|
||||
public bool CanRenderEdge => m_bRenderEdge;
|
||||
|
||||
private bool IsScriptEnabled(ECMScript scriptId)
|
||||
{
|
||||
int idx = (int)scriptId;
|
||||
if (idx < 0 || idx >= m_ScriptEnable.Length)
|
||||
return false;
|
||||
return m_ScriptEnable[idx];
|
||||
}
|
||||
|
||||
private void ResetOuterData()
|
||||
{
|
||||
for (int i = 0; i < m_OuterData.Length; i++)
|
||||
m_OuterData[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
public class CLuaMemTbl
|
||||
{
|
||||
public void Init(string tableName) { }
|
||||
public bool AddMethod(string name, IList<string> args, string script) => false;
|
||||
public void RemoveMethod(string name) { }
|
||||
public void Release() { }
|
||||
}
|
||||
|
||||
public class CECModel
|
||||
{
|
||||
private const uint COMACT_FLAG_MODE_NONE = 0;
|
||||
//protected CECModelStaticData m_pMapModel;
|
||||
protected CECModelStaticData m_pMapModel;
|
||||
public void ClearComActFlag(bool bSignalCurrent) { ClearComActFlag(0, bSignalCurrent); }
|
||||
public void ClearComActFlag(int nChannel, bool bSignalCurrent)
|
||||
{
|
||||
@@ -42,14 +401,15 @@ public class CECModel
|
||||
AnimationName = animationName;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasCHAABB() { return m_pMapModel.HasCHAABB(); }
|
||||
|
||||
public void PlayGfx(string szPath, string szHook, float fScale, bool bFadeOut, A3DVECTOR3 vOffset, float fPitch, float fYaw, float fRot, bool bUseECMHook, uint dwFadeOutTime)
|
||||
{
|
||||
if (!bFadeOut)
|
||||
dwFadeOutTime = 0;
|
||||
string strKey = szPath;
|
||||
strKey += szHook;
|
||||
|
||||
|
||||
|
||||
// PGFX_INFO pInfo;
|
||||
//
|
||||
|
||||
@@ -609,7 +609,7 @@ public class CECNPC : CECObject
|
||||
|
||||
Vector3 dir = m_vMoveDir.normalized;
|
||||
Vector3 moveDelta = dir * m_fMoveSpeed * deltaTime;
|
||||
if(_characterController == null)
|
||||
if (_characterController == null)
|
||||
{
|
||||
BMLogger.LogError(" CECNPC.MovingTo _characterController == null " + gameObject.name);
|
||||
}
|
||||
@@ -662,7 +662,7 @@ public class CECNPC : CECObject
|
||||
// No delay die, enter disappear process immediately
|
||||
if (!bDelay)
|
||||
Disappear();
|
||||
|
||||
|
||||
|
||||
StartWork((int)WorkType.WT_NORMAL, (int)WorkID.WORK_DEAD, m_dwStates);
|
||||
|
||||
@@ -807,8 +807,9 @@ public class CECNPC : CECObject
|
||||
return;
|
||||
}
|
||||
var model = await NPCBuilder.Instance.GetModelByPath(AFile.NormalizePath(szModelFile.ToLower(), true));
|
||||
if (model == null) {
|
||||
|
||||
if (model == null)
|
||||
{
|
||||
|
||||
model = GameObject.CreatePrimitive(PrimitiveType.Capsule);
|
||||
BMLogger.LogWarning($" CECNPC.QueueLoadNPCModel model == null szModelFile= {szModelFile} ");
|
||||
}
|
||||
@@ -979,6 +980,10 @@ public class CECNPC : CECObject
|
||||
}
|
||||
}
|
||||
}
|
||||
public bool GetCHAABB(ref A3DAABB aabb)
|
||||
{
|
||||
return m_pNPCModelPolicy.GetCHAABB(ref aabb);
|
||||
}
|
||||
void SetPos(Vector3 pos)
|
||||
{
|
||||
transform.position = pos;
|
||||
|
||||
@@ -7,6 +7,10 @@ public class CECNPCModelDefaultPolicy
|
||||
{
|
||||
CECModel m_pNPCModel;
|
||||
CECNPC m_pNPC;
|
||||
int m_nBrushes;
|
||||
A3DAABB m_CHAABB; // AABB Updated with m_ppBrushes
|
||||
// number of brush object used in collision
|
||||
|
||||
public CECNPCModelDefaultPolicy(CECNPC pNPC)
|
||||
{
|
||||
m_pNPCModel = new CECModel();
|
||||
@@ -51,6 +55,27 @@ public class CECNPCModelDefaultPolicy
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public override bool GetCHAABB(ref A3DAABB aabb)
|
||||
{
|
||||
|
||||
bool bRet = (false);
|
||||
if (HasCHAABB())
|
||||
{
|
||||
aabb = m_CHAABB;
|
||||
// m_CHAABB ¸ù¾Ý͹°üÉϵĶ¥µãλÖÃÀ´¼ÆËã°üΧºÐ£¬¸ü׼ȷ²¢Óë͹°ü¼ì²â±£³ÖÒ»ÖÂ
|
||||
// ²»ÄÜʹÓà GetPos() À´µ÷Õû m_CHAABB ºó×÷Ϊ¼ÆËã½á¹û·µ»Ø
|
||||
//aabb.Center = GetPos() + A3DVECTOR3(0.0f, m_CHAABB.Extents.y, 0.0f);
|
||||
//aabb.CompleteMinsMaxs();
|
||||
bRet = true;
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
bool HasCHAABB()
|
||||
{
|
||||
return m_pNPCModel != null
|
||||
&& m_pNPCModel.HasCHAABB()
|
||||
&& m_nBrushes > 0;
|
||||
}
|
||||
public override bool PlayModelAction(int iAction, bool bRestart, CECAttackEvent cECAttackEvent)
|
||||
{
|
||||
/* if (m_pNPCModel == null)
|
||||
@@ -72,7 +97,7 @@ public class CECNPCModelDefaultPolicy
|
||||
else if (iAction == (int)NPCActionIndex.ACT_ATTACK1 || iAction == (int)NPCActionIndex.ACT_ATTACK2)
|
||||
{
|
||||
//bool bHideFX = !CECOptimize::Instance().GetGFX().CanShowAttack(m_pNPC->GetNPCID(), m_pNPC->GetClassID());
|
||||
result = _npcVisual.TryPlayAction(GetActionName(iAction, true), cECAttackEvent,true);
|
||||
result = _npcVisual.TryPlayAction(GetActionName(iAction, true), cECAttackEvent, true);
|
||||
if (result)
|
||||
{
|
||||
string szAct = GetActionName(iAction, false);
|
||||
|
||||
@@ -13,5 +13,7 @@ namespace BrewMonster
|
||||
public abstract bool HasAction(int iAction);
|
||||
public abstract void ClearComActFlag(bool bSignalCurrent);
|
||||
public abstract bool PlayAttackAction(int nAttackSpeed, CECAttackEvent attackevent);
|
||||
public abstract bool GetCHAABB(ref A3DAABB ab);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -713,7 +713,21 @@ namespace CSNetwork
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_ENCHANTRESULT, MANAGER_INDEX.MAN_PLAYER, -1, pDataBuf, pCmdHeader);
|
||||
else if (ISNPCID(pCmd3.caster))
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_NM_ENCHANTRESULT, MANAGER_INDEX.MAN_NPC, 0, pDataBuf, pCmdHeader);
|
||||
|
||||
break;
|
||||
case CommandID.SKILL_PERFORM:
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_CASTSKILL, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
|
||||
break;
|
||||
case CommandID.SET_COOLDOWN:
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_SETCOOLTIME, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
|
||||
break;
|
||||
case CommandID.COMBO_SKILL_PREPARE:
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_COMBO_SKILL_PREPARE, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader, dwDataSize);
|
||||
break;
|
||||
case CommandID.PLAYER_EXT_PROP_BASE:
|
||||
case CommandID.PLAYER_EXT_PROP_MOVE:
|
||||
case CommandID.PLAYER_EXT_PROP_ATK:
|
||||
case CommandID.PLAYER_EXT_PROP_DEF:
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_PLAYEREXTPROP, MANAGER_INDEX.MAN_PLAYER, -1, pDataBuf, pCmdHeader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -652,122 +652,5 @@ namespace BrewMonster
|
||||
APPEAR_RUNINTOVIEW, // Player run into view
|
||||
APPEAR_GHOST, // Player is in ghost state, in player list but not active
|
||||
};
|
||||
public class A3DAABB
|
||||
{
|
||||
public A3DVECTOR3 Center;
|
||||
public A3DVECTOR3 Extents;
|
||||
public A3DVECTOR3 Mins;
|
||||
public A3DVECTOR3 Maxs;
|
||||
|
||||
public A3DAABB() { }
|
||||
|
||||
public A3DAABB(A3DAABB aabb)
|
||||
{
|
||||
Center = aabb.Center;
|
||||
Extents = aabb.Extents;
|
||||
Mins = aabb.Mins;
|
||||
Maxs = aabb.Maxs;
|
||||
}
|
||||
|
||||
public A3DAABB(A3DVECTOR3 mins, A3DVECTOR3 maxs)
|
||||
{
|
||||
Mins = mins;
|
||||
Maxs = maxs;
|
||||
Center = (mins + maxs) * 0.5f;
|
||||
Extents = maxs - Center;
|
||||
}
|
||||
|
||||
// Reset AABB về trạng thái rỗng
|
||||
public void Clear()
|
||||
{
|
||||
Mins = new A3DVECTOR3(999999f, 999999f, 999999f);
|
||||
Maxs = new A3DVECTOR3(-999999f, -999999f, -999999f);
|
||||
Center = new A3DVECTOR3(0f, 0f, 0f);
|
||||
Extents = new A3DVECTOR3(0f, 0f, 0f);
|
||||
}
|
||||
|
||||
// Thêm 1 điểm vào AABB
|
||||
public void AddVertex(A3DVECTOR3 v)
|
||||
{
|
||||
if (v.x < Mins.x) Mins.x = v.x;
|
||||
if (v.y < Mins.y) Mins.y = v.y;
|
||||
if (v.z < Mins.z) Mins.z = v.z;
|
||||
|
||||
if (v.x > Maxs.x) Maxs.x = v.x;
|
||||
if (v.y > Maxs.y) Maxs.y = v.y;
|
||||
if (v.z > Maxs.z) Maxs.z = v.z;
|
||||
|
||||
CompleteCenterExts();
|
||||
}
|
||||
|
||||
// Hợp nhất 2 AABB
|
||||
public void Merge(A3DAABB subAABB)
|
||||
{
|
||||
if (subAABB.Mins.x < Mins.x) Mins.x = subAABB.Mins.x;
|
||||
if (subAABB.Mins.y < Mins.y) Mins.y = subAABB.Mins.y;
|
||||
if (subAABB.Mins.z < Mins.z) Mins.z = subAABB.Mins.z;
|
||||
|
||||
if (subAABB.Maxs.x > Maxs.x) Maxs.x = subAABB.Maxs.x;
|
||||
if (subAABB.Maxs.y > Maxs.y) Maxs.y = subAABB.Maxs.y;
|
||||
if (subAABB.Maxs.z > Maxs.z) Maxs.z = subAABB.Maxs.z;
|
||||
|
||||
CompleteCenterExts();
|
||||
}
|
||||
|
||||
// Cập nhật Mins, Maxs từ Center + Extents
|
||||
public void CompleteMinsMaxs()
|
||||
{
|
||||
Mins = Center - Extents;
|
||||
Maxs = Center + Extents;
|
||||
}
|
||||
|
||||
// Cập nhật Center + Extents từ Mins, Maxs
|
||||
public void CompleteCenterExts()
|
||||
{
|
||||
Center = (Mins + Maxs) * 0.5f;
|
||||
Extents = Maxs - Center;
|
||||
}
|
||||
|
||||
// Kiểm tra điểm có nằm trong AABB không
|
||||
public bool IsPointIn(A3DVECTOR3 v)
|
||||
{
|
||||
return !(v.x > Maxs.x || v.x < Mins.x ||
|
||||
v.y > Maxs.y || v.y < Mins.y ||
|
||||
v.z > Maxs.z || v.z < Mins.z);
|
||||
}
|
||||
|
||||
// Kiểm tra 1 AABB khác có nằm trong AABB này không
|
||||
public bool IsAABBIn(A3DAABB aabb)
|
||||
{
|
||||
return (aabb.Mins.x >= Mins.x && aabb.Maxs.x <= Maxs.x &&
|
||||
aabb.Mins.y >= Mins.y && aabb.Maxs.y <= Maxs.y &&
|
||||
aabb.Mins.z >= Mins.z && aabb.Maxs.z <= Maxs.z);
|
||||
}
|
||||
|
||||
// Xây AABB từ một tập vertices
|
||||
public void Build(A3DVECTOR3[] vertices)
|
||||
{
|
||||
Clear();
|
||||
foreach (var v in vertices)
|
||||
AddVertex(v);
|
||||
}
|
||||
|
||||
// Lấy các vertices (8 điểm) của AABB
|
||||
public A3DVECTOR3[] GetVertices()
|
||||
{
|
||||
A3DVECTOR3[] verts = new A3DVECTOR3[8];
|
||||
|
||||
verts[0] = new A3DVECTOR3(Mins.x, Mins.y, Mins.z);
|
||||
verts[1] = new A3DVECTOR3(Maxs.x, Mins.y, Mins.z);
|
||||
verts[2] = new A3DVECTOR3(Maxs.x, Maxs.y, Mins.z);
|
||||
verts[3] = new A3DVECTOR3(Mins.x, Maxs.y, Mins.z);
|
||||
|
||||
verts[4] = new A3DVECTOR3(Mins.x, Mins.y, Maxs.z);
|
||||
verts[5] = new A3DVECTOR3(Maxs.x, Mins.y, Maxs.z);
|
||||
verts[6] = new A3DVECTOR3(Maxs.x, Maxs.y, Maxs.z);
|
||||
verts[7] = new A3DVECTOR3(Mins.x, Maxs.y, Maxs.z);
|
||||
|
||||
return verts;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace BrewMonster
|
||||
public static Skill56Stub __stub_Skill56Stub = new Skill56Stub();
|
||||
public static Skill57Stub __stub_Skill57Stub = new Skill57Stub();
|
||||
public static Skill58Stub __stub_Skill58Stub = new Skill58Stub();
|
||||
//public static Skill59Stub __stub_Skill59Stub = new Skill59Stub();
|
||||
public static Skill59Stub __stub_Skill59Stub = new Skill59Stub();
|
||||
//public static Skill60Stub __stub_Skill60Stub = new Skill60Stub();
|
||||
//public static Skill61Stub __stub_Skill61Stub = new Skill61Stub();
|
||||
//public static Skill62Stub __stub_Skill62Stub = new Skill62Stub();
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace BrewMonster.Scripts.Skills
|
||||
{
|
||||
id = i;
|
||||
stub = s;
|
||||
player = new PlayerWrapper();
|
||||
}
|
||||
public static Skill Create(uint id, int n)
|
||||
{
|
||||
@@ -61,6 +62,8 @@ namespace BrewMonster.Scripts.Skills
|
||||
{
|
||||
return stub.is_senior != 0 ? stub.pre_skills : new Dictionary<uint, int>();
|
||||
}
|
||||
public override int GetRangeType() { return stub.GetRange().type; }
|
||||
|
||||
public override int GetTargetType()
|
||||
{
|
||||
if (stub.restrict_corpse == 1)
|
||||
|
||||
@@ -227,3 +227,4 @@ namespace BrewMonster
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -227,3 +227,4 @@ namespace BrewMonster
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -324,3 +324,4 @@ namespace BrewMonster
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -318,3 +318,4 @@ namespace BrewMonster
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -329,3 +329,4 @@ namespace BrewMonster
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -322,3 +322,4 @@ namespace BrewMonster
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,316 @@
|
||||
#define SKILL_CLIENT
|
||||
using BrewMonster.Scripts.Skills;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using static BrewMonster.PET_EVOLVE_CONFIG;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
#if SKILL_SERVER
|
||||
public class Skill59 : Skill
|
||||
{
|
||||
public const int SKILL_ID = 59;
|
||||
|
||||
public Skill59() : base(SKILL_ID)
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public class Skill59Stub : SkillStub
|
||||
{
|
||||
private static readonly int[] RequiredLevelArray = { 29, 34, 39, 44, 49, 54, 59, 64, 69, 74 };
|
||||
private static readonly int[] RequiredSpArray = { 3540, 5190, 7380, 10260, 14100, 19200, 26100, 35400, 48000, 71700 };
|
||||
private static readonly int[] RequiredMoneyArray = { 1090, 1540, 1990, 2480, 2980, 3480, 3980, 12980, 51980, 151980 };
|
||||
|
||||
#if SKILL_SERVER
|
||||
public class State1 : SkillStub.State
|
||||
{
|
||||
public int GetTime(Skill skill)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public bool Quit(Skill skill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Loop(Skill skill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Bypass(Skill skill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Calculate(Skill skill)
|
||||
{
|
||||
skill.GetPlayer().SetPray(1);
|
||||
}
|
||||
|
||||
public bool Interrupt(Skill skill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Cancel(Skill skill)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Skip(Skill skill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SKILL_SERVER
|
||||
public class State2 : SkillStub.State
|
||||
{
|
||||
public int GetTime(Skill skill)
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
|
||||
public bool Quit(Skill skill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Loop(Skill skill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Bypass(Skill skill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Calculate(Skill skill)
|
||||
{
|
||||
skill.GetPlayer().SetPerform(1);
|
||||
}
|
||||
|
||||
public bool Interrupt(Skill skill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Cancel(Skill skill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Skip(Skill skill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SKILL_SERVER
|
||||
public class State3 : SkillStub.State
|
||||
{
|
||||
public int GetTime(Skill skill)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public bool Quit(Skill skill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Loop(Skill skill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Bypass(Skill skill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Calculate(Skill skill)
|
||||
{
|
||||
}
|
||||
|
||||
public bool Interrupt(Skill skill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Cancel(Skill skill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Skip(Skill skill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public Skill59Stub() : base(59)
|
||||
{
|
||||
cls = 0;
|
||||
name = "虎跃";
|
||||
nativename = "虎跃";
|
||||
icon = "虎跃.dds";
|
||||
max_level = 10;
|
||||
type = 8;
|
||||
apcost = 10;
|
||||
arrowcost = 0;
|
||||
apgain = 0;
|
||||
attr = 1;
|
||||
rank = 3;
|
||||
eventflag = 0;
|
||||
posdouble = 0;
|
||||
clslimit = 0;
|
||||
time_type = 0;
|
||||
showorder = 1129;
|
||||
allow_land = true;
|
||||
allow_air = true;
|
||||
allow_water = true;
|
||||
allow_ride = false;
|
||||
auto_attack = false;
|
||||
long_range = 0;
|
||||
restrict_corpse = 0;
|
||||
allow_forms = 1;
|
||||
effect = "虎跃.sgc";
|
||||
range = new Range();
|
||||
range.type = 5;
|
||||
doenchant = 1;
|
||||
dobless = 0;
|
||||
commoncooldown = 0;
|
||||
commoncooldowntime = 0;
|
||||
pre_skills = new Dictionary<uint, int>();
|
||||
pre_skills.Add(0, 1);
|
||||
restrict_weapons.Add(0);
|
||||
restrict_weapons.Add(1);
|
||||
restrict_weapons.Add(182);
|
||||
restrict_weapons.Add(5);
|
||||
restrict_weapons.Add(292);
|
||||
restrict_weapons.Add(9);
|
||||
#if SKILL_SERVER
|
||||
statestub.Add(new State1());
|
||||
statestub.Add(new State2());
|
||||
statestub.Add(new State3());
|
||||
#endif
|
||||
}
|
||||
|
||||
~Skill59Stub()
|
||||
{
|
||||
}
|
||||
|
||||
public float GetMpcost(Skill skill)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
public int GetExecutetime(Skill skill)
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
|
||||
public int GetCoolingtime(Skill skill)
|
||||
{
|
||||
return 16000 - 1000 * skill.GetLevel();
|
||||
}
|
||||
|
||||
public int GetRequiredLevel(Skill skill)
|
||||
{
|
||||
return RequiredLevelArray[skill.GetLevel() - 1];
|
||||
}
|
||||
|
||||
public int GetRequiredSp(Skill skill)
|
||||
{
|
||||
return RequiredSpArray[skill.GetLevel() - 1];
|
||||
}
|
||||
|
||||
public int GetRequiredMoney(Skill skill)
|
||||
{
|
||||
return RequiredMoneyArray[skill.GetLevel() - 1];
|
||||
}
|
||||
|
||||
public float GetRadius(Skill skill)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
public float GetAttackdistance(Skill skill)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
public float GetAngle(Skill skill)
|
||||
{
|
||||
return (float)(1 - 0.0111111 * 0);
|
||||
}
|
||||
|
||||
public float GetPraydistance(Skill skill)
|
||||
{
|
||||
return (float)(10 + 0.6 * skill.GetLevel());
|
||||
}
|
||||
|
||||
#if SKILL_CLIENT
|
||||
public int GetIntroduction(Skill skill, StringBuilder buffer, int length, string format)
|
||||
{
|
||||
string result = string.Format(format,
|
||||
skill.GetLevel(),
|
||||
16 - skill.GetLevel(),
|
||||
10 + 0.6 * skill.GetLevel());
|
||||
if (result.Length < length)
|
||||
{
|
||||
buffer.Append(result);
|
||||
return result.Length;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SKILL_SERVER
|
||||
public int GetEnmity(Skill skill)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public bool StateAttack(Skill skill)
|
||||
{
|
||||
skill.GetVictim().SetProbability(1.0f * 100);
|
||||
skill.GetVictim().SetTime(2100);
|
||||
skill.GetVictim().SetRatio(0.65f);
|
||||
skill.GetVictim().SetIncdebuffdodge(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TakeEffect(Skill skill)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public float GetEffectdistance(Skill skill)
|
||||
{
|
||||
return 25f;
|
||||
}
|
||||
|
||||
public int GetAttackspeed(Skill skill)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public float GetHitrate(Skill skill)
|
||||
{
|
||||
return 1f;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ed6ddc876b1d6d4d91c7bbf94bc0c8f
|
||||
@@ -232,3 +232,4 @@ namespace BrewMonster
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -35,6 +35,13 @@ namespace BrewMonster.Scripts.World
|
||||
return pTerrain.GetPosHeight(vPos, ref pvNormal);
|
||||
}
|
||||
|
||||
public float GetWaterHeight(A3DVECTOR3 vPos)
|
||||
{
|
||||
// TODO: Hook into the actual water system once it is available.
|
||||
A3DVECTOR3 dummy = default;
|
||||
return GetTerrainHeight(vPos, ref dummy);
|
||||
}
|
||||
|
||||
public CECObject GetObject(int idObject, int iAliveFlag)
|
||||
{
|
||||
CECObject pObject = null;
|
||||
|
||||
+370
-56
@@ -1214,7 +1214,7 @@ namespace BrewMonster
|
||||
trcInfo.vExt = vExt;
|
||||
trcInfo.vStart = vTargetPos + EC_Utility.ToA3DVECTOR3(g_vAxisY) * vExt.y;
|
||||
trcInfo.vDelta = new A3DVECTOR3(0);
|
||||
if (EC_CDR.CollideWithEnv(trcInfo))
|
||||
if (EC_CDR.CollideWithEnv(ref trcInfo))
|
||||
break;
|
||||
|
||||
bAvailable = true;
|
||||
@@ -1223,6 +1223,319 @@ namespace BrewMonster
|
||||
|
||||
return bAvailable;
|
||||
}
|
||||
|
||||
private float CalcAABBOnCollidePos(A3DAABB aabbTarget)
|
||||
{
|
||||
// ¸ù¾Ý HostPlayer Óëij¶ÔÏó£¨ÈçNPC£© AABB£¬¼ÆËã AABB ³åÍ»ÁÙ½ç״̬ÏÂÁ½Õß¾àÀë (Compute the separation distance between host/player AABBs when they nearly collide)
|
||||
// ·µ»ØÖµÓ¦Êʵ±Ôö¼ÓÒ»¸öÔöÁ¿£¬¼´Àë³åͻλÖÃÉÔԶЩ (Return value should keep a slightly safer distance)
|
||||
|
||||
float fAABBCollideDist = 0.0f;
|
||||
|
||||
A3DAABB aabbHost = m_aabb;
|
||||
A3DVECTOR3 vHostHeight = new A3DVECTOR3(0.0f, aabbHost.Extents.y, 0.0f);
|
||||
A3DVECTOR3 vHostRoot = aabbHost.Center - vHostHeight;
|
||||
A3DVECTOR3 vTargetHeight = new A3DVECTOR3(0.0f, aabbTarget.Extents.y, 0.0f);
|
||||
A3DVECTOR3 vTargetRoot = aabbTarget.Center - vTargetHeight;
|
||||
|
||||
A3DVECTOR3 vRootDir = vTargetRoot - vHostRoot;
|
||||
float fRootDist = vRootDir.Normalize();
|
||||
float fMinDist = Mathf.Min(Mathf.Min(aabbHost.Extents.x, aabbHost.Extents.y), aabbHost.Extents.z);
|
||||
fMinDist = Mathf.Max(fMinDist, 0.01f);
|
||||
|
||||
if (fRootDist >= fMinDist)
|
||||
{
|
||||
A3DVECTOR3 vCenterDelta0 = aabbHost.Center - aabbTarget.Center;
|
||||
A3DVECTOR3 vTargetExt = aabbTarget.Extents;
|
||||
A3DVECTOR3 vHostExt = aabbHost.Extents;
|
||||
A3DVECTOR3 vSumExt = vTargetExt + vHostExt;
|
||||
|
||||
A3DVECTOR3 t = new A3DVECTOR3(0.0f);
|
||||
const float fZero = 0.001f;
|
||||
|
||||
if (Mathf.Abs(vRootDir.x) >= fZero)
|
||||
{
|
||||
float t1 = (vSumExt.x - vCenterDelta0.x) / vRootDir.x;
|
||||
float t2 = (vSumExt.x + vCenterDelta0.x) / -vRootDir.x;
|
||||
if (t1 >= fZero && t1 < fRootDist) t.x = t1;
|
||||
if (t2 >= fZero && t2 < fRootDist && t2 > t.x) t.x = t2;
|
||||
}
|
||||
|
||||
if (Mathf.Abs(vRootDir.y) >= fZero)
|
||||
{
|
||||
float t1 = (vSumExt.y - vCenterDelta0.y) / vRootDir.y;
|
||||
float t2 = (vSumExt.y + vCenterDelta0.y) / -vRootDir.y;
|
||||
if (t1 >= fZero && t1 < fRootDist) t.y = t1;
|
||||
if (t2 >= fZero && t2 < fRootDist && t2 > t.y) t.y = t2;
|
||||
}
|
||||
|
||||
if (Mathf.Abs(vRootDir.z) >= fZero)
|
||||
{
|
||||
float t1 = (vSumExt.z - vCenterDelta0.z) / vRootDir.z;
|
||||
float t2 = (vSumExt.z + vCenterDelta0.z) / -vRootDir.z;
|
||||
if (t1 >= fZero && t1 < fRootDist) t.z = t1;
|
||||
if (t2 >= fZero && t2 < fRootDist && t2 > t.z) t.z = t2;
|
||||
}
|
||||
|
||||
float fHostMove = 0.0f;
|
||||
if (t.x > 0.0f) fHostMove = t.x;
|
||||
if (t.y > 0.0f && t.y > fHostMove) fHostMove = t.y;
|
||||
if (t.z > 0.0f && t.z > fHostMove) fHostMove = t.z;
|
||||
|
||||
if (fHostMove > 0.0f)
|
||||
{
|
||||
fAABBCollideDist = fRootDist - fHostMove;
|
||||
}
|
||||
}
|
||||
|
||||
return fAABBCollideDist;
|
||||
}
|
||||
|
||||
private bool CalcCollideFreePos(A3DAABB aabbTarget, out A3DVECTOR3 vPos)
|
||||
{
|
||||
// ¸ù¾Ýµ±Ç° HostPlayer λÖÃÓë¸ø¶¨Ä¿±êµÄÅöײ°üΧºÐ aabbTarget£¬¼ÆËãÄ¿±ê¸½½ü(ÓëµØÐκÍ͹°ü)ÎÞ³åÍ»µÄλÖà (Find a terrain/brush free position near the target AABB)
|
||||
// vPos ´æ·ÅÎÞ³åÍ»µÄλÖ㬿ÉÓÃÓÚ SetPos (vPos stores the safe position for SetPos)
|
||||
bool bFound = false;
|
||||
vPos = default;
|
||||
|
||||
A3DAABB aabbHost = m_aabb;
|
||||
A3DVECTOR3 vHostHeight = new A3DVECTOR3(0.0f, aabbHost.Extents.y, 0.0f);
|
||||
A3DVECTOR3 vHostRoot = aabbHost.Center - vHostHeight;
|
||||
A3DVECTOR3 vTargetHeight = new A3DVECTOR3(0.0f, aabbTarget.Extents.y, 0.0f);
|
||||
A3DVECTOR3 vTargetRoot = aabbTarget.Center - vTargetHeight;
|
||||
|
||||
A3DVECTOR3 vRootDir = vTargetRoot - vHostRoot;
|
||||
float fRootDist = vRootDir.Normalize();
|
||||
float fAABBCollideDist = CalcAABBOnCollidePos(aabbTarget);
|
||||
|
||||
if (fAABBCollideDist > 0.0f)
|
||||
{
|
||||
float[] fDeltaTests = { 0.001f, 0.1f };
|
||||
foreach (float fDelta in fDeltaTests)
|
||||
{
|
||||
// ¿¼Âǵ½µØÐÎÆð·üµÈÒòËØ£¬Óëʵ¼Ê³åͻλÖÃÀ¿ªÒ»¶¨¾àÀë²¢Öð¸ö²âÊÔ£¬ÒÔÔö´ó³É¹¦·µ»Ø¼¸ÂÊ (Offset slightly to improve success probability)
|
||||
if (fRootDist > fAABBCollideDist + fDelta)
|
||||
{
|
||||
float fTestMoveDist = fRootDist - (fAABBCollideDist + fDelta);
|
||||
A3DVECTOR3 vTestPos = vHostRoot + vRootDir * fTestMoveDist;
|
||||
|
||||
// ¸ù¾ÝµØÐκÍ͹°ü½øÐÐÐÞÕý¡¢²¢²âÊÔ¿ÉÓÃÐÔ (Adjust with terrain/brush constraints and verify)
|
||||
vTestPos.y = ClampAboveGround(vTestPos);
|
||||
if (IsPosCollideFree(vTestPos))
|
||||
{
|
||||
// ºÍ͹°üÎÞÅöײ£¬Ö±½Ó¿ÉÓà (No brush collision, use directly)
|
||||
bFound = true;
|
||||
vPos = vTestPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ºÍ͹°üÓÐÅöײ£¬³¢ÊÔÔÚÊúÖ±·½ÏòÉϲéÕÒ (If still colliding, search vertically)
|
||||
if (CalcVerticalCollideFreePos(vTestPos, out A3DVECTOR3 vTestPos2))
|
||||
{
|
||||
bFound = true;
|
||||
vPos = vTestPos2;
|
||||
}
|
||||
}
|
||||
|
||||
if (bFound)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bFound;
|
||||
}
|
||||
|
||||
private bool CalcBrushOnCollidePos(A3DVECTOR3 vTestPos, A3DVECTOR3 vDelta, A3DVECTOR3 vExtents, out A3DVECTOR3 vPos, out bool bNoCollide)
|
||||
{
|
||||
// ·µ»Ø true£ºvPos ΪÎÞÅöײλÖã»Èô bNoCollide Ϊ true£¬Ôò vPos Ϊ vTestPos£»·ñÔòΪ¼ÆËã³öµÄλÖà (Return true with vPos pointing at a usable location; if bNoCollide==true the input position was already free)
|
||||
// ·µ»Ø false£ºÒâζ×Å bStartSolid = true (Return false implies we started within solid geometry)
|
||||
bool bFound = false;
|
||||
|
||||
A3DVECTOR3 vCenterHeight = new A3DVECTOR3(0.0f, vExtents.y, 0.0f);
|
||||
env_trace_t trcInfo = new env_trace_t
|
||||
{
|
||||
dwCheckFlag = EC_CDR.CDR_EVN.CDR_BRUSH,
|
||||
vExt = vExtents,
|
||||
vStart = vTestPos + vCenterHeight,
|
||||
vDelta = vDelta,
|
||||
vTerStart = vTestPos + vCenterHeight,
|
||||
vWatStart = vTestPos + vCenterHeight,
|
||||
bWaterSolid = false
|
||||
};
|
||||
|
||||
if (EC_CDR.CollideWithEnv(ref trcInfo))
|
||||
{
|
||||
bNoCollide = false;
|
||||
if (!trcInfo.bStartSolid)
|
||||
{
|
||||
vPos = trcInfo.vStart + trcInfo.fFraction * trcInfo.vDelta - vCenterHeight;
|
||||
bFound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
vPos = default;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vPos = vTestPos;
|
||||
bNoCollide = true;
|
||||
bFound = true;
|
||||
}
|
||||
|
||||
if (!bFound)
|
||||
{
|
||||
vPos = default;
|
||||
bNoCollide = false;
|
||||
}
|
||||
|
||||
return bFound;
|
||||
}
|
||||
|
||||
private bool CalcVerticalCollideFreePos(A3DVECTOR3 vRefPos, out A3DVECTOR3 vPos)
|
||||
{
|
||||
// ¼ÆËã vRefPos ¸½½üÊúÖ±·½ÏòÉÏÓë͹°ü¼°µØÐÎÎÞ³åÍ»µÄλÖà (Search along the vertical direction around vRefPos for a collision-free spot)
|
||||
// vRefPos Ϊ HostPlayer foot λÖà (vRefPos corresponds to the host's foot)
|
||||
bool bFound = false;
|
||||
vPos = default;
|
||||
|
||||
CECWorld world = CECWorld.Instance;
|
||||
if (world == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
A3DAABB hostAabb = m_aabb;
|
||||
A3DVECTOR3 vHostExts = hostAabb.Extents;
|
||||
|
||||
// ¹¹½¨ËõС°æ HostPlayer £¬ÏòÏÂѰÕÒ¿ÉÓÃλÖà (Use a shrinked collider to probe downward)
|
||||
A3DVECTOR3 vShrinkExts = new A3DVECTOR3(vHostExts.x, vHostExts.y * 0.5f, vHostExts.z);
|
||||
A3DVECTOR3 vShrinkPos = vRefPos + new A3DVECTOR3(0.0f, vHostExts.y * 0.5f, 0.0f);
|
||||
|
||||
A3DVECTOR3 vStartPos = vShrinkPos;
|
||||
A3DVECTOR3 vVerticalDelta = new A3DVECTOR3(0.0f, -1.0f, 0.0f);
|
||||
A3DVECTOR3 dummyNormal = default;
|
||||
float terrainHeight = world.GetTerrainHeight(vStartPos, ref dummyNormal);
|
||||
if (vStartPos.y < terrainHeight + 0.01f)
|
||||
{
|
||||
// ²âÊÔλÖÃÐè´¦ÓÚµØÐÎÒÔÉÏ (Candidate must be above the terrain)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!CalcBrushOnCollidePos(vStartPos, vVerticalDelta, vShrinkExts, out A3DVECTOR3 vCandidate, out bool bNoCollide))
|
||||
{
|
||||
// vStartPos ´¦ÓÚ͹°üÀï (Start position lies inside a brush)
|
||||
break;
|
||||
}
|
||||
|
||||
if (bNoCollide)
|
||||
{
|
||||
// ´Ó vStartPos µ½ vRefPos ¶¼ÎÞÅöײ£¬¿ÉÄÜÊÇ (No collision between vStartPos and vRefPos; possible cases)
|
||||
// ÇéÐÎ1£ºvRefPos ´¦Í·¶¥ÓÐ͹°üµ¼ÖÂÅöײ£¨´Ó¶øµ÷Óô˺¯ÊýÐÞÕý£© (Case1: upper brush causes the issue)
|
||||
// ÇéÐÎ2£º»òÕß vRefPos ±¾Éí¼´ÎÞÅöײ£¬Îóµ÷Óô˺¯Êý×öÖØ¸´¼ÆËã (Case2: vRefPos was already free)
|
||||
// ÇéÐÎ3£º»òÆäËüδ¿¼ÂÇÇé¿ö (Case3: other edge cases)
|
||||
// ³¢ÊԴӵײ¿Ïò vRefPos ʹÓÃÔʼ´óС HostPlayer ²éÕÒÎÞÅöײλÖã¬ÒÔ´¦ÀíÉÏÊöÇéÐÎ1 (Try again with the original extents to address case1)
|
||||
vStartPos += vVerticalDelta;
|
||||
vVerticalDelta = vRefPos - vStartPos;
|
||||
if (!CalcBrushOnCollidePos(vStartPos, vVerticalDelta, vHostExts, out vCandidate, out bNoCollide))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (bNoCollide)
|
||||
{
|
||||
vCandidate = vRefPos;
|
||||
}
|
||||
// else vCandidate ÊÇËõС°æ HostPlayer ÎÞÅöײµÄλÖã¬Ò²ÊÇʵ¼Ê´óС HostPlayer ÐÞÕý vRefPos µÄλÖà (Otherwise the computed candidate already fixes the offset)
|
||||
}
|
||||
|
||||
vCandidate.y = ClampAboveGround(vCandidate);
|
||||
if (!IsPosCollideFree(vCandidate))
|
||||
{
|
||||
// λÖóåÍ» (Still interpenetrating)
|
||||
break;
|
||||
}
|
||||
|
||||
vPos = vCandidate;
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return bFound;
|
||||
}
|
||||
|
||||
private float ClampAboveGround(A3DVECTOR3 vPos)
|
||||
{
|
||||
// ½« vPos ÏÞÖÆµ½µØÃæÒÔÉÏ (Clamp vPos above the ground)
|
||||
// ·ÉÐÐ״̬»òË®µ×ʱ£¬ÏÞÖÆÈËÎïÔÚË®ÃæÒÔÉÏ£¬ÀëË®Ãæ/µØÃæÒ»¶¨¾àÀ룻Èôµ÷Õûºó vPos ÊúÖ±ÍùÏÂÓÐ͹°ü£¬Ôò»¹»áÏÞÖÆµ½Àë͹°üÒ»¶¨¾àÀë (When flying/underwater we also keep distance from surfaces and nearby brushes)
|
||||
// ×¢Ò⣺vPos ±»µ÷Õûºó£¬ÓпÉÄÜ´¦ÓÚ͹°üÖУ»Ðè¼ì²é·µ»Ø¸ß¶Èµ÷ÕûÖµ£¬ÒÔ±ÜÃâµ÷Õû¹ý´ó (Beware of large adjustments placing us back into brushes)
|
||||
|
||||
A3DVECTOR3 vTemp = new A3DVECTOR3(vPos);
|
||||
CECWorld world = CECWorld.Instance;
|
||||
if (world == null)
|
||||
{
|
||||
return vTemp.y;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
A3DVECTOR3 dummyNormal = default;
|
||||
float fTerrainHeight = world.GetTerrainHeight(vTemp, ref dummyNormal);
|
||||
vTemp.y = EC_Utility.a_ClampFloor(vTemp.y, fTerrainHeight);
|
||||
|
||||
A3DAABB hostAabb = m_aabb;
|
||||
A3DVECTOR3 vExts = hostAabb.Extents;
|
||||
|
||||
if (IsFlying())
|
||||
{
|
||||
float fAbove = m_MoveConst.fMinAirHei;
|
||||
|
||||
// Ïȱ£Ö¤ÀëµØÃæ/Ë®ÃæÒ»¶¨¸ß¶È (Keep some height over terrain/water)
|
||||
float fWaterHeight = world.GetWaterHeight(vTemp);
|
||||
float fSurface = Mathf.Max(fTerrainHeight, fWaterHeight);
|
||||
vTemp.y = EC_Utility.a_ClampFloor(vTemp.y, fSurface + fAbove);
|
||||
|
||||
// ÔÙ³¢ÊÔÀë͹°üÒ»¶¨¸ß¶È (Then test against brushes)
|
||||
if (!CalcBrushOnCollidePos(vTemp, GPDataTypeHelper.g_vAxisY * (fSurface - vTemp.y), vExts, out A3DVECTOR3 vHitPos, out bool bNoCollide) || bNoCollide)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// ÉèÖÃÀë͹°üÒ»¶¨¸ß¶È (Clamp to stay above brushes)
|
||||
vTemp.y = EC_Utility.a_ClampFloor(vTemp.y, vHitPos.y + fAbove);
|
||||
break;
|
||||
}
|
||||
|
||||
float fWaterHeightLow = world.GetWaterHeight(vTemp);
|
||||
if (fWaterHeightLow > fTerrainHeight && vTemp.y + vExts.y < fWaterHeightLow - m_MoveConst.fWaterSurf)
|
||||
{
|
||||
// Ë®µ× (Underwater)
|
||||
float fAbove = m_MoveConst.fMinWaterHei;
|
||||
|
||||
// Ïȱ£Ö¤ÀëË®µ×Ò»¶¨¾àÀë (Keep distance from the riverbed)
|
||||
vTemp.y = EC_Utility.a_ClampFloor(vTemp.y, fTerrainHeight + fAbove);
|
||||
|
||||
// ÔÙ³¢ÊÔÀë͹°üÒ»¶¨¸ß¶È (Then ensure clearance from brushes)
|
||||
if (!CalcBrushOnCollidePos(vTemp, GPDataTypeHelper.g_vAxisY * (fTerrainHeight - vTemp.y), vExts, out A3DVECTOR3 vHitPos, out bool bNoCollide) || bNoCollide)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// ÉèÖÃÀë͹°üÒ»¶¨¸ß¶È (Clamp relative to brush hit position)
|
||||
vTemp.y = EC_Utility.a_ClampFloor(vTemp.y, vHitPos.y + fAbove);
|
||||
break;
|
||||
}
|
||||
|
||||
// µØÃæÉÏ£¬ÎÞÐèÔÙ´¦Àí (Already safe on ground)
|
||||
break;
|
||||
}
|
||||
|
||||
return vTemp.y;
|
||||
}
|
||||
public void OnMsgHstPickupItem(in ECMSG Msg)
|
||||
{
|
||||
var data = Msg.dwParam1 as byte[];
|
||||
@@ -2886,7 +3199,7 @@ namespace BrewMonster
|
||||
// 刺客如影随行类技能 (Assassin shadow-following skills)
|
||||
bool bSuccess = false;
|
||||
|
||||
do
|
||||
while (true)
|
||||
{
|
||||
// Break if no target or self-target
|
||||
if (idTarget == 0 || idTarget == GetCharacterID())
|
||||
@@ -2946,62 +3259,63 @@ namespace BrewMonster
|
||||
A3DVECTOR3 vMovePos = vHostPos + vMoveDir * (fDist - fNearDist);
|
||||
|
||||
// TODO: Implement ClampAboveGround
|
||||
// float fClampedHeight = ClampAboveGround(vMovePos);
|
||||
// if (Mathf.Abs(fClampedHeight - vMovePos.y) >= 5.0f)
|
||||
// {
|
||||
// Debug.Log("Would stuck or so");
|
||||
// break;
|
||||
// }
|
||||
// vMovePos.y = fClampedHeight;
|
||||
float fClampedHeight = ClampAboveGround(vMovePos);
|
||||
if (Mathf.Abs(fClampedHeight - vMovePos.y) >= 5.0f)
|
||||
{
|
||||
Debug.Log("Would stuck or so");
|
||||
break;
|
||||
}
|
||||
vMovePos.y = fClampedHeight;
|
||||
bool bPosVerified = false;
|
||||
|
||||
// 目标为带凸包的 NPC 时,单独处理 (Special handling for NPCs with collision)
|
||||
if (GPDataTypeHelper.ISNPCID(idTarget))
|
||||
{
|
||||
// TODO: Implement CalcCollideFreePos for NPC AABB
|
||||
// CECNPC pNPC = pObject as CECNPC;
|
||||
// A3DAABB aabbNPC;
|
||||
// if (pNPC.GetCHAABB(out aabbNPC))
|
||||
// {
|
||||
// A3DVECTOR3 vTestPos;
|
||||
// if (CalcCollideFreePos(aabbNPC, out vTestPos))
|
||||
// {
|
||||
// vMovePos = vTestPos;
|
||||
// bPosVerified = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Debug.Log("Would stuck or so");
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
CECNPC pNPC = pObject as CECNPC;
|
||||
A3DAABB aabbNPC = new A3DAABB();
|
||||
if (pNPC.GetCHAABB(ref aabbNPC))
|
||||
{
|
||||
A3DVECTOR3 vTestPos;
|
||||
if (CalcCollideFreePos(aabbNPC, out vTestPos))
|
||||
{
|
||||
vMovePos = vTestPos;
|
||||
bPosVerified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Would stuck or so");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Implement collision checking
|
||||
// if (!bPosVerified && !IsPosCollideFree(vMovePos))
|
||||
// {
|
||||
// A3DVECTOR3 vTestPos2;
|
||||
// if (!CalcVerticalCollideFreePos(vMovePos, out vTestPos2))
|
||||
// {
|
||||
// Debug.Log("Would stuck or so");
|
||||
// break;
|
||||
// }
|
||||
// vMovePos = vTestPos2;
|
||||
// bPosVerified = true;
|
||||
// }
|
||||
if (!bPosVerified && !IsPosCollideFree(vMovePos))
|
||||
{
|
||||
A3DVECTOR3 vTestPos2;
|
||||
if (!CalcVerticalCollideFreePos(vMovePos, out vTestPos2))
|
||||
{
|
||||
Debug.Log("Would stuck or so");
|
||||
break;
|
||||
}
|
||||
vMovePos = vTestPos2;
|
||||
bPosVerified = true;
|
||||
}
|
||||
|
||||
// TODO: Implement IsTooNear check for final position
|
||||
// if (IsTooNear(vMovePos))
|
||||
// {
|
||||
// Debug.Log("Target is too near");
|
||||
// break;
|
||||
// }
|
||||
//TODO: Implement IsTooNear check for final position
|
||||
float reffake = 0;
|
||||
if (IsTooNear(vMovePos, ref reffake))
|
||||
{
|
||||
Debug.Log("Target is too near");
|
||||
break;
|
||||
}
|
||||
|
||||
// 发送协议 (Send protocol)
|
||||
UnityGameSession.c2s_CmdCastPosSkill(m_pPrepSkill.GetSkillID(), EC_Utility.ToVector3(vMovePos), byPVPMask, 1, idTarget);
|
||||
bSuccess = true;
|
||||
|
||||
} while (false);
|
||||
}
|
||||
|
||||
m_pPrepSkill = null;
|
||||
return bSuccess;
|
||||
@@ -3091,24 +3405,24 @@ namespace BrewMonster
|
||||
byMask |= (byte)PVPMask.GP_PVPMASK_FORCE;
|
||||
else
|
||||
{
|
||||
/* CECConfigs pConfigs = EC_Game.GetConfigs();
|
||||
CECConfigs pConfigs = EC_Game.GetConfigs();
|
||||
|
||||
if (pConfigs.GetGameSettings().bAtk_Player)
|
||||
{
|
||||
byMask |= GP_PVPMASK_FORCE;
|
||||
if (pConfigs.GetGameSettings().bAtk_Player)
|
||||
{
|
||||
byMask |= (byte)PVPMask.GP_PVPMASK_FORCE;
|
||||
|
||||
if (pConfigs.GetGameSettings().bAtk_NoMafia)
|
||||
byMask |= GP_PVPMASK_NOMAFIA;
|
||||
if (pConfigs.GetGameSettings().bAtk_NoMafia)
|
||||
byMask |= (byte)PVPMask.GP_PVPMASK_NOMAFIA;
|
||||
|
||||
if (pConfigs.GetGameSettings().bAtk_NoWhite)
|
||||
byMask |= GP_PVPMASK_NOWHITE;
|
||||
if (pConfigs.GetGameSettings().bAtk_NoWhite)
|
||||
byMask |= (byte)PVPMask.GP_PVPMASK_NOWHITE;
|
||||
|
||||
if (pConfigs.GetGameSettings().bAtk_NoAlliance)
|
||||
byMask |= GP_PVPMASK_NOALLIANCE;
|
||||
if (pConfigs.GetGameSettings().bAtk_NoAlliance)
|
||||
byMask |= (byte)PVPMask.GP_PVPMASK_NOALLIANCE;
|
||||
|
||||
if (pConfigs.GetGameSettings().bAtk_NoForce)
|
||||
byMask |= GP_PVPMASK_NOFORCE;
|
||||
}*/
|
||||
if (pConfigs.GetGameSettings().bAtk_NoForce)
|
||||
byMask |= (byte)PVPMask.GP_PVPMASK_NOFORCE;
|
||||
}
|
||||
}
|
||||
|
||||
return byMask;
|
||||
|
||||
+10
-195
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user