Merge pull request 'Add normal attack for host player.' (#20) from feature/hp_normal_attack into develop
Reviewed-on: https://git.brew.monster/Unity/perfect-world-unity/pulls/20
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95c82a23114631b428b9fff51c373a39
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bac3638b875256b479fb1e463c6e213d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 464b57f0bb61a1143a27580c5fe83dca
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -1,42 +1,42 @@
|
||||
using UnityEngine;
|
||||
//using UnityEngine;
|
||||
|
||||
public class CECObject : MonoBehaviour
|
||||
{
|
||||
protected uint m_dwBornStamp;
|
||||
protected bool m_bBornInSight;
|
||||
protected bool m_bSelectable;
|
||||
protected int m_iCID;
|
||||
//public class CECObject : MonoBehaviour
|
||||
//{
|
||||
// protected uint m_dwBornStamp;
|
||||
// protected bool m_bBornInSight;
|
||||
// protected bool m_bSelectable;
|
||||
// protected int m_iCID;
|
||||
|
||||
public virtual void SetUpCECObject()
|
||||
{
|
||||
m_dwBornStamp = 0;
|
||||
m_bBornInSight = false;
|
||||
m_bSelectable = false;
|
||||
m_iCID = (int)ClassID.OCID_OBJECT;
|
||||
}
|
||||
public void SetBornStamp(uint dwStamp) { m_dwBornStamp = dwStamp; }
|
||||
public void SetBornInSight(bool bFlag) { m_bBornInSight = bFlag; }
|
||||
public void SetSelectable(bool bSelectable) { m_bSelectable = bSelectable; }
|
||||
public enum ClassID
|
||||
{
|
||||
OCID_OBJECT = 0,
|
||||
OCID_PLAYER,
|
||||
OCID_HOSTPLAYER,
|
||||
OCID_ELSEPLAYER,
|
||||
OCID_LOGINPLAYER,
|
||||
OCID_NPC,
|
||||
OCID_MONSTER,
|
||||
OCID_SERVER,
|
||||
OCID_MATTER,
|
||||
OCID_PET,
|
||||
OCID_CLONED_PLAYER, // 复制角色模型
|
||||
OCID_HOST_NAVIGATER, // 纯客户端player类,用于强制移动
|
||||
OCID_NPCCLONED_MASTER, // NPC 复制的角色模型
|
||||
};
|
||||
public enum EnviromentMoveType
|
||||
{
|
||||
MOVEENV_GROUND = 0, // Move on ground
|
||||
MOVEENV_WATER,
|
||||
MOVEENV_AIR,
|
||||
}
|
||||
}
|
||||
// public virtual void SetUpCECObject()
|
||||
// {
|
||||
// m_dwBornStamp = 0;
|
||||
// m_bBornInSight = false;
|
||||
// m_bSelectable = false;
|
||||
// m_iCID = (int)ClassID.OCID_OBJECT;
|
||||
// }
|
||||
// public void SetBornStamp(uint dwStamp) { m_dwBornStamp = dwStamp; }
|
||||
// public void SetBornInSight(bool bFlag) { m_bBornInSight = bFlag; }
|
||||
// public void SetSelectable(bool bSelectable) { m_bSelectable = bSelectable; }
|
||||
// public enum ClassID
|
||||
// {
|
||||
// OCID_OBJECT = 0,
|
||||
// OCID_PLAYER,
|
||||
// OCID_HOSTPLAYER,
|
||||
// OCID_ELSEPLAYER,
|
||||
// OCID_LOGINPLAYER,
|
||||
// OCID_NPC,
|
||||
// OCID_MONSTER,
|
||||
// OCID_SERVER,
|
||||
// OCID_MATTER,
|
||||
// OCID_PET,
|
||||
// OCID_CLONED_PLAYER, // 复制角色模型
|
||||
// OCID_HOST_NAVIGATER, // 纯客户端player类,用于强制移动
|
||||
// OCID_NPCCLONED_MASTER, // NPC 复制的角色模型
|
||||
// };
|
||||
// public enum EnviromentMoveType
|
||||
// {
|
||||
// MOVEENV_GROUND = 0, // Move on ground
|
||||
// MOVEENV_WATER,
|
||||
// MOVEENV_AIR,
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,15 @@
|
||||
using CSNetwork.GPDataType;
|
||||
using UnityEngine;
|
||||
|
||||
public class A3DFuncs
|
||||
{
|
||||
// Returns vector with same direction and unit length
|
||||
public static A3DVECTOR3 a3d_Normalize(A3DVECTOR3 v)
|
||||
{
|
||||
float mag = v.Magnitude();
|
||||
if (mag< 1e-12 && mag> -1e-12)
|
||||
return new A3DVECTOR3(0.0f);
|
||||
else
|
||||
return v / mag;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a1b54a25c0c92e64d8292ea30bf4f1ee
|
||||
@@ -0,0 +1,808 @@
|
||||
using CSNetwork.GPDataType;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// class A3DMATRIX3
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public struct A3DMATRIX3
|
||||
{
|
||||
// Construct flag
|
||||
public enum CONSTRUCT
|
||||
{
|
||||
IDENTITY = 0, // Construct a identity matrix
|
||||
CLEARED, // Construct a cleared matrix
|
||||
}
|
||||
|
||||
//float _11, _12, _13;
|
||||
//float _21, _22, _23;
|
||||
//float _31, _32, _33;
|
||||
|
||||
public float[] m;
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return new float[9] {
|
||||
// _11, _12, _13,
|
||||
// _21, _22, _23,
|
||||
// _31, _32, _33
|
||||
// };
|
||||
// }
|
||||
// set
|
||||
// {
|
||||
// if (value.Length != 9 )
|
||||
// throw new ArgumentException("Matrix must be 9");
|
||||
// _11 = value[0]; _12 = value[1]; _13 = value[2];
|
||||
// _21 = value[3]; _22 = value[lenght]; _23 = value[5];
|
||||
// _31 = value[6]; _32 = value[7]; _33 = value[8];
|
||||
// }
|
||||
//}
|
||||
|
||||
//public A3DMATRIX3() { }
|
||||
|
||||
public A3DMATRIX3(CONSTRUCT c)
|
||||
{
|
||||
if (c == CONSTRUCT.IDENTITY)
|
||||
{
|
||||
m = new float[9]{
|
||||
1.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f
|
||||
};
|
||||
}
|
||||
else/* if (c == CONSTRUCT.CLEARED)*/
|
||||
{
|
||||
m = new float[9]{
|
||||
0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public A3DMATRIX3(float[,] arr)
|
||||
{
|
||||
m = new float[9]{
|
||||
arr[0, 0], arr[0, 1], arr[0, 2],
|
||||
arr[1, 0], arr[1, 1], arr[1, 2],
|
||||
arr[2, 0], arr[2, 1], arr[2, 2]
|
||||
};
|
||||
}
|
||||
|
||||
public A3DMATRIX3(A3DMATRIX3 rkMatrix)
|
||||
{
|
||||
m = new float[9]{
|
||||
rkMatrix.m[0], rkMatrix.m[1], rkMatrix.m[2],
|
||||
rkMatrix.m[3], rkMatrix.m[4], rkMatrix.m[5],
|
||||
rkMatrix.m[6], rkMatrix.m[7], rkMatrix.m[8]
|
||||
};
|
||||
}
|
||||
|
||||
public A3DMATRIX3(float fEntry00, float fEntry01, float fEntry02,
|
||||
float fEntry10, float fEntry11, float fEntry12,
|
||||
float fEntry20, float fEntry21, float fEntry22)
|
||||
{
|
||||
m = new float[9]{
|
||||
fEntry00, fEntry01, fEntry02,
|
||||
fEntry10, fEntry11, fEntry12,
|
||||
fEntry20, fEntry21, fEntry22
|
||||
};
|
||||
}
|
||||
// Operations
|
||||
|
||||
public A3DVECTOR3 GetRow(int i) { int row = i * 3; return new A3DVECTOR3(m[row + 0], m[row + 1], m[row + 2]); }
|
||||
public A3DVECTOR3 GetCol(int i) { return new A3DVECTOR3(m[i + (0 * 3)], m[i + (1 * 3)], m[i + (2 * 3)]); }
|
||||
|
||||
// * operator
|
||||
public static A3DVECTOR3 operator *(A3DVECTOR3 v, A3DMATRIX3 mat)
|
||||
{
|
||||
return new A3DVECTOR3(v.x * mat.m[0] + v.y * mat.m[3] + v.z * mat.m[6],
|
||||
v.x * mat.m[1] + v.y * mat.m[4] + v.z * mat.m[7],
|
||||
v.x * mat.m[2] + v.y * mat.m[5] + v.z * mat.m[8]);
|
||||
}
|
||||
public static A3DVECTOR3 operator *(A3DMATRIX3 mat, A3DVECTOR3 v)
|
||||
{
|
||||
return new A3DVECTOR3(v.x * mat.m[0] + v.y * mat.m[3] + v.z * mat.m[6],
|
||||
v.x * mat.m[1] + v.y * mat.m[4] + v.z * mat.m[7],
|
||||
v.x * mat.m[2] + v.y * mat.m[5] + v.z * mat.m[8]);
|
||||
}
|
||||
public static A3DMATRIX3 operator *(A3DMATRIX3 mat1, A3DMATRIX3 mat2)
|
||||
{
|
||||
A3DMATRIX3 matRet = new A3DMATRIX3();
|
||||
int lenght = 3;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
for (int k = 0; k < 3; k++)
|
||||
matRet.m[(i * lenght) + j] += mat1.m[(i * lenght) + k] * mat2.m[(k * lenght) + j];
|
||||
}
|
||||
}
|
||||
return matRet;
|
||||
}
|
||||
|
||||
// *= operator
|
||||
public A3DMATRIX3 MultiplyAssign(A3DMATRIX3 mat)
|
||||
{
|
||||
A3DMATRIX3 temp = this * mat;
|
||||
Array.Copy(temp.m, this.m, temp.m.Length);
|
||||
return this;
|
||||
}
|
||||
|
||||
void Transpose()
|
||||
{
|
||||
float t;
|
||||
t = m[1]; m[1] = m[3]; m[3] = t;
|
||||
t = m[2]; m[2] = m[6]; m[6] = t;
|
||||
t = m[5]; m[5] = m[7]; m[7] = t;
|
||||
}
|
||||
|
||||
// Clear all elements to zero
|
||||
void Clear()
|
||||
{
|
||||
m = new float[9]{
|
||||
0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f
|
||||
};
|
||||
}
|
||||
// Set matrix to identity matrix
|
||||
void Identity()
|
||||
{
|
||||
m = new float[9] {
|
||||
1.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f
|
||||
};
|
||||
}
|
||||
|
||||
// Build matrix to be translation and rotation matrix
|
||||
void Translate(float x, float y)
|
||||
{
|
||||
Identity();
|
||||
m[6] = x;
|
||||
m[7] = y;
|
||||
}
|
||||
void Rotate(float fRad)
|
||||
{
|
||||
Identity();
|
||||
m[4] = m[0] = (float)Math.Cos(fRad);
|
||||
m[1] = (float)Math.Cos(fRad);
|
||||
m[3] = -m[1];
|
||||
}
|
||||
}
|
||||
|
||||
public struct D3DXVECTOR3
|
||||
{
|
||||
public float X;
|
||||
public float Y;
|
||||
public float Z;
|
||||
|
||||
// Constructors
|
||||
public D3DXVECTOR3(float x, float y, float z)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
}
|
||||
|
||||
public D3DXVECTOR3(float[] v)
|
||||
{
|
||||
if (v == null || v.Length < 3) throw new ArgumentException("Array must have at least 3 elements.");
|
||||
X = v[0];
|
||||
Y = v[1];
|
||||
Z = v[2];
|
||||
}
|
||||
|
||||
public D3DXVECTOR3(D3DXVECTOR3 v)
|
||||
{
|
||||
X = v.X;
|
||||
Y = v.Y;
|
||||
Z = v.Z;
|
||||
}
|
||||
|
||||
// Unary operators
|
||||
public static D3DXVECTOR3 operator +(D3DXVECTOR3 v) => v;
|
||||
public static D3DXVECTOR3 operator -(D3DXVECTOR3 v) => new D3DXVECTOR3(-v.X, -v.Y, -v.Z);
|
||||
|
||||
// Binary operators
|
||||
public static D3DXVECTOR3 operator +(D3DXVECTOR3 a, D3DXVECTOR3 b) =>
|
||||
new D3DXVECTOR3(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
|
||||
|
||||
public static D3DXVECTOR3 operator -(D3DXVECTOR3 a, D3DXVECTOR3 b) =>
|
||||
new D3DXVECTOR3(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
|
||||
|
||||
public static D3DXVECTOR3 operator *(D3DXVECTOR3 v, float s) =>
|
||||
new D3DXVECTOR3(v.X * s, v.Y * s, v.Z * s);
|
||||
|
||||
public static D3DXVECTOR3 operator *(float s, D3DXVECTOR3 v) => v * s;
|
||||
|
||||
public static D3DXVECTOR3 operator /(D3DXVECTOR3 v, float s)
|
||||
{
|
||||
if (s == 0f) throw new DivideByZeroException();
|
||||
return new D3DXVECTOR3(v.X / s, v.Y / s, v.Z / s);
|
||||
}
|
||||
|
||||
// Assignment-style operators
|
||||
public static D3DXVECTOR3 Add(ref D3DXVECTOR3 a, D3DXVECTOR3 b)
|
||||
{
|
||||
a.X += b.X; a.Y += b.Y; a.Z += b.Z;
|
||||
return a;
|
||||
}
|
||||
|
||||
public static D3DXVECTOR3 Subtract(ref D3DXVECTOR3 a, D3DXVECTOR3 b)
|
||||
{
|
||||
a.X -= b.X; a.Y -= b.Y; a.Z -= b.Z;
|
||||
return a;
|
||||
}
|
||||
|
||||
public static D3DXVECTOR3 Multiply(ref D3DXVECTOR3 v, float s)
|
||||
{
|
||||
v.X *= s; v.Y *= s; v.Z *= s;
|
||||
return v;
|
||||
}
|
||||
|
||||
public static D3DXVECTOR3 Divide(ref D3DXVECTOR3 v, float s)
|
||||
{
|
||||
if (s == 0f) throw new DivideByZeroException();
|
||||
v.X /= s; v.Y /= s; v.Z /= s;
|
||||
return v;
|
||||
}
|
||||
|
||||
// Comparison operators
|
||||
public static bool operator ==(D3DXVECTOR3 a, D3DXVECTOR3 b) =>
|
||||
a.X == b.X && a.Y == b.Y && a.Z == b.Z;
|
||||
|
||||
public static bool operator !=(D3DXVECTOR3 a, D3DXVECTOR3 b) =>
|
||||
!(a == b);
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is D3DXVECTOR3 v) return this == v;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode() => HashCode.Combine(X, Y, Z);
|
||||
|
||||
// Magnitude and Normalize
|
||||
public float Magnitude() => (float)Math.Sqrt(X * X + Y * Y + Z * Z);
|
||||
|
||||
public D3DXVECTOR3 Normalize()
|
||||
{
|
||||
float mag = Magnitude();
|
||||
if (Math.Abs(mag) < 1e-12f) return new D3DXVECTOR3(0f, 0f, 0f);
|
||||
return this / mag;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// class A3DMATRIX4
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public struct A3DMATRIX4
|
||||
{
|
||||
// Construct flag
|
||||
public enum CONSTRUCT
|
||||
{
|
||||
IDENTITY = 0, // Construct a identity matrix
|
||||
}
|
||||
|
||||
//float _11, _12, _13, _14;
|
||||
//float _21, _22, _23, _24;
|
||||
//float _31, _32, _33, _34;
|
||||
//float _41, _42, _43, _44;
|
||||
|
||||
public float[] m;
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return new float[16] {
|
||||
// _11, _12, _13, _14,
|
||||
// _21, _22, _23, _24,
|
||||
// _31, _32, _33, _34,
|
||||
// _41, _42, _43, _44
|
||||
// };
|
||||
// }
|
||||
// set
|
||||
// {
|
||||
// if (value.Length != 16)
|
||||
// throw new ArgumentException("Matrix must be range 16");
|
||||
// _11 = value[0]; _12 = value[1]; _13 = value[2]; _14 = value[3];
|
||||
// _21 = value[4]; _22 = value[5]; _23 = value[6]; _24 = value[7];
|
||||
// _31 = value[8]; _32 = value[9]; _33 = value[10]; _34 = value[11];
|
||||
// _41 = value[12]; _42 = value[13]; _43 = value[14]; _44 = value[15];
|
||||
// }
|
||||
//}
|
||||
|
||||
// Constructions and Destructions
|
||||
|
||||
public A3DMATRIX4(float[] v)
|
||||
{
|
||||
m = new float[16];
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
m[i] = v[i];
|
||||
}
|
||||
}
|
||||
|
||||
public A3DMATRIX4(A3DMATRIX4 mat)
|
||||
{
|
||||
float _11 = mat.m[0], _12 = mat.m[1], _13 = mat.m[2], _14 = mat.m[3];
|
||||
float _21 = mat.m[4], _22 = mat.m[5], _23 = mat.m[6], _24 = mat.m[7];
|
||||
float _31 = mat.m[8], _32 = mat.m[9], _33 = mat.m[10], _34 = mat.m[11];
|
||||
float _41 = mat.m[12], _42 = mat.m[13], _43 = mat.m[14], _44 = mat.m[15];
|
||||
m = new float[16] {
|
||||
_11, _12, _13, _14,
|
||||
_21, _22, _23, _24,
|
||||
_31, _32, _33, _34,
|
||||
_41, _42, _43, _44
|
||||
};
|
||||
}
|
||||
|
||||
public A3DMATRIX4(CONSTRUCT c)
|
||||
{
|
||||
m = new float[16] {
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
}
|
||||
|
||||
public A3DMATRIX4(float fEntry00, float fEntry01, float fEntry02, float fEntry03,
|
||||
float fEntry10, float fEntry11, float fEntry12, float fEntry13,
|
||||
float fEntry20, float fEntry21, float fEntry22, float fEntry23,
|
||||
float fEntry30, float fEntry31, float fEntry32, float fEntry33)
|
||||
{
|
||||
m = new float[16] {
|
||||
fEntry00, fEntry01, fEntry02, fEntry03,
|
||||
fEntry10, fEntry11, fEntry12, fEntry13,
|
||||
fEntry20, fEntry21, fEntry22, fEntry23,
|
||||
fEntry30, fEntry31, fEntry32, fEntry33
|
||||
};
|
||||
}
|
||||
// Operaitons
|
||||
|
||||
// Get row and column
|
||||
public A3DVECTOR3 GetRow(int i) { int row = i * 4; return new A3DVECTOR3(m[row + 0], m[row + 1], m[row + 2]); }
|
||||
public A3DVECTOR3 GetCol(int i) { return new A3DVECTOR3(m[(0 * 4) + i], m[(1 * 4) + i], m[(2 * 4) + i]); }
|
||||
// Set row and column
|
||||
public void SetRow(int i, A3DVECTOR3 v) { int row = i * 4; m[row + 0] = v.x; m[row + 1] = v.y; m[row + 2] = v.z; }
|
||||
public void SetCol(int i, A3DVECTOR3 v) { m[(0 * 3) + i] = v.x; m[(1 * 3) + i] = v.y; m[(2 * 3) + i] = v.z; }
|
||||
|
||||
// * operator
|
||||
public static A3DVECTOR3 operator *(A3DVECTOR3 v, A3DMATRIX4 mat)
|
||||
{
|
||||
A3DVECTOR3 vRet = new A3DVECTOR3(v.x * mat.m[0] + v.y * mat.m[4] + v.z * mat.m[8] + mat.m[12],
|
||||
v.x * mat.m[1] + v.y * mat.m[5] + v.z * mat.m[9] + mat.m[13],
|
||||
v.x * mat.m[2] + v.y * mat.m[6] + v.z * mat.m[10] + mat.m[14]);
|
||||
float w = 1.0f / (v.x * mat.m[3] + v.y * mat.m[7] + v.z * mat.m[11] + mat.m[15]);
|
||||
return vRet *= w;
|
||||
}
|
||||
public static A3DVECTOR3 operator *(A3DMATRIX4 mat, A3DVECTOR3 v)
|
||||
{
|
||||
A3DVECTOR3 vRet = new A3DVECTOR3(v.x * mat.m[0] + v.y * mat.m[4] + v.z * mat.m[8] + mat.m[12],
|
||||
v.x * mat.m[1] + v.y * mat.m[5] + v.z * mat.m[9] + mat.m[13],
|
||||
v.x * mat.m[2] + v.y * mat.m[6] + v.z * mat.m[10] + mat.m[14]);
|
||||
float w = 1.0f / (v.x * mat.m[3] + v.y * mat.m[7] + v.z * mat.m[11] + mat.m[15]);
|
||||
return vRet *= w;
|
||||
}
|
||||
|
||||
|
||||
public static A3DVECTOR4 operator *(A3DVECTOR4 v, A3DMATRIX4 mat)
|
||||
{
|
||||
return new A3DVECTOR4(v.m[0] * mat.m[0] + v.m[1] * mat.m[4] + v.m[2] * mat.m[8] + v.m[3] * mat.m[12],
|
||||
v.m[0] * mat.m[1] + v.m[1] * mat.m[5] + v.m[2] * mat.m[9] + v.m[3] * mat.m[13],
|
||||
v.m[0] * mat.m[2] + v.m[1] * mat.m[6] + v.m[2] * mat.m[10] + v.m[0] * mat.m[14],
|
||||
v.m[0] * mat.m[3] + v.m[1] * mat.m[7] + v.m[2] * mat.m[11] + v.m[3] * mat.m[15]);
|
||||
}
|
||||
public static A3DVECTOR4 operator *(A3DMATRIX4 mat, A3DVECTOR4 v)
|
||||
{
|
||||
return new A3DVECTOR4(v.m[0] * mat.m[0] + v.m[1] * mat.m[4] + v.m[2] * mat.m[8] + v.m[3] * mat.m[12],
|
||||
v.m[0] * mat.m[1] + v.m[1] * mat.m[5] + v.m[2] * mat.m[9] + v.m[3] * mat.m[13],
|
||||
v.m[0] * mat.m[2] + v.m[1] * mat.m[6] + v.m[2] * mat.m[10] + v.m[3] * mat.m[14],
|
||||
v.m[0] * mat.m[3] + v.m[1] * mat.m[7] + v.m[2] * mat.m[11] + v.m[3] * mat.m[15]);
|
||||
}
|
||||
public static A3DMATRIX4 operator *(A3DMATRIX4 mat1, A3DMATRIX4 mat2)
|
||||
{
|
||||
A3DMATRIX4 matRet = new A3DMATRIX4();
|
||||
int lenght = 4;
|
||||
for (int i = 0; i < lenght; i++)
|
||||
{
|
||||
for (int j = 0; j < lenght; j++)
|
||||
{
|
||||
for (int k = 0; k < lenght; k++)
|
||||
//matRet.m[i,j] += mat1.m[i,k] * mat2.m[k,j];
|
||||
matRet.m[(i * lenght) + j] += mat1.m[(i * lenght) + k] * mat2.m[(k * lenght) + j];
|
||||
|
||||
}
|
||||
}
|
||||
return matRet;
|
||||
}
|
||||
|
||||
// Scale matrix
|
||||
public static A3DMATRIX4 operator *(A3DMATRIX4 mat, float s)
|
||||
{
|
||||
A3DMATRIX4 matRet = new A3DMATRIX4();
|
||||
int lenght = 4;
|
||||
for (int i = 0; i < lenght; i++)
|
||||
{
|
||||
for (int j = 0; j < lenght; j++)
|
||||
matRet.m[(i * lenght) + j] = mat.m[(i * lenght) + j] * s;
|
||||
}
|
||||
|
||||
return matRet;
|
||||
}
|
||||
public static A3DMATRIX4 operator *(float s, A3DMATRIX4 mat) { return mat * s; }
|
||||
public static A3DMATRIX4 operator /(A3DMATRIX4 mat, float s) { return mat * (1.0f / s); }
|
||||
|
||||
// *= operator
|
||||
public A3DMATRIX4 MultiplyAssign(A3DMATRIX4 mat)
|
||||
{
|
||||
A3DMATRIX4 temp = this * mat;
|
||||
Array.Copy(temp.m, this.m, temp.m.Length);
|
||||
return this;
|
||||
}
|
||||
public A3DMATRIX4 MultiplyAssign(float s)
|
||||
{
|
||||
A3DMATRIX4 temp = this;
|
||||
int lenght = 4;
|
||||
for (int i = 0; i < lenght; i++)
|
||||
{
|
||||
for (int j = 0; j < lenght; j++)
|
||||
m[(i * lenght) + j] *= s;
|
||||
}
|
||||
Array.Copy(temp.m, this.m, temp.m.Length);
|
||||
return this;
|
||||
}
|
||||
// /= operator
|
||||
public A3DMATRIX4 DivisionAssign(float s) { return MultiplyAssign(1.0f / s); }
|
||||
|
||||
// == operator
|
||||
public static bool operator ==(A3DMATRIX4 mat1, A3DMATRIX4 mat2)
|
||||
{
|
||||
int lenght = 4;
|
||||
for (int i = 0; i < lenght; i++)
|
||||
{
|
||||
for (int j = 0; j < lenght; j++)
|
||||
{
|
||||
if (mat1.m[(i * lenght) + j] != mat2.m[(i * lenght) + j])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// != operator
|
||||
public static bool operator !=(A3DMATRIX4 mat1, A3DMATRIX4 mat2)
|
||||
{
|
||||
int lenght = 4;
|
||||
for (int i = 0; i < lenght; i++)
|
||||
{
|
||||
for (int j = 0; j < lenght; j++)
|
||||
{
|
||||
if (mat1.m[(i * lenght) + j] != mat2.m[(i * lenght) + j])
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// + operator
|
||||
public static A3DMATRIX4 operator +(A3DMATRIX4 mat1, A3DMATRIX4 mat2)
|
||||
{
|
||||
A3DMATRIX4 matRet = new A3DMATRIX4();
|
||||
int lenght = 4;
|
||||
for (int i = 0; i < lenght; i++)
|
||||
{
|
||||
for (int j = 0; j < lenght; j++)
|
||||
matRet.m[(i * lenght) + j] = mat1.m[(i * lenght) + j] + mat2.m[(i * lenght) + j];
|
||||
}
|
||||
return matRet;
|
||||
}
|
||||
// - operator
|
||||
public static A3DMATRIX4 operator -(A3DMATRIX4 mat1, A3DMATRIX4 mat2)
|
||||
{
|
||||
int lenght = 4;
|
||||
A3DMATRIX4 matRet = new A3DMATRIX4();
|
||||
for (int i = 0; i < lenght; i++)
|
||||
{
|
||||
for (int j = 0; j < lenght; j++)
|
||||
matRet.m[(i * lenght) + j] = mat1.m[(i * lenght) + j] - mat2.m[(i * lenght) + j];
|
||||
}
|
||||
|
||||
return matRet;
|
||||
}
|
||||
// += operator
|
||||
public A3DMATRIX4 AdditionAssign(A3DMATRIX4 mat)
|
||||
{
|
||||
int lenght = 4;
|
||||
A3DMATRIX4 temp = this;
|
||||
for (int i = 0; i < lenght; i++)
|
||||
{
|
||||
for (int j = 0; j < lenght; j++)
|
||||
m[(i * lenght) + j] += mat.m[(i * lenght) + j];
|
||||
}
|
||||
Array.Copy(temp.m, this.m, temp.m.Length);
|
||||
return this;
|
||||
}
|
||||
// -= operator
|
||||
public A3DMATRIX4 SubtractionAssign(A3DMATRIX4 mat)
|
||||
{
|
||||
int lenght = 4;
|
||||
A3DMATRIX4 temp = this;
|
||||
for (int i = 0; i < lenght; i++)
|
||||
{
|
||||
for (int j = 0; j < lenght; j++)
|
||||
m[(i * lenght) + j] -= mat.m[(i * lenght) + j];
|
||||
}
|
||||
Array.Copy(temp.m, this.m, temp.m.Length);
|
||||
return this;
|
||||
}
|
||||
|
||||
// Clear all elements to zero
|
||||
public void Clear()
|
||||
{
|
||||
m = new float[16] {
|
||||
0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f
|
||||
};
|
||||
}
|
||||
// Set matrix to identity matrix
|
||||
public void Identity()
|
||||
{
|
||||
m = new float[16] {
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
}
|
||||
// Transpose matrix
|
||||
public void Transpose()
|
||||
{
|
||||
float t = 0f;
|
||||
t = m[1]; m[1] = m[4]; m[4] = t;
|
||||
t = m[2]; m[2] = m[8]; m[8] = t;
|
||||
t = m[3]; m[3] = m[12]; m[2] = t;
|
||||
t = m[6]; m[6] = m[9]; m[9] = t;
|
||||
t = m[7]; m[7] = m[13]; m[3] = t;
|
||||
t = m[11]; m[11] = m[4]; m[4] = t;
|
||||
}
|
||||
// Get transpose matrix of this matrix
|
||||
public A3DMATRIX4 GetTranspose()
|
||||
{
|
||||
int lenght = 4;
|
||||
A3DMATRIX4 matRet = new A3DMATRIX4();
|
||||
for (int i = 0; i < lenght; i++)
|
||||
{
|
||||
for (int j = 0; j < lenght; j++)
|
||||
matRet.m[(i * lenght) + j] = m[(j * lenght) + i];
|
||||
}
|
||||
|
||||
return matRet;
|
||||
}
|
||||
// Inverse matrix
|
||||
// void Inverse() { *this = GetInverse(); }
|
||||
// Get inverse matrix of this matrix
|
||||
// A3DMATRIX4 GetInverse() const;
|
||||
// Inverse matrix (used only by transform matrix)
|
||||
public void InverseTM()
|
||||
{
|
||||
A3DMATRIX4 temp = GetInverseTM();
|
||||
Array.Copy(temp.m, this.m, temp.m.Length);
|
||||
}
|
||||
// Get inverse matrix (used only by transform matrix)
|
||||
public A3DMATRIX4 GetInverseTM()
|
||||
{
|
||||
float _11 = m[0], _12 = m[1], _13 = m[2], _14 = m[3];
|
||||
float _21 = m[4], _22 = m[5], _23 = m[6], _24 = m[7];
|
||||
float _31 = m[8], _32 = m[9], _33 = m[10], _34 = m[11];
|
||||
float _41 = m[12], _42 = m[13], _43 = m[14], _44 = m[15];
|
||||
|
||||
float fDet = 1.0f / Det3x3(_11, _12, _13, _21, _22, _23, _31, _32, _33);
|
||||
|
||||
A3DMATRIX4 mat = new A3DMATRIX4();
|
||||
|
||||
mat.m[0] = fDet * Det3x3(_22, _23, _24, _32, _33, _34, _42, _43, _44);
|
||||
mat.m[1] = -fDet * Det3x3(_12, _13, _14, _32, _33, _34, _42, _43, _44);
|
||||
mat.m[2] = fDet * Det3x3(_12, _13, _14, _22, _23, _24, _42, _43, _44);
|
||||
mat.m[3] = -fDet * Det3x3(_12, _13, _14, _22, _23, _24, _32, _33, _34);
|
||||
|
||||
mat.m[4] = -fDet * Det3x3(_21, _23, _24, _31, _33, _34, _41, _43, _44);
|
||||
mat.m[5] = fDet * Det3x3(_11, _13, _14, _31, _33, _34, _41, _43, _44);
|
||||
mat.m[6] = -fDet * Det3x3(_11, _13, _14, _21, _23, _24, _41, _43, _44);
|
||||
mat.m[7] = fDet * Det3x3(_11, _13, _14, _21, _23, _24, _31, _33, _34);
|
||||
|
||||
mat.m[8] = fDet * Det3x3(_21, _22, _24, _31, _32, _34, _41, _42, _44);
|
||||
mat.m[9] = -fDet * Det3x3(_11, _12, _14, _31, _32, _34, _41, _42, _44);
|
||||
mat.m[10] = fDet * Det3x3(_11, _12, _14, _21, _22, _24, _41, _42, _44);
|
||||
mat.m[11] = -fDet * Det3x3(_11, _12, _14, _21, _22, _24, _31, _32, _34);
|
||||
|
||||
mat.m[12] = -fDet * Det3x3(_21, _22, _23, _31, _32, _33, _41, _42, _43);
|
||||
mat.m[13] = fDet * Det3x3(_11, _12, _13, _31, _32, _33, _41, _42, _43);
|
||||
mat.m[14] = -fDet * Det3x3(_11, _12, _13, _21, _22, _23, _41, _42, _43);
|
||||
mat.m[15] = fDet * Det3x3(_11, _12, _13, _21, _22, _23, _31, _32, _33);
|
||||
|
||||
return mat;
|
||||
}
|
||||
// Get determinant of this matrix
|
||||
public float Determinant()
|
||||
{
|
||||
float _11 = m[0], _12 = m[1], _13 = m[2], _14 = m[3];
|
||||
float _21 = m[4], _22 = m[5], _23 = m[6], _24 = m[7];
|
||||
float _31 = m[8], _32 = m[9], _33 = m[10], _34 = m[11];
|
||||
float _41 = m[12], _42 = m[13], _43 = m[14], _44 = m[15];
|
||||
|
||||
float fDet = 0f;
|
||||
fDet = _11 * _22 * _33 * _44;
|
||||
fDet += _21 * _32 * _43 * _14;
|
||||
fDet += _31 * _42 * _13 * _24;
|
||||
fDet += _41 * _12 * _23 * _34;
|
||||
fDet -= _41 * _32 * _23 * _14;
|
||||
fDet -= _42 * _33 * _24 * _11;
|
||||
fDet -= _43 * _34 * _21 * _12;
|
||||
fDet -= _44 * _31 * _22 * _13;
|
||||
return fDet;
|
||||
}
|
||||
|
||||
// Build matrix to be translation and rotation matrix
|
||||
public void Translate(float x, float y, float z)
|
||||
{
|
||||
Identity();
|
||||
m[12] = x;
|
||||
m[13] = y;
|
||||
m[14] = z;
|
||||
}
|
||||
public void RotateX(float fRad)
|
||||
{
|
||||
Identity();
|
||||
m[10] = m[5] = Mathf.Cos(fRad);
|
||||
m[6] = Mathf.Sin(fRad);
|
||||
m[9] = -m[6];
|
||||
}
|
||||
public void RotateY(float fRad)
|
||||
{
|
||||
Identity();
|
||||
m[10] = m[0] = Mathf.Cos(fRad);
|
||||
m[8] = Mathf.Sin(fRad);
|
||||
m[2] = -m[8];
|
||||
}
|
||||
public void RotateZ(float fRad)
|
||||
{
|
||||
Identity();
|
||||
m[5] = m[0] = Mathf.Cos(fRad);
|
||||
m[1] = Mathf.Sin(fRad);
|
||||
m[4] = -m[1];
|
||||
}
|
||||
public void RotateAxis(A3DVECTOR3 v, float fRad)
|
||||
{
|
||||
float fCos = Mathf.Cos(fRad);
|
||||
float fSin = Mathf.Sin(fRad);
|
||||
|
||||
m[0] = (v.x * v.x) * (1.0f - fCos) + fCos;
|
||||
m[4] = (v.x * v.y) * (1.0f - fCos) - (v.z * fSin);
|
||||
m[8] = (v.x * v.x) * (1.0f - fCos) + (v.y * fSin);
|
||||
|
||||
m[1] = (v.y * v.y) * (1.0f - fCos) + (v.z * fSin);
|
||||
m[5] = (v.y * v.y) * (1.0f - fCos) + fCos;
|
||||
m[9] = (v.y * v.z) * (1.0f - fCos) - (v.x * fSin);
|
||||
|
||||
m[2] = (v.z * v.x) * (1.0f - fCos) - (v.y * fSin);
|
||||
m[6] = (v.z * v.y) * (1.0f - fCos) + (v.x * fSin);
|
||||
m[10] = (v.z * v.z) * (1.0f - fCos) + fCos;
|
||||
|
||||
m[3] = m[7] = m[11] = 0.0f;
|
||||
m[12] = m[13] = m[14] = 0.0f;
|
||||
m[15] = 1.0f;
|
||||
}
|
||||
public void RotateAxis(A3DVECTOR3 vPos, A3DVECTOR3 vAxis, float fRad)
|
||||
{
|
||||
Translate(-vPos.x, -vPos.y, -vPos.z);
|
||||
|
||||
A3DMATRIX4 mat = new A3DMATRIX4();
|
||||
mat.RotateAxis(vAxis, fRad);
|
||||
MultiplyAssign(mat);
|
||||
mat.Translate(vPos.x, vPos.y, vPos.z);
|
||||
MultiplyAssign(mat);
|
||||
}
|
||||
public void Scale(float sx, float sy, float sz)
|
||||
{
|
||||
Clear();
|
||||
m[0] = sx;
|
||||
m[5] = sy;
|
||||
m[10] = sz;
|
||||
m[15] = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
// Calcualte determinant of a 3x3 matrix
|
||||
public float Det3x3(float a11, float a12, float a13, float a21, float a22, float a23,
|
||||
float a31, float a32, float a33)
|
||||
{
|
||||
return a11 * a22 * a33 + a21 * a32 * a13 + a31 * a12 * a23 -
|
||||
a13 * a22 * a31 - a23 * a32 * a11 - a33 * a12 * a21;
|
||||
}
|
||||
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// class A3DVECTOR4
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public struct A3DVECTOR4
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
|
||||
public float[] m;
|
||||
//{
|
||||
// get => new float[] { x, y, z, w };
|
||||
// set
|
||||
// {
|
||||
// if (value == null || value.Length < 4)
|
||||
// throw new ArgumentException("Array must have at least 4 elements.");
|
||||
// x = value[0];
|
||||
// y = value[1];
|
||||
// z = value[2];
|
||||
// w = value[3];
|
||||
// }
|
||||
//}
|
||||
|
||||
// Constructors and Destructors
|
||||
public A3DVECTOR4(float _x, float _y, float _z, float _w)
|
||||
{
|
||||
x = _x;
|
||||
y = _y;
|
||||
z = _z;
|
||||
w = _w;
|
||||
m = new float[] { x, y, z, w };
|
||||
}
|
||||
public A3DVECTOR4(float f)
|
||||
{
|
||||
x = y = z = w = f;
|
||||
m = new float[] { x, y, z, w };
|
||||
}
|
||||
public A3DVECTOR4(float[] f)
|
||||
{
|
||||
if (f == null || f.Length < 4)
|
||||
throw new ArgumentException("Array must have at least 4 elements.");
|
||||
x = f[0]; y = f[1]; z = f[2]; w = f[3];
|
||||
m = new float[] { x, y, z, w };
|
||||
}
|
||||
public A3DVECTOR4(A3DVECTOR4 v)
|
||||
{
|
||||
x = v.x; y = v.y; z = v.z; w = v.w;
|
||||
m = new float[] { x, y, z, w };
|
||||
}
|
||||
public A3DVECTOR4(A3DVECTOR3 v)
|
||||
{
|
||||
x = v.x; y = v.y; z = v.z; w = 1.0f;
|
||||
m = new float[] { x, y, z, w };
|
||||
}
|
||||
|
||||
// Operations
|
||||
|
||||
// = operator
|
||||
public A3DVECTOR4 assignment(A3DVECTOR4 v)
|
||||
{
|
||||
x = v.x; y = v.y; z = v.z; w = v.w; return this;
|
||||
}
|
||||
public A3DVECTOR4 assignment(A3DVECTOR3 v) { x = v.x; y = v.y; z = v.z; w = 1.0f; return this; }
|
||||
|
||||
public void Set(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; }
|
||||
public void Clear() { x = y = z = w = 0.0f; }
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc8e1e1d27a1f8f4e8995615fba55f2b
|
||||
@@ -7,9 +7,6 @@ using System.Buffers.Binary;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
using UnityEngine.LightTransport;
|
||||
using static CECNPC;
|
||||
using static CECObject;
|
||||
|
||||
public class CECNPCMan : CECObject, IMsgHandler
|
||||
{
|
||||
@@ -21,7 +18,7 @@ public class CECNPCMan : CECObject, IMsgHandler
|
||||
public CECNPCMan()
|
||||
{
|
||||
m_vServerPos = Vector3.zero;
|
||||
m_iCID = (int)ClassID.OCID_MONSTER;
|
||||
m_iCID = (int)Class_ID.OCID_MONSTER;
|
||||
}
|
||||
public bool ProcessMessage(ECMSG Msg)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,674 @@
|
||||
using System.Security.Cryptography;
|
||||
using Unity.VisualScripting;
|
||||
using WorkList = System.Collections.Generic.List<CECHPWork>;
|
||||
|
||||
public class CECHPWork : CECObjectWork
|
||||
{
|
||||
// Host work ID
|
||||
public static class Host_work_ID
|
||||
{
|
||||
public const int WORK_INVALID = -1,
|
||||
WORK_STAND = 0, // Stand and do nothing
|
||||
WORK_MOVETOPOS = 1, // Move to a destination terrain position
|
||||
WORK_TRACEOBJECT = 2, // Trace specified object (NPC, player etc.)
|
||||
WORK_HACKOBJECT = 3, // Hack specified object (NPC, player etc.)
|
||||
WORK_SPELLOBJECT = 4, // Spell magic on specified object (NPC, player etc.)
|
||||
WORK_USEITEM = 5, // Host use item
|
||||
WORK_DEAD = 6, // Host is dead
|
||||
WORK_FOLLOW = 7, // Follow some one else
|
||||
WORK_FLYOFF = 8, // Fly off
|
||||
WORK_FREEFALL = 9, // Free fall
|
||||
WORK_SIT = 10, // Sit
|
||||
WORK_PICKUP = 11, // Pickup item
|
||||
WORK_CONCENTRATE = 12, // All concentrate work
|
||||
WORK_REVIVE = 13, // Revive
|
||||
WORK_FLASHMOVE = 14, // Flash move
|
||||
WORK_BEBOUND = 15, // Be bound by buddy
|
||||
WORK_PASSIVEMOVE = 16, // Passive movement (knock back / pull)
|
||||
WORK_CONGREGATE = 17, // Congregate reply
|
||||
WORK_SKILLSTATEACT = 18, // skill buff action
|
||||
WORK_FORCENAVIGATEMOVE = 19, // force navigate move
|
||||
NUM_WORK = 20;
|
||||
}
|
||||
|
||||
protected static class Work_mask
|
||||
{
|
||||
public const uint MASK_STAND = 0x0001,
|
||||
MASK_MOVETOPOS = 0x0002,
|
||||
MASK_TRACEOBJECT = 0x0004,
|
||||
MASK_HACKOBJECT = 0x0008,
|
||||
MASK_SPELLOBJECT = 0x0010,
|
||||
MASK_USEITEM = 0x0020,
|
||||
MASK_DEAD = 0x0040,
|
||||
MASK_FOLLOW = 0x0080,
|
||||
MASK_FLYOFF = 0x0100,
|
||||
MASK_FREEFALL = 0x0200,
|
||||
MASK_SIT = 0x0400,
|
||||
MASK_PICKUP = 0x0800,
|
||||
MASK_CONCENTRATE = 0x1000,
|
||||
MASK_REVIVE = 0x2000,
|
||||
MASK_FLASHMOVE = 0x4000,
|
||||
MASK_BEBOUND = 0x8000,
|
||||
MASK_CONGREGATE = 0x10000,
|
||||
MASK_SKILLSTATEACT = 0x20000,
|
||||
MASK_FORCENAVIGATE = 0x40000;
|
||||
public const uint MASK_ALLWORK = 0xffffffff;
|
||||
}
|
||||
|
||||
protected CECHPWorkMan m_pWorkMan; // Work manager
|
||||
protected CECHostPlayer m_pHost; // Host player object
|
||||
|
||||
public CECHPWork(int iWorkID, CECHPWorkMan pWorkMan) : base(iWorkID)
|
||||
{
|
||||
m_pWorkMan = pWorkMan;
|
||||
m_pHost = pWorkMan.GetHostPlayer();
|
||||
}
|
||||
|
||||
// Operations
|
||||
// Override from CECObjectWork
|
||||
public virtual void Cancel()
|
||||
{
|
||||
|
||||
}
|
||||
// This work is do player moving ?
|
||||
public virtual bool IsMoving()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Copy work data
|
||||
public virtual bool CopyData(CECHPWork pWork)
|
||||
{
|
||||
m_bFinished = pWork.m_bFinished;
|
||||
m_bFirstTick = pWork.m_bFirstTick;
|
||||
return true;
|
||||
}
|
||||
|
||||
public string GetWorkName()
|
||||
{
|
||||
return GetWorkName(GetWorkID());
|
||||
}
|
||||
public static uint GetWorkMask(int iWorkID)
|
||||
{
|
||||
if (!Validate(iWorkID))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint[] l_workMask = new uint[]{
|
||||
Work_mask.MASK_STAND,
|
||||
Work_mask.MASK_MOVETOPOS,
|
||||
Work_mask.MASK_TRACEOBJECT,
|
||||
Work_mask.MASK_HACKOBJECT,
|
||||
Work_mask.MASK_SPELLOBJECT,
|
||||
Work_mask.MASK_USEITEM,
|
||||
Work_mask.MASK_DEAD,
|
||||
Work_mask.MASK_FOLLOW,
|
||||
Work_mask.MASK_FLYOFF,
|
||||
Work_mask.MASK_FREEFALL,
|
||||
Work_mask.MASK_SIT,
|
||||
Work_mask.MASK_PICKUP,
|
||||
Work_mask.MASK_CONCENTRATE,
|
||||
Work_mask.MASK_REVIVE,
|
||||
Work_mask.MASK_FLASHMOVE,
|
||||
Work_mask.MASK_BEBOUND,
|
||||
Work_mask.MASK_CONGREGATE,
|
||||
Work_mask.MASK_SKILLSTATEACT,
|
||||
Work_mask.MASK_FORCENAVIGATE,
|
||||
};
|
||||
return l_workMask[iWorkID];
|
||||
}
|
||||
public static bool Validate(int iWorkID)
|
||||
{
|
||||
return iWorkID >= 0 && iWorkID < Host_work_ID.NUM_WORK;
|
||||
}
|
||||
|
||||
public static string GetWorkName(int iWorkID)
|
||||
{
|
||||
string[] l_WorkName = new string[Host_work_ID.NUM_WORK]
|
||||
{
|
||||
"WORK_STAND",
|
||||
"WORK_MOVETOPOS",
|
||||
"WORK_TRACEOBJECT",
|
||||
"WORK_HACKOBJECT",
|
||||
"WORK_SPELLOBJECT",
|
||||
"WORK_USEITEM",
|
||||
"WORK_DEAD",
|
||||
"WORK_FOLLOW",
|
||||
"WORK_FLYOFF",
|
||||
"WORK_FREEFALL",
|
||||
"WORK_SIT",
|
||||
"WORK_PICKUP",
|
||||
"WORK_CONCENTRATE",
|
||||
"WORK_REVIVE",
|
||||
"WORK_FLASHMOVE",
|
||||
"WORK_BEBOUND",
|
||||
"WORK_PASSIVEMOVE",
|
||||
"WORK_CONGREGATE",
|
||||
"WORK_SKILLSTATEACT",
|
||||
"WORK_FORCENAVIGATEMOVE"
|
||||
};
|
||||
if (Validate(iWorkID))
|
||||
{
|
||||
return l_WorkName[iWorkID];
|
||||
}
|
||||
else if (iWorkID == Host_work_ID.WORK_INVALID)
|
||||
{
|
||||
return "WORK_INVALID";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class CECHPWorkMan
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
public class CECHPWorkMan
|
||||
{
|
||||
// Work priority
|
||||
public static class Work_priority
|
||||
{
|
||||
public const int PRIORITY_0 = 0,
|
||||
PRIORITY_1 = 1,
|
||||
PRIORITY_2 = 2,
|
||||
NUM_PRIORITY = 3;
|
||||
};
|
||||
|
||||
// Delayed work info.
|
||||
public struct DELAYWORK
|
||||
{
|
||||
public int iPriority;
|
||||
public CECHPWork pWork;
|
||||
}
|
||||
|
||||
private CECHostPlayer m_pHost;
|
||||
private WorkList[] m_WorkStack = new WorkList[Work_priority.NUM_PRIORITY];
|
||||
private int m_iCurPriority;
|
||||
private DELAYWORK m_Delayed;
|
||||
private CECHPWorkPostTickCommand m_pPostTickCommand;
|
||||
|
||||
public CECHPWorkMan(CECHostPlayer pHost)
|
||||
{
|
||||
m_pHost = pHost;
|
||||
m_iCurPriority = -1;
|
||||
m_Delayed = new DELAYWORK
|
||||
{
|
||||
iPriority = 0,
|
||||
pWork = null
|
||||
};
|
||||
m_pPostTickCommand = null;
|
||||
}
|
||||
|
||||
public CECHPWork GetRunningWork(int iWorkID)
|
||||
{
|
||||
CECHPWork result = null;
|
||||
if (ValidatePriority(m_iCurPriority))
|
||||
{
|
||||
WorkList workList = m_WorkStack[m_iCurPriority];
|
||||
for (int i = 0; i < workList.Count; ++i)
|
||||
{
|
||||
if (iWorkID == workList[i].GetWorkID())
|
||||
{
|
||||
result = workList[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public CECHPWork GetWork(int iWorkID, int iPriority = Work_priority.PRIORITY_1, bool bIncludeDelayedWork = false)
|
||||
{
|
||||
CECHPWorkGeneralMatcher cECHPWork = new CECHPWorkGeneralMatcher(iWorkID, iPriority, bIncludeDelayedWork);
|
||||
return GetWork(cECHPWork);
|
||||
}
|
||||
public CECHPWork GetWork(CECHPWorkMatcher matcher)
|
||||
{
|
||||
CECHPWork result = null;
|
||||
for (int i = (Work_priority.NUM_PRIORITY - 1); i >= 0; --i)
|
||||
{
|
||||
WorkList workList = m_WorkStack[i];
|
||||
for (int j = 0; j < workList.Count; ++j)
|
||||
{
|
||||
CECHPWork pWork = workList[j];
|
||||
if (matcher.Match(pWork, i, false))
|
||||
{
|
||||
result = pWork;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result == null && GetDelayedWork() != null && matcher.Match(m_Delayed.pWork, m_Delayed.iPriority, true))
|
||||
{
|
||||
result = GetDelayedWork();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool InternallyStartWork(int iPriority, CECHPWork pWork)
|
||||
{
|
||||
bool bStarted = false;
|
||||
if (CanRunSimultaneouslyWithCurrentWork(iPriority, pWork))
|
||||
{
|
||||
WorkList workList = m_WorkStack[iPriority];
|
||||
workList.Add(pWork);
|
||||
bStarted = true;
|
||||
//LOG_DEBUG_INFO(AString().Format("CECHPWork::%s started simultaneously, priority=%d", pWork->GetWorkName(), iPriority));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pWork.GetWorkID() == CECHPWork.Host_work_ID.WORK_DEAD)
|
||||
{
|
||||
for (int i = iPriority; i < Work_priority.NUM_PRIORITY; i++)
|
||||
{
|
||||
FinishWorkAtPriority(i);
|
||||
}
|
||||
ClearDelayedWork();
|
||||
WorkList workList = m_WorkStack[iPriority];
|
||||
workList.Add(pWork);
|
||||
m_iCurPriority = iPriority;
|
||||
bStarted = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool shouldStart = (iPriority >= m_iCurPriority);
|
||||
FinishWorkAtPriority(iPriority);
|
||||
WorkList workList = m_WorkStack[iPriority];
|
||||
workList.Add(pWork);
|
||||
if (shouldStart)
|
||||
{
|
||||
if (iPriority > m_iCurPriority)
|
||||
{
|
||||
CancelWorkAtPriority(m_iCurPriority);
|
||||
}
|
||||
m_iCurPriority = iPriority;
|
||||
bStarted = true;
|
||||
}
|
||||
}
|
||||
//if (bStarted)
|
||||
//{
|
||||
// LOG_DEBUG_INFO(AString().Format("CECHPWork::%s started, priority=%d", pWork->GetWorkName(), iPriority));
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// LOG_DEBUG_INFO(AString().Format("CECHPWork::%s add to priority queue %d", pWork->GetWorkName(), iPriority));
|
||||
//}
|
||||
}
|
||||
return bStarted;
|
||||
}
|
||||
bool CanRunSimultaneouslyWithCurrentWork(int iPriority, CECHPWork pWork)
|
||||
{
|
||||
if (!ValidatePriority(iPriority) || iPriority != m_iCurPriority)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
WorkList workList = m_WorkStack[iPriority];
|
||||
if (workList == null || workList.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var work in workList)
|
||||
{
|
||||
if (!CanRunSimultaneously(work, pWork))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool CanRunSimultaneously(CECHPWork pWork1, CECHPWork pWork2)
|
||||
{
|
||||
if (pWork1.GetWorkID() == CECHPWork.Host_work_ID.WORK_MOVETOPOS &&
|
||||
pWork2.GetWorkID() == CECHPWork.Host_work_ID.WORK_SPELLOBJECT)
|
||||
{
|
||||
return CanSpellWhileMoving(pWork2 as CECHPWorkSpell);
|
||||
}
|
||||
if (pWork2.GetWorkID() == CECHPWork.Host_work_ID.WORK_MOVETOPOS &&
|
||||
pWork1.GetWorkID() == CECHPWork.Host_work_ID.WORK_SPELLOBJECT)
|
||||
{
|
||||
return CanSpellWhileMoving(pWork1 as CECHPWorkSpell);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool CanSpellWhileMoving(CECHPWorkSpell pWorkSpell)
|
||||
{
|
||||
//return pWorkSpell.GetSkill()
|
||||
// && CECCastSkillWhenMove::Instance().IsSkillSupported(pWorkSpell->GetSkill()->GetSkillID(), m_pHost);
|
||||
return false;
|
||||
}
|
||||
void StartAwaitingWorks()
|
||||
{
|
||||
if (ValidatePriority(m_iCurPriority))
|
||||
{
|
||||
for (--m_iCurPriority; m_iCurPriority >= 0; --m_iCurPriority)
|
||||
{
|
||||
WorkList workList = m_WorkStack[m_iCurPriority];
|
||||
if (workList == null || workList.Count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
foreach (var work in workList)
|
||||
{
|
||||
work.OnWorkShift();
|
||||
//LOG_DEBUG_INFO(AString().Format("CECHPWork::%s started by decrease priority, priority=%d", workList[j]->GetWorkName(), m_iCurPriority));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
StartDelayedWork();
|
||||
}
|
||||
|
||||
void FinishWorkAtPriority(int iPriority)
|
||||
{
|
||||
if (!ValidatePriority(iPriority))
|
||||
{
|
||||
return;
|
||||
}
|
||||
WorkList workList = m_WorkStack[iPriority];
|
||||
while ((workList != null && workList.Count > 0))
|
||||
{
|
||||
KillWork(iPriority, 0);
|
||||
}
|
||||
if (m_iCurPriority == iPriority)
|
||||
{
|
||||
m_iCurPriority = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void KillWork(int iPriority, int index)
|
||||
{
|
||||
if (!ValidatePriority(iPriority))
|
||||
{
|
||||
return;
|
||||
}
|
||||
WorkList workList = m_WorkStack[iPriority];
|
||||
if (index < 0 || index >= workList.Count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CECHPWork pWork = workList[index];
|
||||
KillWork(pWork);
|
||||
//LOG_DEBUG_INFO(AString().Format("CECHPWork::%s priority=%d killed", pWork->GetWorkName(), iPriority));
|
||||
//delete pWork;
|
||||
workList.RemoveAt(index);
|
||||
}
|
||||
void KillWork(CECHPWork pWork)
|
||||
{
|
||||
if (pWork == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (pWork.GetWorkID() == CECHPWork.Host_work_ID.WORK_MOVETOPOS)
|
||||
{
|
||||
CECHPWorkMove pWorkMove = pWork as CECHPWorkMove;
|
||||
if (pWorkMove != null)
|
||||
{
|
||||
if (pWorkMove.GetAutoMove())
|
||||
{
|
||||
//pWorkMove.Finish();
|
||||
}
|
||||
else
|
||||
{
|
||||
pWorkMove.Cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pWork.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelWork(CECHPWork pWork)
|
||||
{
|
||||
|
||||
}
|
||||
public void CancelWorkAtPriority(int iPriority)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool DelayWork(int iPriority, CECHPWork pWork)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public void StartDelayedWork()
|
||||
{
|
||||
|
||||
}
|
||||
public void ClearDelayedWork()
|
||||
{
|
||||
|
||||
}
|
||||
public CECHPWork GetDelayedWork()
|
||||
{
|
||||
return m_Delayed.pWork;
|
||||
}
|
||||
|
||||
public bool ValidatePriority(int iPriority)
|
||||
{
|
||||
return iPriority >= 0 && iPriority < Work_priority.NUM_PRIORITY;
|
||||
}
|
||||
|
||||
public bool StartWork(int iPriority, CECHPWork pWork, bool bNoDelay = false)
|
||||
{
|
||||
if (pWork == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!ValidatePriority(iPriority))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//if (pWork.GetWorkID() == CECHPWork.Host_work_ID.WORK_TRACEOBJECT)
|
||||
//{
|
||||
// if (g_pGame->GetGameRun()->GetHostInputFilter()->IsMoveUsagePressed())
|
||||
// {
|
||||
// CECHPWorkTrace pWorkTrace = pWork as CECHPWorkTrace;
|
||||
// if (!pWorkTrace.CanTouch())
|
||||
// { // 2014-8-16 当还在通过键盘操纵移动时、有条件忽略 CECHPWorkTrace,
|
||||
// //delete pWorkTrace; // 否则会因 CECHPWorkTrace 中临时转向目标位置、而后又被键盘操纵调整移动方向导致方向瞬间抖动
|
||||
// return false; // 当 CECHPWorkTrace 中目标可立即接触时,不忽略 CECHPWorkTrace,以实现键盘控制移动中、对某怪应用技能时,立刻转向怪施放技能
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
if (!bNoDelay && DelayWork(iPriority, pWork))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return InternallyStartWork(iPriority, pWork);
|
||||
}
|
||||
public bool StartWork_p0(CECHPWork pWork, bool bNoDelay = false) { return StartWork(Work_priority.PRIORITY_0, pWork, bNoDelay); }
|
||||
public bool StartWork_p1(CECHPWork pWork, bool bNoDelay = false) { return StartWork(Work_priority.PRIORITY_1, pWork, bNoDelay); }
|
||||
public bool StartWork_p2(CECHPWork pWork, bool bNoDelay = false) { return StartWork(Work_priority.PRIORITY_2, pWork, bNoDelay); }
|
||||
public CECHostPlayer GetHostPlayer() { return m_pHost; }
|
||||
|
||||
public CECHPWork CreateWork(int idWork)
|
||||
{
|
||||
CECHPWork pWork = null;
|
||||
|
||||
switch (idWork)
|
||||
{
|
||||
//case CECHPWork.Host_work_ID.WORK_STAND: pWork = new CECHPWorkStand(this); break;
|
||||
case CECHPWork.Host_work_ID.WORK_MOVETOPOS: pWork = new CECHPWorkMove(this); break;
|
||||
case CECHPWork.Host_work_ID.WORK_TRACEOBJECT: pWork = new CECHPWorkTrace(this); break;
|
||||
case CECHPWork.Host_work_ID.WORK_HACKOBJECT: pWork = new CECHPWorkMelee(this); break;
|
||||
case CECHPWork.Host_work_ID.WORK_SPELLOBJECT: pWork = new CECHPWorkSpell(this); break;
|
||||
//case CECHPWork.Host_work_ID.WORK_USEITEM: pWork = new CECHPWorkUse(this); break;
|
||||
//case CECHPWork.Host_work_ID.WORK_DEAD: pWork = new CECHPWorkDead(this); break;
|
||||
//case CECHPWork.Host_work_ID.WORK_FOLLOW: pWork = new CECHPWorkFollow(this); break;
|
||||
//case CECHPWork.Host_work_ID.WORK_FLYOFF: pWork = new CECHPWorkFly(this); break;
|
||||
//case CECHPWork.Host_work_ID.WORK_FREEFALL: pWork = new CECHPWorkFall(this); break;
|
||||
//case CECHPWork.Host_work_ID.WORK_SIT: pWork = new CECHPWorkSit(this); break;
|
||||
//case CECHPWork.Host_work_ID.WORK_PICKUP: pWork = new CECHPWorkPick(this); break;
|
||||
//case CECHPWork.Host_work_ID.WORK_CONCENTRATE: pWork = new CECHPWorkConcentrate(this); break;
|
||||
//case CECHPWork.Host_work_ID.WORK_REVIVE: pWork = new CECHPWorkRevive(this); break;
|
||||
//case CECHPWork.Host_work_ID.WORK_FLASHMOVE: pWork = new CECHPWorkFMove(this); break;
|
||||
//case CECHPWork.Host_work_ID.WORK_BEBOUND: pWork = new CECHPWorkBeBound(this); break;
|
||||
//case CECHPWork.Host_work_ID.WORK_PASSIVEMOVE: pWork = new CECHPWorkPassiveMove(this); break;
|
||||
//case CECHPWork.Host_work_ID.WORK_CONGREGATE: pWork = new CECHPWorkCongregate(this); break;
|
||||
//case CECHPWork.Host_work_ID.WORK_SKILLSTATEACT: pWork = new CECHPWorkSkillStateAction(this); break;
|
||||
//case CECHPWork.Host_work_ID.WORK_FORCENAVIGATEMOVE: pWork = new CECHPWorkNavigate(this); break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
return pWork;
|
||||
}
|
||||
|
||||
public bool CanStartWork(int iWorkID, int iPriority = CECHPWorkMan.Work_priority.PRIORITY_1)
|
||||
{
|
||||
if (!ValidatePriority(iPriority))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (GetWork(iWorkID) != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!HasWorkOnPriority(iPriority))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
WorkList workList = m_WorkStack[iPriority];
|
||||
for (int i = 0; i < workList.Count; ++i)
|
||||
{
|
||||
if (!workList[i].CanTransferTo(CECHPWork.GetWorkMask(iWorkID)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HasWorkOnPriority(int iPriority)
|
||||
{
|
||||
return ValidatePriority(iPriority) && m_WorkStack[iPriority].Count != 0;
|
||||
}
|
||||
|
||||
public void SetPostTickCommand(CECHPWorkPostTickCommand command)
|
||||
{
|
||||
m_pPostTickCommand = command;
|
||||
}
|
||||
|
||||
bool HasWorkRunningOnPriority(int iPriority){
|
||||
return HasWorkOnPriority(iPriority);
|
||||
}
|
||||
bool IsAnyWorkRunning(){
|
||||
return HasWorkRunningOnPriority(m_iCurPriority);
|
||||
}
|
||||
|
||||
public void Tick(float dwDeltaTime)
|
||||
{
|
||||
if (!IsAnyWorkRunning())
|
||||
{
|
||||
return;
|
||||
}
|
||||
WorkList workList = m_WorkStack[m_iCurPriority];
|
||||
for (int i = 0; i < workList.Count;)
|
||||
{
|
||||
CECHPWork pWork = workList[i];
|
||||
|
||||
SetPostTickCommand(null);
|
||||
pWork.Tick(dwDeltaTime);
|
||||
|
||||
if (m_pPostTickCommand == null)
|
||||
{
|
||||
if (!pWork.IsFinished())
|
||||
{
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
KillWork(m_iCurPriority, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pPostTickCommand.Run(this);
|
||||
SetPostTickCommand(null);
|
||||
break; // 不确定 m_pPostTickCommand 执行什么内容,此处跳出
|
||||
}
|
||||
}
|
||||
if (workList.Count == 0)
|
||||
{
|
||||
StartAwaitingWorks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class CECHPWorkPostTickCommand
|
||||
{
|
||||
public abstract bool Run(CECHPWorkMan pWorkMan);
|
||||
};
|
||||
|
||||
public abstract class CECHPWorkMatcher
|
||||
{
|
||||
public abstract bool Match(CECHPWork pWork, int priority, bool isDelayWork);
|
||||
};
|
||||
|
||||
public class CECHPWorkGeneralMatcher : CECHPWorkMatcher
|
||||
{
|
||||
int m_workID;
|
||||
int m_priority;
|
||||
bool m_matchDelayedWork;
|
||||
|
||||
public override bool Match(CECHPWork pWork, int priority, bool isDelayWork)
|
||||
{
|
||||
return pWork != null
|
||||
&& pWork.GetWorkID() == m_workID
|
||||
&& priority == m_priority
|
||||
&& isDelayWork == m_matchDelayedWork;
|
||||
}
|
||||
|
||||
public CECHPWorkGeneralMatcher(int workID, int priority, bool bIncludeDelayedWork)
|
||||
{
|
||||
m_workID = workID;
|
||||
m_priority = priority;
|
||||
m_matchDelayedWork = bIncludeDelayedWork;
|
||||
}
|
||||
}
|
||||
|
||||
public class CECHPWorkPostTickRunWorkCommand : CECHPWorkPostTickCommand
|
||||
{
|
||||
CECHPWork m_pWork;
|
||||
int m_iPriority;
|
||||
bool m_bNoDelay;
|
||||
bool m_bShouldTick;
|
||||
uint m_dwTickTime;
|
||||
|
||||
// Constructor
|
||||
public CECHPWorkPostTickRunWorkCommand(
|
||||
CECHPWork pWork,
|
||||
bool bNoDelay = false,
|
||||
int iPriority = CECHPWorkMan.Work_priority.PRIORITY_1,
|
||||
bool bShouldTick = false,
|
||||
uint dwTickTime = 0)
|
||||
{
|
||||
m_pWork = pWork;
|
||||
m_bNoDelay = bNoDelay;
|
||||
m_iPriority = iPriority;
|
||||
m_bShouldTick = bShouldTick;
|
||||
m_dwTickTime = dwTickTime;
|
||||
}
|
||||
|
||||
public override bool Run(CECHPWorkMan pWorkMan)
|
||||
{
|
||||
if (m_pWork == null || pWorkMan == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!pWorkMan.StartWork(m_iPriority, m_pWork, m_bNoDelay))
|
||||
{
|
||||
m_pWork = null;
|
||||
return false;
|
||||
}
|
||||
if (m_bShouldTick)
|
||||
{
|
||||
m_pWork.Tick(m_dwTickTime);
|
||||
}
|
||||
m_pWork = null;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de7b8e482be7d8347b45ab9751adae44
|
||||
@@ -0,0 +1,155 @@
|
||||
using BrewMonster;
|
||||
using BrewMonster.Network;
|
||||
using CSNetwork.GPDataType;
|
||||
using PerfectWorld.Scripts.Managers;
|
||||
using PerfectWorld.Scripts.Player;
|
||||
using UnityEngine;
|
||||
|
||||
class CECHPWorkPostTickCommand1 : CECHPWorkPostTickRunWorkCommand
|
||||
{
|
||||
public CECHPWorkPostTickCommand1(CECHPWork pWork) : base(pWork, true)
|
||||
{
|
||||
}
|
||||
public virtual bool Run(CECHPWorkMan pWorkMan)
|
||||
{
|
||||
if (!base.Run(pWorkMan))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//AP_ActionEvent(AP_EVENT_MELEEOUTOFRANGE);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class CECHPWorkMelee
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CECHPWorkMelee : CECHPWork
|
||||
{
|
||||
protected int m_idTarget; // Target id
|
||||
protected int m_iIdleTime; // Idle time
|
||||
protected int m_iIdleTimeCnt; // Idle time counter
|
||||
|
||||
// Constructor and Destructor
|
||||
public CECHPWorkMelee(CECHPWorkMan pWorkMan) : base(Host_work_ID.WORK_HACKOBJECT, pWorkMan)
|
||||
{
|
||||
m_dwMask = Work_mask.MASK_HACKOBJECT;
|
||||
m_dwTransMask = Work_mask.MASK_STAND | Work_mask.MASK_MOVETOPOS | Work_mask.MASK_TRACEOBJECT;
|
||||
Reset();
|
||||
}
|
||||
|
||||
// Tick routine
|
||||
public virtual bool Tick(float dwDeltaTime)
|
||||
{
|
||||
base.Tick(dwDeltaTime);
|
||||
|
||||
if (m_idTarget != 0 || m_idTarget == m_pHost.m_PlayerInfo.cid)
|
||||
{
|
||||
m_bFinished = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// If target turn to be un-attackable, cancel action
|
||||
if (m_pHost.AttackableJudge(m_idTarget, true) == 0)
|
||||
{
|
||||
UnityGameSession.c2s_CmdCancelAction();
|
||||
//g_pGame.GetGameSession().c2s_CmdCancelAction();
|
||||
m_bFinished = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_iIdleTimeCnt < m_iIdleTime)
|
||||
{
|
||||
m_iIdleTimeCnt += (int)dwDeltaTime;
|
||||
if (m_iIdleTimeCnt < m_iIdleTime)
|
||||
return true;
|
||||
|
||||
m_iIdleTimeCnt = m_iIdleTime;
|
||||
}
|
||||
|
||||
// Face to target
|
||||
//m_pHost.TurnFaceTo(m_idTarget);
|
||||
|
||||
int idTraceTarget = 0;
|
||||
|
||||
if (GPDataTypeHelper.ISPLAYERID(m_idTarget))
|
||||
{
|
||||
EC_ElsePlayer pPlayer = EC_ManMessageMono.Instance.GetECManPlayer.GetElsePlayer(m_idTarget);
|
||||
if (!pPlayer || pPlayer.IsDead()) // Taget has missed ?
|
||||
return true;
|
||||
|
||||
// if (!m_pHost.CanTouchTarget(pPlayer.GetServerPos(), pPlayer.GetTouchRadius(), 1, 0.8f))
|
||||
if (!m_pHost.CanTouchTarget(pPlayer.GetPos(), pPlayer.GetTouchRadius(), 1))
|
||||
idTraceTarget = m_idTarget;
|
||||
}
|
||||
else if (GPDataTypeHelper.ISNPCID(m_idTarget))
|
||||
{
|
||||
CECNPC pNPC = EC_ManMessageMono.Instance._CECNPCMan.GetNPC(m_idTarget);
|
||||
if (!pNPC || pNPC.IsDead()) // Taget has missed ?
|
||||
return true;
|
||||
|
||||
if (!m_pHost.CanTouchTarget(pNPC.GetPos(), pNPC.GetTouchRadius(), 1))
|
||||
idTraceTarget = m_idTarget;
|
||||
}
|
||||
|
||||
if (idTraceTarget != 0 && !m_pHost.IsRooting())
|
||||
{
|
||||
CECHPWorkTrace pWork = (CECHPWorkTrace)m_pWorkMan.CreateWork(Host_work_ID.WORK_TRACEOBJECT);
|
||||
pWork.SetTraceTarget(pWork.CreatTraceTarget(idTraceTarget, CECHPWorkTrace.Trace_reason.TRACE_ATTACK));
|
||||
m_pWorkMan.SetPostTickCommand(new CECHPWorkPostTickCommand1(pWork));
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// Reset work
|
||||
public virtual void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
|
||||
m_idTarget = 0;
|
||||
m_iIdleTime = 0;
|
||||
m_iIdleTimeCnt = 0;
|
||||
}
|
||||
// Copy work data
|
||||
public virtual bool CopyData(CECHPWork pWork)
|
||||
{
|
||||
if (!base.CopyData(pWork))
|
||||
return false;
|
||||
|
||||
CECHPWorkMelee pSrc = (CECHPWorkMelee)pWork;
|
||||
|
||||
m_idTarget = pSrc.m_idTarget;
|
||||
m_iIdleTime = pSrc.m_iIdleTime;
|
||||
m_iIdleTimeCnt = pSrc.m_iIdleTimeCnt;
|
||||
|
||||
return true;
|
||||
}
|
||||
public virtual void Cancel()
|
||||
{
|
||||
// TO DO: fix later
|
||||
//m_pHost.TurnFaceTo(0);
|
||||
}
|
||||
|
||||
// Get attack target
|
||||
public int GetTarget() { return m_idTarget; }
|
||||
// Set idle time
|
||||
public void SetIdleTime(int iTime)
|
||||
{
|
||||
m_iIdleTime = iTime;
|
||||
m_iIdleTimeCnt = 0;
|
||||
}
|
||||
// Get idle time
|
||||
public int GetIdleTime() { return m_iIdleTime; }
|
||||
|
||||
// On first tick
|
||||
protected virtual void OnFirstTick()
|
||||
{
|
||||
m_pHost.m_iMoveMode = (int)MoveMode.MOVE_STAND;
|
||||
m_pHost.PlayAction((int)EC_Player.PLAYER_ACTION_TYPE.ACT_ATTACK_1 + Random.Range(0, 3), true, 200, false);
|
||||
|
||||
m_idTarget = m_pHost.m_idSelTarget;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 387c716aaa1c40b4cb343fa662a973e2
|
||||
@@ -0,0 +1,367 @@
|
||||
using CSNetwork.GPDataType;
|
||||
using UnityEngine;
|
||||
|
||||
public class CECHPWorkMove : CECHPWork
|
||||
{
|
||||
public static class Types
|
||||
{
|
||||
public const int DEST_2D = 0,
|
||||
DEST_3D = 1,
|
||||
DEST_DIR = 2,
|
||||
DEST_PUSH = 3,
|
||||
DEST_STANDJUMP = 4,
|
||||
DEST_AUTOPF = 5; // Movement type
|
||||
}
|
||||
|
||||
protected A3DVECTOR3 m_vMoveDest; // Move destination position or direction
|
||||
protected int m_iDestType; // Destination type
|
||||
protected bool m_bHaveDest; // true, have destination
|
||||
protected bool m_bMeetSlide; // true, meet slide
|
||||
protected A3DVECTOR3 m_vCurDir; // Current move direction
|
||||
protected bool m_bReadyCancel; // true, ready to cancel
|
||||
protected bool m_bGliding; // glide
|
||||
protected float m_fGlideTime;
|
||||
protected float m_fGlideSpan;
|
||||
protected float m_fGlideAng;
|
||||
protected float m_fGlideVel; // glide angular vel
|
||||
protected float m_fGlidePitch; // glide pitch angle
|
||||
protected float m_fCurPitch;
|
||||
protected float m_fPushPitch;
|
||||
protected float m_fPushLean;
|
||||
|
||||
protected bool m_bUseAutoMoveDialog; // Auto move
|
||||
protected float m_fAutoHeight; // Height of auto moving destination
|
||||
protected bool m_bAutoLand; // Auto land when arrive at destination
|
||||
protected bool m_bAutoFly; // Auto fly
|
||||
protected bool m_bReachedHeight;// Player reached specified height
|
||||
protected bool m_bAutoFlyPending; // Mark whether a fly command had been executed
|
||||
|
||||
protected int m_iNPCTempleId;
|
||||
protected int m_iTaskId;
|
||||
protected bool m_bSwitchTo2D;
|
||||
|
||||
protected bool m_bResetAutoPF;
|
||||
|
||||
public CECHPWorkMove(CECHPWorkMan pWorkMan) : base (Host_work_ID.WORK_MOVETOPOS, pWorkMan)
|
||||
{
|
||||
m_dwMask = Work_mask.MASK_MOVETOPOS;
|
||||
m_dwTransMask = Work_mask.MASK_STAND | Work_mask.MASK_TRACEOBJECT | Work_mask.MASK_FOLLOW;
|
||||
Reset();
|
||||
}
|
||||
|
||||
public CECHPWorkMove(int iWorkID, CECHPWorkMan pWorkMan) : base(iWorkID, pWorkMan)
|
||||
{
|
||||
}
|
||||
|
||||
// Set destination position or direction
|
||||
public void SetDestination(int iDestType, A3DVECTOR3 vMoveDest)
|
||||
{
|
||||
m_iDestType = iDestType;
|
||||
m_vMoveDest = vMoveDest;
|
||||
m_bHaveDest = true;
|
||||
m_bGliding = false;
|
||||
//m_pHost->SetAdjustOrient(false); // 2014-9-10 徐文彬:在 CECHPWorkMove 创建的时候都会调用此函数,会导致其它时机通过 SetDestDirAndUp 调用对人物的朝向调整失效。
|
||||
// 重现方法为:月仙“望月咏”技能释放后、马上按住'A'或'D'等移动键并摁住不放,将导致人物施法方向偏离目标而朝向移动方向(需多次尝试)
|
||||
|
||||
//清空任务信息
|
||||
m_iTaskId = 0;
|
||||
m_iNPCTempleId = 0;
|
||||
ResetUseAutoPF();
|
||||
|
||||
if (iDestType == Types.DEST_DIR)
|
||||
{
|
||||
m_vCurDir = vMoveDest;
|
||||
if (m_bUseAutoMoveDialog)
|
||||
{
|
||||
m_bUseAutoMoveDialog = false;
|
||||
m_bAutoLand = false;
|
||||
m_fAutoHeight = -1.0f;
|
||||
m_bAutoFly = false;
|
||||
m_bReachedHeight = true;
|
||||
m_bAutoFlyPending = false;
|
||||
}
|
||||
}
|
||||
else if (iDestType == Types.DEST_2D || iDestType == Types.DEST_3D)
|
||||
{
|
||||
m_vCurDir = vMoveDest - new A3DVECTOR3(m_pHost.transform.position.x, m_pHost.transform.position.y, m_pHost.transform.position.z);
|
||||
m_vCurDir.y = 0.0f;
|
||||
m_vCurDir.Normalize();
|
||||
}
|
||||
else if (IsAutoPF())
|
||||
{
|
||||
// TO DO: fix later
|
||||
//m_vCurDir = CECIntelligentRoute::Instance().GetCurDest() - m_pHost->GetPos();
|
||||
//m_vCurDir.y = 0.0f;
|
||||
//m_vCurDir.Normalize();
|
||||
//if (m_bUseAutoMoveDialog)
|
||||
//{
|
||||
// // 此处禁用 m_bUseAutoMoveDialog,见 SetUseAutoMoveDialog 中说明
|
||||
// m_bUseAutoMoveDialog = false;
|
||||
// m_bAutoLand = false;
|
||||
// m_fAutoHeight = -1.0f;
|
||||
// m_bAutoFly = false;
|
||||
// m_bReachedHeight = true;
|
||||
// m_bAutoFlyPending = false;
|
||||
//}
|
||||
}
|
||||
|
||||
// TO DO: fix later
|
||||
//if (m_pHost.m_pMoveTargetGFX)
|
||||
//{
|
||||
// if (iDestType != DEST_PUSH)
|
||||
// m_pHost.m_pMoveTargetGFX.Stop();
|
||||
//}
|
||||
}
|
||||
|
||||
void ResetUseAutoPF()
|
||||
{
|
||||
m_bResetAutoPF = true;
|
||||
}
|
||||
|
||||
// Tick routine
|
||||
public virtual bool Tick(float dwDeltaTime)
|
||||
{
|
||||
//UpdateResetUseAutoPF();
|
||||
//if (m_bSwitchTo2D)
|
||||
//{
|
||||
// SwitchToDest2D();
|
||||
// m_bSwitchTo2D = false;
|
||||
// return true;
|
||||
//}
|
||||
//if (IsAutoPF())
|
||||
//{
|
||||
// if (CECIntelligentRoute::Instance().IsIdle())
|
||||
// {
|
||||
// // 智能寻路模式未成功时,等待下个 Tick 切换到 DEST_2D 模式
|
||||
// return true;
|
||||
// }
|
||||
// if (m_pHost.IsFlying())
|
||||
// {
|
||||
// // 中途切换到飞行模式时,切换到 DEST_2D 模式
|
||||
// CECIntelligentRoute::Instance().ResetSearch();
|
||||
// m_bSwitchTo2D = true;
|
||||
// return true;
|
||||
// }
|
||||
//}
|
||||
|
||||
//base.Tick(dwDeltaTime);
|
||||
|
||||
//if (m_pHost.IsRooting())
|
||||
// return true;
|
||||
|
||||
//if (m_bUseAutoMoveDialog)
|
||||
//{
|
||||
// if (m_pHost.IsFlying())
|
||||
// {
|
||||
// m_bAutoFly = false;
|
||||
// m_bAutoFlyPending = false;
|
||||
// }
|
||||
|
||||
// if (m_bAutoFly && !m_bAutoFlyPending && !m_pHost.IsFlying())
|
||||
// {
|
||||
// if (m_pHost.CmdFly())
|
||||
// {
|
||||
// m_bAutoFly = false;
|
||||
// m_bAutoFlyPending = true;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// // Make sure 'Win_AutoPlay' dialog doesn't show up
|
||||
// CECGameUIMan pGameUI = g_pGame.GetGameRun().GetUIManager().GetInGameUIMan();
|
||||
// pGameUI.AutoMoveShowDialog(false);
|
||||
//}
|
||||
|
||||
////寻路过程中找到NPC对象转为WorkTrace状态
|
||||
//if ((m_vMoveDest - m_pHost.GetPos()).MagnitudeH() <= 5.0f)
|
||||
//{
|
||||
// if (m_iNPCTempleId)
|
||||
// {
|
||||
// CECNPC pNPC = g_pGame.GetGameRun().GetWorld().GetNPCMan().FindNPCByTempleID(m_iNPCTempleId);
|
||||
// if (pNPC && m_pHost.SelectTarget(pNPC->GetNPCID()))
|
||||
// {
|
||||
// CECHPWorkTrace pWork = m_pWorkMan.CreateNPCTraceWork(pNPC, m_iTaskId);
|
||||
// if (pWork)
|
||||
// {
|
||||
// m_bAutoLand = false; //防止飞行状态寻路结束,转到worktrace之前自动着陆,进入workfall。
|
||||
// Finish();
|
||||
// m_pWorkMan.SetPostTickCommand(new CECHPWorkPostTickRunWorkCommand(pWork, true));
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
//float fDeltaTime = dwDeltaTime;
|
||||
//if (m_pHost.m_iMoveEnv == CECPlayer::MOVEENV_GROUND ||
|
||||
// m_pHost.m_iMoveEnv == CECPlayer::MOVEENV_WATER && m_pHost.IsJumping() && (m_pHost.m_CDRInfo.vAbsVelocity.y > 0 || m_pHost.m_CDRInfo.fYVel > 0))
|
||||
//{
|
||||
// // Play appropriate actions
|
||||
// if (!m_pHost.IsJumping() && !m_pHost.IsPlayingAction(CECPlayer::ACT_TRICK_RUN) &&
|
||||
// m_pHost.m_iMoveMode != CECPlayer::MOVE_SLIDE && !m_bMeetSlide)
|
||||
// {
|
||||
// int iAction = m_pHost->GetMoveStandAction(true);
|
||||
// m_pHost.PlayAction(iAction, false);
|
||||
// }
|
||||
|
||||
// Tick_Walk(fDeltaTime);
|
||||
//}
|
||||
//else // (m_pHost->m_iMoveEnv == CECPlayer::MOVEENV_AIR || m_pHost->m_iMoveEnv == CECPlayer::MOVEENV_WATER)
|
||||
//{
|
||||
// m_pHost->ResetJump();
|
||||
|
||||
// // Play appropriate actions
|
||||
// if (!m_bGliding)
|
||||
// {
|
||||
// int iAction = m_pHost.GetMoveStandAction(true);
|
||||
// m_pHost.PlayAction(iAction, false);
|
||||
// }
|
||||
|
||||
// Tick_FlySwim(fDeltaTime);
|
||||
//}
|
||||
|
||||
return true;
|
||||
}
|
||||
// Reset work
|
||||
public virtual void Reset()
|
||||
{
|
||||
|
||||
}
|
||||
// Work is cancel
|
||||
public virtual void Cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// This work is do player moving ?
|
||||
public virtual bool IsMoving() { return true; }
|
||||
// Copy work data
|
||||
public virtual bool CopyData(CECHPWork pWork)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Play move target effect
|
||||
public void PlayMoveTargetGFX(A3DVECTOR3 vPos, A3DVECTOR3 vNormal)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// User press cancel button
|
||||
public void PressCancel() { m_bReadyCancel = true; }
|
||||
|
||||
public void SetUseAutoMoveDialog(bool bUseAutoMoveDialog)
|
||||
{
|
||||
|
||||
}
|
||||
public bool GetUseAutoMoveDialog() { return m_bUseAutoMoveDialog; }
|
||||
public bool GetAutoMove()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetAutoLand(bool bAutoLand) { m_bAutoLand = bAutoLand; }
|
||||
bool GetAutoLand() { return m_bAutoLand; }
|
||||
|
||||
void SetAutoHeight(float fHeight) { m_fAutoHeight = fHeight; m_bAutoFly = true; m_bReachedHeight = false; }
|
||||
float GetAutoHeight() { return m_fAutoHeight; }
|
||||
bool IsAutoFly() { return m_bAutoFly;}
|
||||
|
||||
bool IsAutoPF(){ return m_iDestType == Types.DEST_AUTOPF; }
|
||||
|
||||
// Finish work
|
||||
void Finish()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SetTaskNPCInfo(int tid, int taskid)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SwitchToDest2D()
|
||||
{
|
||||
//int tid, taskid;
|
||||
//tid = m_iNPCTempleId;
|
||||
//taskid = m_iTaskId;
|
||||
//CECGameUIMan* pGameUI = g_pGame->GetGameRun()->GetUIManager()->GetInGameUIMan();
|
||||
//pGameUI->SetAutoMoveShowDialogTarget((int)m_vMoveDest.x, (int)m_vMoveDest.z);
|
||||
//SetDestination(CECHPWorkMove::DEST_2D, m_vMoveDest);
|
||||
//SetTaskNPCInfo(tid, taskid);
|
||||
//SetUseAutoMoveDialog(true);
|
||||
}
|
||||
// On first tick
|
||||
protected virtual void OnFirstTick()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Tick routine of walking on ground
|
||||
protected bool Tick_Walk(float fDeltaTime)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// Tick routine of flying or swimming
|
||||
protected bool Tick_FlySwim(float fDeltaTime)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// Start gliding
|
||||
protected void Glide(float fMoveTime, A3DVECTOR3 vMoveDirH, float fDeltaTime, bool bFly)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Calculate vertical speed when fly or swim
|
||||
protected float CalcFlySwimVertSpeed(float fSpeed1, float fPushDir, float fPushAccel, float fDeltaTime)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected void ClearResetUseAutoPF()
|
||||
{
|
||||
|
||||
}
|
||||
protected void UpdateResetUseAutoPF()
|
||||
{
|
||||
// if (!m_bResetAutoPF)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// CECIntelligentRoute::Instance().SetUsage(CECIntelligentRoute::enumUsageWorkMove);
|
||||
// CECIntelligentRoute::Instance().ResetSearch();
|
||||
// if (m_iDestType == DEST_2D || m_iDestType == DEST_3D)
|
||||
// {
|
||||
//# ifdef SHOW_AUTOMOVE_FOOTPRINTS
|
||||
// g_AutoPFFollowPoints.clear();
|
||||
// g_AutoPFPathPoints.clear();
|
||||
//#endif
|
||||
// }
|
||||
// else if (IsAutoPF())
|
||||
// {
|
||||
// bool bSwitchTo2D(true);
|
||||
// while (true)
|
||||
// {
|
||||
// if (m_pHost->IsFlying())
|
||||
// {
|
||||
// break;
|
||||
// }
|
||||
// CECHostBrushTest brushTester(m_pHost->GetPos(), m_pHost->m_CDRInfo.vExtent, m_pHost->m_CDRInfo.fStepHeight);
|
||||
// if (CECIntelligentRoute::Instance().Search(m_pHost->GetPos(), m_vMoveDest, &brushTester) != CECIntelligentRoute::enumSearchSuccess)
|
||||
// {
|
||||
// break;
|
||||
// }
|
||||
// bSwitchTo2D = false;
|
||||
// break;
|
||||
// }
|
||||
// if (bSwitchTo2D)
|
||||
// {
|
||||
// m_bSwitchTo2D = true;
|
||||
// }
|
||||
// }
|
||||
// ClearResetUseAutoPF();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d03d31e6920c13745a437cff8cfe4572
|
||||
@@ -0,0 +1,75 @@
|
||||
using UnityEngine;
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class CECHPWorkSpell
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
public class CECHPWorkSpell : CECHPWork
|
||||
{
|
||||
public static class Spell_magic_state
|
||||
{
|
||||
public const int ST_INCANT = 0,
|
||||
ST_SPELL = 1;
|
||||
}
|
||||
|
||||
public CECHPWorkSpell(CECHPWorkMan pWorkMan) : base(Host_work_ID.WORK_SPELLOBJECT, pWorkMan)
|
||||
{
|
||||
m_dwMask = Work_mask.MASK_SPELLOBJECT;
|
||||
m_dwTransMask = Work_mask.MASK_STAND | Work_mask.MASK_MOVETOPOS | Work_mask.MASK_TRACEOBJECT;
|
||||
Reset();
|
||||
}
|
||||
|
||||
public CECHPWorkSpell(int iWorkID, CECHPWorkMan pWorkMan) : base(iWorkID, pWorkMan)
|
||||
{
|
||||
}
|
||||
|
||||
protected CECSkill m_pSkill; // Skill object
|
||||
protected CECCounter m_OverTimeCnt; // Over time counter
|
||||
protected int m_iState;
|
||||
protected int m_idTarget; // Target id
|
||||
|
||||
// On first tick
|
||||
protected virtual void OnFirstTick()
|
||||
{
|
||||
//m_pHost.m_iMoveMode = CECHostPlayer::MOVE_STAND;
|
||||
}
|
||||
// Prepare cast
|
||||
public void PrepareCast(int idTarget, CECSkill pSkill, int iIncantTime)
|
||||
{
|
||||
|
||||
}
|
||||
// Change state
|
||||
public void ChangeState(int iState)
|
||||
{
|
||||
|
||||
}
|
||||
// Get state
|
||||
public int GetState()
|
||||
{
|
||||
return m_iState;
|
||||
}
|
||||
public CECSkill GetSkill()
|
||||
{
|
||||
return m_pSkill;
|
||||
}
|
||||
|
||||
// Tick routine
|
||||
public virtual bool Tick(uint dwDeltaTime)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Reset work
|
||||
public virtual void Reset()
|
||||
{
|
||||
|
||||
}
|
||||
// Copy work data
|
||||
public virtual bool CopyData(CECHPWork pWork)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Cancel work
|
||||
public virtual void Cancel()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c82fffc45c6f0534e9a668a8ce937e1a
|
||||
@@ -0,0 +1,994 @@
|
||||
using BrewMonster;
|
||||
using BrewMonster.Network;
|
||||
using CSNetwork.GPDataType;
|
||||
using PerfectWorld.Scripts.Player;
|
||||
using System;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using UnityEngine;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class CECHPWorkTrace
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static class TraceObjectType
|
||||
{
|
||||
public const int TRACE_NONE = 0,
|
||||
TRACE_PLAYER = 1,
|
||||
TRACE_MATTER = 2,
|
||||
TRACE_NPC = 3,
|
||||
TRACE_TASKNPC = 4;
|
||||
}
|
||||
|
||||
public abstract class CECTracedObject
|
||||
{
|
||||
//friend CECHPWorkTrace;
|
||||
protected int m_iTraceType;
|
||||
protected int m_iObjectId;
|
||||
protected int m_iReason;
|
||||
protected bool m_bMoreClose;
|
||||
protected CECHostPlayer m_pHost;
|
||||
|
||||
public CECTracedObject(int type, int id, CECHostPlayer pHost, int ireason)
|
||||
{
|
||||
m_iTraceType = type;
|
||||
m_iObjectId = id;
|
||||
m_iReason = ireason;
|
||||
m_pHost = pHost;
|
||||
m_bMoreClose = false;
|
||||
}
|
||||
public CECTracedObject(CECTracedObject rhs)
|
||||
{
|
||||
m_iTraceType = rhs.m_iTraceType;
|
||||
m_iObjectId = rhs.m_iObjectId;
|
||||
m_iReason = rhs.m_iReason;
|
||||
m_bMoreClose = rhs.m_bMoreClose;
|
||||
m_pHost = rhs.m_pHost;
|
||||
}
|
||||
|
||||
public abstract bool OnTargetMissing();
|
||||
public abstract A3DVECTOR3 GetTargetPos();
|
||||
public abstract bool OnTouched();
|
||||
public abstract CECTracedObject Clone();
|
||||
|
||||
public virtual bool IsTargetMissing()
|
||||
{
|
||||
if (m_iObjectId != 0)
|
||||
{
|
||||
CECObject pObj = EC_ManMessageMono.Instance.GetObject(m_iObjectId, 0);
|
||||
if (pObj)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public A3DVECTOR3? GetMovePos()
|
||||
{
|
||||
A3DVECTOR3 vMovePos;
|
||||
CECObject pObject = EC_ManMessageMono.Instance.GetObject(m_iObjectId, 0);
|
||||
if (pObject)
|
||||
{
|
||||
if (GPDataTypeHelper.ISPLAYERID(m_iObjectId))
|
||||
{
|
||||
if (m_iObjectId == m_pHost.GetCharacterID())
|
||||
{
|
||||
vMovePos = m_pHost.GetPos();
|
||||
}
|
||||
else
|
||||
{
|
||||
vMovePos = (pObject as EC_ElsePlayer).GetServerPos();
|
||||
}
|
||||
}
|
||||
else if (GPDataTypeHelper.ISNPCID(m_iObjectId))
|
||||
{
|
||||
vMovePos = (pObject as CECNPC).GetServerPos();
|
||||
}
|
||||
else
|
||||
{
|
||||
vMovePos = pObject.GetPos();
|
||||
}
|
||||
return vMovePos;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int GetObjectID()
|
||||
{
|
||||
return m_iObjectId;
|
||||
}
|
||||
public bool CanTouchMoreClose()
|
||||
{
|
||||
return m_bMoreClose;
|
||||
}
|
||||
public void SetMoveCloseFlag(bool bMoveClode)
|
||||
{
|
||||
m_bMoreClose = bMoveClode;
|
||||
}
|
||||
public int GetTraceReason()
|
||||
{
|
||||
return m_iReason;
|
||||
}
|
||||
public bool CanTouchFrom(A3DVECTOR3 vHostPos)
|
||||
{
|
||||
while (m_iObjectId != 0)
|
||||
{
|
||||
A3DVECTOR3 vTargetPos = new A3DVECTOR3(0f, 0f, 0f);
|
||||
vTargetPos = GetTargetPos();
|
||||
|
||||
int iTouchReason = 0;
|
||||
if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK)
|
||||
iTouchReason = 1;
|
||||
else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_SPELL)
|
||||
iTouchReason = 2;
|
||||
else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_TALK)
|
||||
iTouchReason = 3;
|
||||
|
||||
float fMaxCut = m_bMoreClose ? -1.0f : 1.0f;
|
||||
|
||||
CECObject pObject = EC_ManMessageMono.Instance.GetObject(m_iObjectId, 0);
|
||||
|
||||
float fTouchRadius = 0.0f;
|
||||
if (GPDataTypeHelper.ISPLAYERID(m_iObjectId))
|
||||
{
|
||||
if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_TALK)
|
||||
{
|
||||
fTouchRadius = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
EC_Player pPlayer = pObject.GetComponent<CECHostPlayer>();
|
||||
fTouchRadius = pPlayer.GetTouchRadius();
|
||||
}
|
||||
return m_pHost.CanTouchTarget(vHostPos, vTargetPos, fTouchRadius, iTouchReason, fMaxCut);
|
||||
}
|
||||
else if (GPDataTypeHelper.ISNPCID(m_iObjectId))
|
||||
{
|
||||
CECNPC pNPC = pObject as CECNPC;
|
||||
fTouchRadius = pNPC.GetTouchRadius();
|
||||
return m_pHost.CanTouchTarget(vHostPos, vTargetPos, fTouchRadius, iTouchReason, fMaxCut);
|
||||
}
|
||||
//else if (GPDataTypeHelper.ISMATTERID(m_iObjectId))
|
||||
//{
|
||||
// CECMatter pMatter = (pObject) as CECMatter;
|
||||
// return pMatter.CalcDist(vHostPos, true) < pMatter.GetGatherDist();
|
||||
//}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public int GetTraceType()
|
||||
{
|
||||
return m_iTraceType;
|
||||
}
|
||||
public CECObject GetTargetObject()
|
||||
{
|
||||
return EC_ManMessageMono.Instance.GetObject(m_iObjectId, 0);
|
||||
}
|
||||
};
|
||||
|
||||
public class CECTracedNPC : CECTracedObject
|
||||
{
|
||||
protected bool m_bForceAttack;
|
||||
|
||||
public CECTracedNPC(int type, int id, CECHostPlayer pHost, int ireason, bool bForceAttack = false) : base(type, id, pHost, ireason)
|
||||
{
|
||||
m_bForceAttack = bForceAttack;
|
||||
}
|
||||
public CECTracedNPC(CECTracedNPC rhs) : base(rhs)
|
||||
{
|
||||
m_bForceAttack = rhs.m_bForceAttack;
|
||||
}
|
||||
|
||||
public override bool OnTargetMissing()
|
||||
{
|
||||
bool bRet = false;
|
||||
|
||||
if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK)
|
||||
{
|
||||
bRet = true;
|
||||
}
|
||||
//else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_SPELL)
|
||||
//{
|
||||
// CECSkill pSkill = m_pHost.m_pPrepSkill;
|
||||
// if (pSkill == null || pSkill.GetTargetType() != 2)
|
||||
// {
|
||||
// bRet = true;
|
||||
// m_pHost.m_pPrepSkill = null;
|
||||
// }
|
||||
//}
|
||||
return bRet;
|
||||
}
|
||||
|
||||
public override A3DVECTOR3 GetTargetPos()
|
||||
{
|
||||
return (GetTargetObject() as CECNPC).GetServerPos();
|
||||
}
|
||||
|
||||
public override bool OnTouched()
|
||||
{
|
||||
bool bActionDone = false;
|
||||
|
||||
if (GPDataTypeHelper.ISNPCID(m_iObjectId))
|
||||
{
|
||||
CECNPC pNPC = (CECNPC)GetTargetObject();
|
||||
|
||||
if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_TALK)
|
||||
{
|
||||
if ((!m_pHost.IsInBattle() || m_pHost.InSameBattleCamp(pNPC)) /*&&
|
||||
!g_pGame.GetGameRun().GetUIManager().GetInGameUIMan().GetDialog("Win_SkillAction").IsShow()*/)
|
||||
{
|
||||
UnityGameSession.c2s_CmdNPCSevHello(m_iObjectId);
|
||||
bActionDone = true;
|
||||
//a_LogOutput(1, "[NormalATK]- CECTracedNPC- OnTouched- TRACE_TALK");
|
||||
}
|
||||
}
|
||||
else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK)
|
||||
{
|
||||
if (m_iObjectId == m_pHost.m_idSelTarget &&
|
||||
m_pHost.AttackableJudge(m_iObjectId, m_bForceAttack) == 1)
|
||||
{
|
||||
byte byPVPMask = EC_Utility.glb_BuildPVPMask(m_bForceAttack);
|
||||
UnityGameSession.c2s_CmdNormalAttack(byPVPMask);
|
||||
m_pHost.m_bPrepareFight = true;
|
||||
bActionDone = true;
|
||||
//a_LogOutput(1, "[NormalATK]- CECTracedNPC- OnTouched- TRACE_ATTACK");
|
||||
}
|
||||
}
|
||||
//else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_SPELL)
|
||||
//{
|
||||
// //a_LogOutput(1, "[NormalATK]- CECTracedNPC- OnTouched- TRACE_SPELL");
|
||||
// if (!m_pHost.CannotAttack())
|
||||
// {
|
||||
// if (m_pHost.CastSkill(m_iObjectId, m_bForceAttack))
|
||||
// bActionDone = true;
|
||||
// }
|
||||
// else
|
||||
// m_pHost.m_pPrepSkill = null;
|
||||
//}
|
||||
}
|
||||
return bActionDone;
|
||||
}
|
||||
|
||||
public override CECTracedObject Clone()
|
||||
{
|
||||
return new CECTracedNPC(this);
|
||||
}
|
||||
|
||||
public override bool IsTargetMissing()
|
||||
{
|
||||
if (base.IsTargetMissing())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
CECNPC pNPC = GetTargetObject() as CECNPC;
|
||||
if (pNPC.IsDead())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class CECTracedPlayer : CECTracedObject
|
||||
{
|
||||
protected bool m_bForceAttack;
|
||||
public CECTracedPlayer(int type, int id, CECHostPlayer pHost, int ireason, bool bForceAttack = false) : base(type, id, pHost, ireason)
|
||||
{
|
||||
m_bForceAttack = bForceAttack;
|
||||
}
|
||||
public CECTracedPlayer(CECTracedPlayer rhs) : base(rhs)
|
||||
{
|
||||
m_bForceAttack = rhs.m_bForceAttack;
|
||||
}
|
||||
|
||||
public override bool OnTargetMissing()
|
||||
{
|
||||
bool bRet = false;
|
||||
|
||||
if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK)
|
||||
{
|
||||
bRet = true;
|
||||
}
|
||||
//else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_SPELL)
|
||||
//{
|
||||
// CECSkill pSkill = m_pHost.m_pPrepSkill;
|
||||
// if (pSkill == null || pSkill.GetTargetType() != 2)
|
||||
// {
|
||||
// bRet = true;
|
||||
// m_pHost.m_pPrepSkill = null;
|
||||
// }
|
||||
//}
|
||||
return bRet;
|
||||
}
|
||||
|
||||
public override A3DVECTOR3 GetTargetPos()
|
||||
{
|
||||
CECObject pObject = EC_ManMessageMono.Instance.GetObject(m_iObjectId, 0);
|
||||
if (m_iObjectId == m_pHost.GetCharacterID())
|
||||
{
|
||||
return m_pHost.GetPos();
|
||||
}
|
||||
else
|
||||
{
|
||||
return (pObject as EC_ElsePlayer).GetServerPos();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnTouched()
|
||||
{
|
||||
bool bActionDone = false;
|
||||
if (GPDataTypeHelper.ISPLAYERID(m_iObjectId))
|
||||
{
|
||||
if (m_iObjectId == 0 || m_iObjectId == m_pHost.GetCharacterID())
|
||||
{
|
||||
// Handle special case
|
||||
//ASSERT(m_iReason == CECHPWorkTrace::TRACE_SPELL);
|
||||
//if (!m_pHost.CannotAttack())
|
||||
//{
|
||||
// if (m_pHost.CastSkill(m_iObjectId, m_bForceAttack, null))
|
||||
// bActionDone = true;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// m_pHost.m_pPrepSkill = null;
|
||||
//}
|
||||
//a_LogOutput(1, "[NormalATK]- CECTracedPlayer- OnTouched- special case- TRACE_SPELL");
|
||||
return bActionDone;
|
||||
}
|
||||
if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK)
|
||||
{
|
||||
if (m_iObjectId == m_pHost.m_idSelTarget &&
|
||||
m_pHost.AttackableJudge(m_iObjectId, m_bForceAttack) == 1)
|
||||
{
|
||||
byte byPVPMask = EC_Utility.glb_BuildPVPMask(m_bForceAttack);
|
||||
UnityGameSession.c2s_CmdNormalAttack(byPVPMask);
|
||||
m_pHost.m_bPrepareFight = true;
|
||||
bActionDone = true;
|
||||
//a_LogOutput(1, "[NormalATK]- CECTracedPlayer- OnTouched- TRACE_ATTACK");
|
||||
}
|
||||
}
|
||||
//else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_SPELL)
|
||||
//{
|
||||
// //a_LogOutput(1, "[NormalATK]- CECTracedPlayer- OnTouched- TRACE_SPELL");
|
||||
// if (!m_pHost.CastSkill(m_iObjectId, m_bForceAttack, GetTargetObject()))
|
||||
// {
|
||||
// m_pHost.m_pPrepSkill = null;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// bActionDone = true;
|
||||
// }
|
||||
//}
|
||||
else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_TALK)
|
||||
{
|
||||
// Visite other's booth, send hello message to him
|
||||
//a_LogOutput(1, "[NormalATK]- CECTracedPlayer- OnTouched- TRACE_TALK");
|
||||
UnityGameSession.c2s_CmdNPCSevHello(m_iObjectId);
|
||||
bActionDone = true;
|
||||
}
|
||||
}
|
||||
return bActionDone;
|
||||
}
|
||||
|
||||
public override CECTracedObject Clone()
|
||||
{
|
||||
return new CECTracedPlayer(this);
|
||||
}
|
||||
|
||||
public override bool IsTargetMissing()
|
||||
{
|
||||
if (base.IsTargetMissing())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
EC_Player pPlayer = GetTargetObject() as EC_Player;
|
||||
if (pPlayer.IsElsePlayer())
|
||||
{
|
||||
if (pPlayer.IsDead())
|
||||
{
|
||||
//if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_SPELL)
|
||||
//{
|
||||
// CECSkill pSkill = m_pHost.m_pPrepSkill;
|
||||
// if (pSkill && pSkill.GetTargetType() == 2)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
public class CECTracedMatter : CECTracedObject
|
||||
{
|
||||
|
||||
public CECTracedMatter(int type, int id, CECHostPlayer pHost, int ireason) : base(type, id, pHost, ireason)
|
||||
{
|
||||
|
||||
}
|
||||
public CECTracedMatter(CECTracedMatter rhs) : base(rhs)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override bool OnTargetMissing()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override A3DVECTOR3 GetTargetPos()
|
||||
{
|
||||
return GetTargetObject().GetPos();
|
||||
}
|
||||
|
||||
public override bool OnTouched()
|
||||
{
|
||||
bool bActionDone = false;
|
||||
//if (GPDataTypeHelper.ISMATTERID(m_iObjectId))
|
||||
//{
|
||||
// if (m_pHost.GetProfession() == PROF_GHOST && m_pHost.IsInvisible())
|
||||
// {
|
||||
// g_pGame.GetGameRun().AddFixedMessage(FIXMSG_CANNOT_USE_WHEN_INVISIBLE);
|
||||
// return bActionDone;
|
||||
// }
|
||||
// CECMatter* pMatter = (CECMatter*)GetTargetObject();
|
||||
|
||||
// if (m_iReason == CECHPWorkTrace::TRACE_PICKUP)
|
||||
// {
|
||||
// // Check whether we have enougth place to hold this item or money
|
||||
// a_LogOutput(1, "[NormalATK]- CECTracedMatter- OnTouched- TRACE_PICKUP");
|
||||
// if (m_pHost.CanTakeItem(pMatter.GetTemplateID(), 1))
|
||||
// {
|
||||
// // Send pickup asking and wait response command
|
||||
// g_pGame.GetGameSession().c2s_CmdPickup(m_iObjectId, pMatter.GetTemplateID());
|
||||
// bActionDone = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // Print a notify message
|
||||
// g_pGame.GetGameRun().AddFixedMessage(FIXMSG_PACKISFULL);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// { // m_iReason == TRACE_GATHER
|
||||
// int tidMatter = pMatter.GetTemplateID();
|
||||
// a_LogOutput(1, "[NormalATK]- CECTracedMatter- OnTouched- TRACE_GATHER");
|
||||
// // Check mine level requirement
|
||||
// if (m_pHost.GetBasicProps().iLevel < pMatter.GetLevelReq())
|
||||
// {
|
||||
// g_pGame.GetGameRun().AddFixedMessage(FIXMSG_LEVELTOOLOW);
|
||||
// return bActionDone;
|
||||
// }
|
||||
|
||||
// // Check whether we have a mine tool
|
||||
// int iPack, iIndex, idTool;
|
||||
// if (m_pHost.FindMineTool(tidMatter, &iPack, &iIndex, &idTool))
|
||||
// {
|
||||
// DATA_TYPE DataType;
|
||||
// const MINE_ESSENCE* pData = (const MINE_ESSENCE*)g_pGame.GetElementDataMan().get_data_ptr(pMatter.GetTemplateID(), ID_SPACE_ESSENCE, DataType);
|
||||
// if (DataType != DT_MINE_ESSENCE)
|
||||
// {
|
||||
// ASSERT(DataType == DT_MINE_ESSENCE);
|
||||
// return bActionDone;
|
||||
// }
|
||||
|
||||
// if (m_pHost.GetCoolTime(GP_CT_PLAYER_GATHER))
|
||||
// {
|
||||
// g_pGame.GetGameRun().AddFixedMessage(FIXMSG_CMD_INCOOLTIME);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // Send gather asking and wait response command
|
||||
// g_pGame.GetGameSession().c2s_CmdGatherMaterial(m_iObjectId, iPack, iIndex, idTool, pData.task_in);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// g_pGame.GetGameRun().AddFixedMessage(FIXMSG_NEEDTOOL);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
return bActionDone;
|
||||
}
|
||||
|
||||
public override CECTracedObject Clone()
|
||||
{
|
||||
return new CECTracedMatter(this);
|
||||
}
|
||||
};
|
||||
public class CECHPWorkTrace : CECHPWork
|
||||
{
|
||||
// Trace reason
|
||||
public static class Trace_reason
|
||||
{
|
||||
public const int TRACE_NONE = -1,
|
||||
TRACE_ATTACK = 0, // Normal attack
|
||||
TRACE_PICKUP = 1, // Pickup object
|
||||
TRACE_TALK = 2, // Go to talk
|
||||
TRACE_SPELL = 3, // Cast magic
|
||||
TRACE_GATHER = 4; // Gather object
|
||||
}
|
||||
// Constructor and Destructor
|
||||
public CECHPWorkTrace(CECHPWorkMan pWorkMan) : base(Host_work_ID.WORK_TRACEOBJECT, pWorkMan)
|
||||
{
|
||||
m_dwMask = Work_mask.MASK_TRACEOBJECT;
|
||||
m_dwTransMask = Work_mask.MASK_STAND | Work_mask.MASK_MOVETOPOS | Work_mask.MASK_FLYOFF | Work_mask.MASK_FREEFALL |
|
||||
Work_mask.MASK_FOLLOW | Work_mask.MASK_USEITEM;
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
// Change trace target
|
||||
//void ChangeTarget(int idTarget, int iReason, bool bUseAutoPF=false);
|
||||
// 设定traceobject
|
||||
public void SetTraceTarget(CECTracedObject pTraceObj, bool bUseAutoPF = false)
|
||||
{
|
||||
ResetUseAutoPF(bUseAutoPF);
|
||||
if (!pTraceObj.GetTargetObject() || pTraceObj.GetObjectID() == m_pHost.GetCharacterID())
|
||||
{
|
||||
// This is special case
|
||||
ReplaceTarget(pTraceObj);
|
||||
return;
|
||||
}
|
||||
int idTarget = pTraceObj.GetObjectID();
|
||||
if (!GPDataTypeHelper.ISPLAYERID(idTarget) && !GPDataTypeHelper.ISNPCID(idTarget) && !GPDataTypeHelper.ISMATTERID(idTarget))
|
||||
{
|
||||
return;
|
||||
}
|
||||
CECObject pObject = pTraceObj.GetTargetObject();
|
||||
if (!pObject)
|
||||
{
|
||||
//delete pTraceObj;
|
||||
return;
|
||||
}
|
||||
ReplaceTarget(pTraceObj);
|
||||
if (m_pTraceObject.GetTargetObject())
|
||||
{
|
||||
A3DVECTOR3 vDirH = pTraceObj.GetTargetPos() - m_pHost.GetPos();
|
||||
vDirH.y = 0.0f;
|
||||
vDirH.Normalize();
|
||||
m_vCurDirH = !vDirH.IsZero() ? vDirH : m_vCurDirH = GPDataTypeHelper.g_vAxisZ;
|
||||
}
|
||||
}
|
||||
|
||||
public CECTracedObject CreatTraceTarget(int iTraceObjId, int iReason, bool bForceAttack = false)
|
||||
{
|
||||
if (GPDataTypeHelper.ISPLAYERID(iTraceObjId))
|
||||
{
|
||||
return new CECTracedPlayer(TraceObjectType.TRACE_PLAYER, iTraceObjId, m_pHost, iReason, bForceAttack);
|
||||
}
|
||||
else if (GPDataTypeHelper.ISNPCID(iTraceObjId))
|
||||
{
|
||||
return new CECTracedNPC(TraceObjectType.TRACE_NPC, iTraceObjId, m_pHost, iReason, bForceAttack);
|
||||
}
|
||||
//else if (GPDataTypeHelper.ISMATTERID(iTraceObjId))
|
||||
//{
|
||||
// return new CECTracedMatter(TraceObjectType.TRACE_MATTER, iTraceObjId, m_pHost, iReason);
|
||||
//}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Tick routine
|
||||
public virtual bool Tick(float dwDeltaTime)
|
||||
{
|
||||
base.Tick(dwDeltaTime);
|
||||
|
||||
CheckPrepSkill();
|
||||
|
||||
UpdateResetUseAutoPF();
|
||||
UpdateUseAutoPF();
|
||||
|
||||
// m_bFinished flag may be set both in OnFirstTick() and CheckPrepSkill(),
|
||||
// so check it here !
|
||||
if (m_bFinished)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (m_pTraceObject.IsTargetMissing())
|
||||
{
|
||||
OnTargetMissing();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_bCheckTouch)
|
||||
{
|
||||
if (IsGoodTimeToTouch())
|
||||
{
|
||||
if (m_pTraceObject.CanTouchFrom(m_pHost.GetPos()))
|
||||
{
|
||||
OnTouchTarget();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_bCheckTouch = true;
|
||||
|
||||
if (!m_pHost.IsRooting())
|
||||
{
|
||||
// Continue tracing object
|
||||
float fDeltaTime = dwDeltaTime /** 0.001f*/;
|
||||
if (m_pHost.m_iMoveEnv == EC_Player.Move_environment.MOVEENV_GROUND)
|
||||
{
|
||||
// Play appropriate actions
|
||||
if (!m_pHost.IsJumping() && !m_pHost.IsPlayingAction((int)EC_Player.PLAYER_ACTION_TYPE.ACT_TRICK_RUN) &&
|
||||
m_pHost.m_iMoveMode != (int)MoveMode.MOVE_SLIDE)
|
||||
{
|
||||
int iAction = m_pHost.GetMoveStandAction(true);
|
||||
m_pHost.PlayAction(iAction, false, 200, false);
|
||||
}
|
||||
|
||||
Trace_Walk(fDeltaTime);
|
||||
}
|
||||
else // (m_pHost.m_iMoveEnv == CECPlayer::MOVEENV_AIR || m_pHost.m_iMoveEnv == CECPlayer::MOVEENV_WATER)
|
||||
{
|
||||
m_pHost.ResetJump();
|
||||
|
||||
// Play appropriate actions
|
||||
int iAction = m_pHost.GetMoveStandAction(true);
|
||||
m_pHost.PlayAction(iAction, false, 200, false);
|
||||
|
||||
Trace_FlySwim(fDeltaTime);
|
||||
}
|
||||
|
||||
m_bHaveMoved = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
// Reset work
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
|
||||
m_bHaveMoved = false;
|
||||
m_bMeetSlide = false;
|
||||
m_bCheckTouch = true;
|
||||
m_bReadyCancel = false;
|
||||
m_bMoreClose = false;
|
||||
//m_pPrepSkill = null;
|
||||
m_bForceAttack = false;
|
||||
m_bActionDone = false;
|
||||
ClearResetUseAutoPF();
|
||||
m_bUseAutoPF = false;
|
||||
m_dwAutoPFNextCheckTime = 0;
|
||||
m_pTraceObject = null;
|
||||
}
|
||||
// Work is cancel
|
||||
public override void Cancel()
|
||||
{
|
||||
//if (m_pHost.m_pPrepSkill && m_pTraceObject.GetTraceReason() == Trace_reason.TRACE_SPELL)
|
||||
// m_pHost.m_pPrepSkill = null;
|
||||
|
||||
ClearResetUseAutoPF();
|
||||
if (GetUseAutoPF())
|
||||
{
|
||||
SetUseAutoPF(false);
|
||||
}
|
||||
//m_pHost.StopModelMove();
|
||||
base.Cancel();
|
||||
|
||||
//AP_ActionEvent(m_bActionDone ? AP_EVENT_TRACEOK : AP_EVENT_MOVEFINISHED, m_pTraceObject.GetTraceReason());
|
||||
}
|
||||
|
||||
// This work is do player moving ?
|
||||
public override bool IsMoving() { return true; }
|
||||
// Copy work data
|
||||
public override bool CopyData(CECHPWork pWork)
|
||||
{
|
||||
if (!base.CopyData(pWork))
|
||||
return false;
|
||||
|
||||
CECHPWorkTrace pSrc = (CECHPWorkTrace)pWork;
|
||||
|
||||
m_bHaveMoved = pSrc.m_bHaveMoved;
|
||||
m_bMeetSlide = pSrc.m_bMeetSlide;
|
||||
m_bCheckTouch = pSrc.m_bCheckTouch;
|
||||
m_bReadyCancel = pSrc.m_bReadyCancel;
|
||||
m_bMoreClose = pSrc.m_bMoreClose;
|
||||
m_vCurDirH = pSrc.m_vCurDirH;
|
||||
//m_pPrepSkill = pSrc.m_pPrepSkill;
|
||||
m_bForceAttack = pSrc.m_bForceAttack;
|
||||
m_bActionDone = pSrc.m_bActionDone;
|
||||
m_bShouldResetUseAutoPF = pSrc.m_bShouldResetUseAutoPF;
|
||||
m_bUseAutoPFResetValue = pSrc.m_bUseAutoPFResetValue;
|
||||
m_bUseAutoPF = pSrc.m_bUseAutoPF;
|
||||
m_dwAutoPFNextCheckTime = pSrc.m_dwAutoPFNextCheckTime;
|
||||
|
||||
//delete m_pTraceObject;
|
||||
m_pTraceObject = pSrc.m_pTraceObject.Clone();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// User press cancel button
|
||||
public void PressCancel()
|
||||
{
|
||||
m_bReadyCancel = true;
|
||||
//if (m_pTraceObject.GetTraceReason() == TRACE_SPELL)
|
||||
// m_pHost.m_pPrepSkill = NULL;
|
||||
}
|
||||
// Set move close flag
|
||||
public void SetMoveCloseFlag(bool bMoveClose) { m_pTraceObject.SetMoveCloseFlag(bMoveClose); }
|
||||
|
||||
// Set / Get force attack flag
|
||||
public void SetForceAttack(bool bTrue) { m_bForceAttack = bTrue; }
|
||||
public bool GetForceAttack() { return m_bForceAttack; }
|
||||
// Set / Get prepared skill
|
||||
public void SetPrepSkill(CECSkill pSkill) { /*m_pPrepSkill = pSkill;*/ }
|
||||
public CECSkill GetPrepSkill() { /*return m_pPrepSkill;*/ return null; }
|
||||
// Get target ID
|
||||
public int GetTarget() { return m_pTraceObject.GetObjectID(); }
|
||||
// Get trace reason
|
||||
public int GetTraceReason() { return m_pTraceObject.GetTraceReason(); }
|
||||
// AutoPF
|
||||
public void SetUseAutoPF(bool bUse)
|
||||
{
|
||||
m_bUseAutoPF = bUse;
|
||||
//if (!m_bUseAutoPF && CECIntelligentRoute.Instance().IsUsageTrace())
|
||||
//{
|
||||
// CECIntelligentRoute.Instance().ResetSearch();
|
||||
//}
|
||||
}
|
||||
public bool GetUseAutoPF()
|
||||
{
|
||||
return m_bUseAutoPF;
|
||||
}
|
||||
public bool IsAutoPF()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SetActionDone(bool bActionDone) { m_bActionDone = bActionDone; }
|
||||
|
||||
public void OnTargetMissing()
|
||||
{
|
||||
StopMove(true);
|
||||
if ((m_pTraceObject.GetTraceType() == TraceObjectType.TRACE_NPC) || (m_pTraceObject.GetTraceType() == TraceObjectType.TRACE_PLAYER))
|
||||
{
|
||||
m_pTraceObject.OnTargetMissing();
|
||||
}
|
||||
//else if (m_pTraceObject.GetTraceReason() == Trace_reason.TRACE_SPELL)
|
||||
//{
|
||||
// m_pHost.m_pPrepSkill = null;
|
||||
//}
|
||||
}
|
||||
|
||||
public void OnTouchTarget()
|
||||
{
|
||||
StopMove(true);
|
||||
m_bActionDone = m_pTraceObject.OnTouched();
|
||||
}
|
||||
public bool CanTouch()
|
||||
{
|
||||
//CECSkill pPrepSkill = m_pHost.m_pPrepSkill;
|
||||
CheckPrepSkill();
|
||||
bool result = m_pTraceObject.CanTouchFrom(m_pHost.GetPos());
|
||||
//m_pHost.m_pPrepSkill = pPrepSkill;
|
||||
return result;
|
||||
}
|
||||
// Attributes
|
||||
|
||||
protected bool m_bHaveMoved; // Have moved flag
|
||||
protected bool m_bMeetSlide; // true, meet slide
|
||||
protected bool m_bCheckTouch; // Check whether touch target in this frame
|
||||
protected A3DVECTOR3 m_vCurDirH; // Current move direction
|
||||
protected bool m_bReadyCancel; // true, ready to cancel
|
||||
protected bool m_bMoreClose; // Move close flag
|
||||
protected bool m_bForceAttack; // Force attack flag
|
||||
protected CECSkill m_pPrepSkill; // Skill prepared to be casted
|
||||
protected bool m_bActionDone; // 目标行为成功发出
|
||||
protected bool m_bShouldResetUseAutoPF;
|
||||
protected bool m_bUseAutoPFResetValue;
|
||||
protected bool m_bUseAutoPF; // Use CECIntelligentRoute::Search
|
||||
protected uint m_dwAutoPFNextCheckTime; // 下次检查时间
|
||||
|
||||
protected CECTracedObject m_pTraceObject; // 定义trace目标对象
|
||||
|
||||
// Operations
|
||||
|
||||
// On first tick
|
||||
protected virtual void OnFirstTick()
|
||||
{
|
||||
m_pHost.m_iMoveMode = (int)MoveMode.MOVE_MOVE;
|
||||
m_bHaveMoved = false;
|
||||
}
|
||||
|
||||
// Trace on ground
|
||||
protected bool Trace_Walk(float fDeltaTime)
|
||||
{
|
||||
A3DVECTOR3 vCurPos = m_pHost.GetPos();
|
||||
A3DVECTOR3 vTargetPos = GetCurMovingDest();
|
||||
CDR_INFO cdr = m_pHost.m_CDRInfo;
|
||||
|
||||
if (m_pHost.m_iMoveMode == (int)MoveMode.MOVE_SLIDE)
|
||||
{
|
||||
m_pHost.PlayAction((int)EC_Player.PLAYER_ACTION_TYPE.ACT_JUMP_LOOP, false, 200, false);
|
||||
|
||||
// This will cause stop moming after we slide down.
|
||||
A3DVECTOR3 vDir = vTargetPos - vCurPos;
|
||||
vDir.y = 0;
|
||||
vDir.Normalize();
|
||||
|
||||
float fMaxSpeedV = 0f;
|
||||
m_bMeetSlide = m_pHost.m_MoveCtrl.MeetSlope(vDir, fMaxSpeedV);
|
||||
EC_Utility.a_ClampFloor(cdr.fYVel, -fMaxSpeedV);
|
||||
|
||||
if (!vDir.IsZero())
|
||||
m_vCurDirH = vDir;
|
||||
|
||||
vCurPos = m_pHost.m_MoveCtrl.GroundMove(m_vCurDirH, m_pHost.GetGroundSpeed(), fDeltaTime);
|
||||
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
|
||||
{
|
||||
m_pHost.m_MoveCtrl.SetSlideLock(true);
|
||||
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), m_pHost.GetGroundSpeed(), (int)GPMoveMode.GP_MOVE_SLIDE);
|
||||
m_bFinished = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
|
||||
//if (GetUseAutoPF() && CECIntelligentRoute::Instance().IsMoveOn())
|
||||
//{
|
||||
// CECIntelligentRoute::Instance().OnPlayerPosChange(vCurPos);
|
||||
//}
|
||||
m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 2, GPDataTypeHelper.g_vOrigin, EC_Utility.ToA3DVECTOR3(cdr.vAbsVelocity), (int)GPMoveMode.GP_MOVE_SLIDE);
|
||||
}
|
||||
}
|
||||
else if (!m_bMeetSlide)
|
||||
{
|
||||
int iMoveMode = m_pHost.m_bWalkRun ? (int)GPMoveMode.GP_MOVE_RUN : (int)GPMoveMode.GP_MOVE_WALK;
|
||||
if (m_pHost.IsJumping())
|
||||
iMoveMode = (int)GPMoveMode.GP_MOVE_JUMP;
|
||||
else if (!m_pHost.m_GndInfo.bOnGround)
|
||||
iMoveMode = (int)GPMoveMode.GP_MOVE_FALL;
|
||||
|
||||
if (m_pHost.m_GndInfo.bOnGround)
|
||||
{
|
||||
if (m_bReadyCancel)
|
||||
{
|
||||
StopMove(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ajust direction only when player on ground
|
||||
A3DVECTOR3 vDirH = vTargetPos - vCurPos;
|
||||
A3DVECTOR3 v = A3DFuncs.a3d_Normalize(vDirH);
|
||||
if (Math.Abs(v.y) > 0.9848f)
|
||||
{
|
||||
PressCancel();
|
||||
return true;
|
||||
}
|
||||
|
||||
vDirH.y = 0.0f;
|
||||
vDirH.Normalize();
|
||||
if (!vDirH.IsZero())
|
||||
m_vCurDirH = vDirH;
|
||||
}
|
||||
|
||||
vCurPos = m_pHost.m_MoveCtrl.GroundMove(m_vCurDirH, m_pHost.GetGroundSpeed(), fDeltaTime, m_pHost.m_fVertSpeed);
|
||||
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
|
||||
//if (GetUseAutoPF() && CECIntelligentRoute::Instance().IsMoveOn())
|
||||
//{
|
||||
// CECIntelligentRoute::Instance().OnPlayerPosChange(vCurPos);
|
||||
//}
|
||||
|
||||
if (cdr.vTPNormal == Vector3.zero)
|
||||
m_bCheckTouch = false;
|
||||
|
||||
//if (!m_vCurDirH.IsZero())
|
||||
//{
|
||||
// m_pHost.StartModelMove(m_vCurDirH, g_vAxisY, 0);
|
||||
//}
|
||||
|
||||
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
|
||||
{
|
||||
// m_pHost.m_MoveCtrl.SendStopMoveCmd(vCurPos, m_pHost.GetGroundSpeed(), iMoveMode);
|
||||
PressCancel();
|
||||
}
|
||||
else
|
||||
m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 0, vTargetPos, EC_Utility.ToA3DVECTOR3(cdr.vAbsVelocity), iMoveMode);
|
||||
}
|
||||
else // m_bMeetSlide == true
|
||||
{
|
||||
if (m_bHaveMoved)
|
||||
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), m_pHost.GetGroundSpeed(), (int)GPMoveMode.GP_MOVE_SLIDE);
|
||||
|
||||
m_bFinished = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// Trace in air and water
|
||||
public bool Trace_FlySwim(float fDeltaTime)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Stop move when touch target
|
||||
public void StopMove(bool bFinish)
|
||||
{
|
||||
// If 'trace' work was transfered from a work which
|
||||
// needs moving (such as 'move to' work) and we touch the target
|
||||
// immediately (m_bHaveMoved = false), we must need to send 'stop move'
|
||||
// command
|
||||
if (m_bHaveMoved || !m_pHost.m_MoveCtrl.IsStop())
|
||||
m_pHost.m_MoveCtrl.SendStopMoveCmd();
|
||||
|
||||
m_pHost.m_vVelocity.Clear();
|
||||
//m_pHost.StopModelMove();
|
||||
|
||||
if (bFinish)
|
||||
{
|
||||
m_bFinished = true;
|
||||
}
|
||||
}
|
||||
// Handle the case that target died when host is tracing it
|
||||
public bool OnTargetDied(CECObject pTarget)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// Is valid time to touch target ?
|
||||
public bool IsGoodTimeToTouch()
|
||||
{
|
||||
if (m_pHost.IsJumping())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// Check prepare skill
|
||||
public void CheckPrepSkill()
|
||||
{
|
||||
|
||||
}
|
||||
public bool GetTargetCurPos(A3DVECTOR3 pos)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public A3DVECTOR3 GetCurMovingDest()
|
||||
{
|
||||
return new A3DVECTOR3();
|
||||
}
|
||||
public void UpdateUseAutoPF()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void ReplaceTarget(CECTracedObject ptraceobj)
|
||||
{
|
||||
//if (m_pTraceObject)
|
||||
//{
|
||||
// delete m_pTraceObject;
|
||||
//}
|
||||
m_pTraceObject = ptraceobj;
|
||||
}
|
||||
|
||||
public void ResetUseAutoPF(bool bUseAutoPF)
|
||||
{
|
||||
m_bShouldResetUseAutoPF = true;
|
||||
m_bUseAutoPFResetValue = bUseAutoPF;
|
||||
}
|
||||
public void UpdateResetUseAutoPF()
|
||||
{
|
||||
if (!m_bShouldResetUseAutoPF)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//# ifdef SHOW_AUTOMOVE_FOOTPRINTS
|
||||
// g_AutoPFFollowPoints.clear();
|
||||
// g_AutoPFPathPoints.clear();
|
||||
//#endif
|
||||
//CECIntelligentRoute::Instance().SetUsage(CECIntelligentRoute::enumUsageWorkTrace);
|
||||
//CECIntelligentRoute::Instance().ResetSearch();
|
||||
SetUseAutoPF(m_bUseAutoPFResetValue);
|
||||
ClearResetUseAutoPF();
|
||||
}
|
||||
public void ClearResetUseAutoPF()
|
||||
{
|
||||
m_bShouldResetUseAutoPF = false;
|
||||
m_bUseAutoPFResetValue = false;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8cd5ac42b14a07f459a8c68c35d38af6
|
||||
@@ -23,6 +23,7 @@ namespace PerfectWorld.Scripts.Managers
|
||||
Dictionary<int, int> m_UkPlayerTab = new Dictionary<int, int>();
|
||||
Dictionary<int, EC_ElsePlayer> m_PlayerTab = new Dictionary<int, EC_ElsePlayer>();
|
||||
private readonly object m_csPlayerTab = new object();
|
||||
CECHostPlayer m_pHostPlayer;
|
||||
public int HandlerId => (int)MANAGER_INDEX.MAN_PLAYER;
|
||||
public bool ProcessMessage(ECMSG Msg)
|
||||
{
|
||||
@@ -468,6 +469,20 @@ namespace PerfectWorld.Scripts.Managers
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get a player (may be host or else player) by id
|
||||
public EC_Player GetPlayer(int cid, uint dwBornStamp = 0)
|
||||
{
|
||||
CECHostPlayer pHost = GetHostPlayer();
|
||||
if (pHost && pHost.GetCharacterID() == cid)
|
||||
return pHost;
|
||||
else
|
||||
return GetElsePlayer(cid, dwBornStamp);
|
||||
}
|
||||
|
||||
public CECHostPlayer GetHostPlayer()
|
||||
{
|
||||
return GameController.Instance.GetHostPlayer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
using CSNetwork.GPDataType;
|
||||
using CSNetwork.Protocols;
|
||||
using UnityEngine;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class CECObject
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public class CECObject : MonoBehaviour
|
||||
{
|
||||
// Class ID
|
||||
public static class Class_ID
|
||||
{
|
||||
public const int OCID_OBJECT = 0,
|
||||
OCID_PLAYER = 1,
|
||||
OCID_HOSTPLAYER = 2,
|
||||
OCID_ELSEPLAYER = 3,
|
||||
OCID_LOGINPLAYER = 4,
|
||||
OCID_NPC = 5,
|
||||
OCID_MONSTER = 6,
|
||||
OCID_SERVER = 7,
|
||||
OCID_MATTER = 8,
|
||||
OCID_PET = 9,
|
||||
OCID_CLONED_PLAYER = 10, // 复制角色模型
|
||||
OCID_HOST_NAVIGATER = 11, // 纯客户端player类,用于强制移动
|
||||
OCID_NPCCLONED_MASTER = 12; // NPC 复制的角色模型
|
||||
}
|
||||
|
||||
// Render flag
|
||||
public static class Render_flag
|
||||
{
|
||||
public const int RD_NORMAL = 0,
|
||||
RD_REFRACT = 1,
|
||||
RD_REFLECT = 2;
|
||||
}
|
||||
|
||||
// Move environment
|
||||
public static class Move_environment
|
||||
{
|
||||
public const int MOVEENV_GROUND = 0, // Move on ground
|
||||
MOVEENV_WATER = 1,
|
||||
MOVEENV_AIR = 2;
|
||||
}
|
||||
|
||||
// Constructor and Destructor
|
||||
public CECObject()
|
||||
{
|
||||
m_iCID = Class_ID.OCID_OBJECT;
|
||||
m_bAdjustOrient = false;
|
||||
m_bVisible = true;
|
||||
m_bBornInSight = false;
|
||||
m_dwBornStamp = 0;
|
||||
|
||||
m_bUseGroundNormal = false;
|
||||
m_vecGroundNormal = new A3DVECTOR3(0.0f, 1.0f, 0.0f);
|
||||
m_vecGroundNormalSet = new A3DVECTOR3(0.0f, 1.0f, 0.0f);
|
||||
|
||||
m_bSelectable = true;
|
||||
}
|
||||
|
||||
public virtual void SetUpCECObject()
|
||||
{
|
||||
m_dwBornStamp = 0;
|
||||
m_bBornInSight = false;
|
||||
m_bSelectable = false;
|
||||
m_iCID = (int)Class_ID.OCID_OBJECT;
|
||||
}
|
||||
|
||||
public void SetSelectable(bool bSelectable) { m_bSelectable = bSelectable; }
|
||||
|
||||
// Tick routine
|
||||
public bool Tick(float dwDeltaTime)
|
||||
{
|
||||
if (m_bAdjustOrient)
|
||||
AdjustOrientation(dwDeltaTime);
|
||||
|
||||
m_vecGroundNormal = Normalize(m_vecGroundNormal * 0.85f + m_vecGroundNormalSet * 0.15f);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Set absolute forward and up direction
|
||||
public virtual void SetDirAndUp(A3DVECTOR3 vDir, A3DVECTOR3 vUp)
|
||||
{
|
||||
//if (m_bUseGroundNormal)
|
||||
//{
|
||||
// A3DVECTOR3 vecRight = Normalize(CrossProduct(g_vAxisY, vDir));
|
||||
// A3DVECTOR3 vecNormal = m_vecGroundNormal - DotProduct(m_vecGroundNormal, vecRight) * vecRight;
|
||||
// A3DVECTOR3 vecNewDir = Normalize(CrossProduct(vecRight, vecNormal));
|
||||
// A3DCoordinate::SetDirAndUp(vecNewDir, vecNormal);
|
||||
//}
|
||||
//else
|
||||
// A3DCoordinate::SetDirAndUp(vDir, vUp);
|
||||
|
||||
// Stop orientation adjusting
|
||||
m_bAdjustOrient = false;
|
||||
}
|
||||
// Set destination orientation of model
|
||||
public void SetDestDirAndUp(A3DVECTOR3 vDir, A3DVECTOR3 vUp, float dwTime)
|
||||
{
|
||||
m_bAdjustOrient = true;
|
||||
m_dwOrientTime = dwTime;
|
||||
m_dwOrientTimeCnt = 0;
|
||||
|
||||
//// Calculate start orientation
|
||||
//A3DMATRIX4 mat = a3d_TransformMatrix(GetDir(), GetUp(), g_vOrigin);
|
||||
//m_quOrientStart.ConvertFromMatrix(mat);
|
||||
|
||||
//// Calculate end orientation
|
||||
//if (m_bUseGroundNormal)
|
||||
//{
|
||||
// A3DVECTOR3 vecRight = Normalize(CrossProduct(g_vAxisY, vDir));
|
||||
// A3DVECTOR3 vecNormal = m_vecGroundNormal - DotProduct(m_vecGroundNormal, vecRight) * vecRight;
|
||||
// A3DVECTOR3 vecNewDir = Normalize(CrossProduct(vecRight, vecNormal));
|
||||
// mat = a3d_TransformMatrix(vecNewDir, vecNormal, g_vOrigin);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// mat = a3d_TransformMatrix(vDir, vUp, g_vOrigin);
|
||||
//}
|
||||
|
||||
//m_quOrientEnd.ConvertFromMatrix(mat);
|
||||
}
|
||||
|
||||
// Calculate distance between this object and specified position
|
||||
public float CalcDist(A3DVECTOR3 vPos, bool b3D)
|
||||
{
|
||||
A3DVECTOR3 vDelta = GetPos() - vPos;
|
||||
return b3D ? vDelta.Magnitude() : vDelta.MagnitudeH();
|
||||
}
|
||||
|
||||
private A3DVECTOR3 Normalize(A3DVECTOR3 v)
|
||||
{
|
||||
float mag = v.Magnitude();
|
||||
if (mag < 1e-12 && mag > -1e-12)
|
||||
return new A3DVECTOR3(0.0f);
|
||||
else
|
||||
return v / mag;
|
||||
}
|
||||
|
||||
public A3DVECTOR3 GetPos()
|
||||
{
|
||||
return new A3DVECTOR3(transform.position.x, transform.position.y, transform.position.z);
|
||||
}
|
||||
|
||||
// Turn around object and face to specified object
|
||||
public virtual void TurnFaceTo(int idTarget, float dwTime = 200)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Set / Get visible flag
|
||||
public void SetVisible(bool bVisible)
|
||||
{
|
||||
m_bVisible = bVisible;
|
||||
}
|
||||
public bool GetVisible()
|
||||
{
|
||||
return m_bVisible;
|
||||
}
|
||||
|
||||
// Get object class ID
|
||||
public int GetClassID() { return m_iCID; }
|
||||
public bool IsPlayer() { return m_iCID == Class_ID.OCID_HOSTPLAYER || m_iCID == Class_ID.OCID_ELSEPLAYER || m_iCID == Class_ID.OCID_LOGINPLAYER; }
|
||||
public bool IsHostPlayer() { return m_iCID == Class_ID.OCID_HOSTPLAYER; }
|
||||
public bool IsElsePlayer() { return m_iCID == Class_ID.OCID_ELSEPLAYER; }
|
||||
public bool IsLoginPlayer(){ return m_iCID == Class_ID.OCID_LOGINPLAYER; }
|
||||
public bool IsNPC() { return m_iCID == Class_ID.OCID_MONSTER || m_iCID == Class_ID.OCID_SERVER; }
|
||||
public bool IsMonsterNPC() { return m_iCID == Class_ID.OCID_MONSTER; }
|
||||
public bool IsServerNPC() { return m_iCID == Class_ID.OCID_SERVER; }
|
||||
public bool IsMatter() { return m_iCID == Class_ID.OCID_MATTER; }
|
||||
public bool IsSelectable() { return m_bSelectable; }
|
||||
// Set / Get object born stamp
|
||||
public uint GetBornStamp() { return m_dwBornStamp; }
|
||||
public void SetBornStamp(uint dwStamp) { m_dwBornStamp = dwStamp; }
|
||||
// Set / Get born in sight flag
|
||||
public bool GetBornInSight() { return m_bBornInSight; }
|
||||
public void SetBornInSight(bool bFlag) { m_bBornInSight = bFlag; }
|
||||
|
||||
// Get object id
|
||||
public static int GetObjectID(CECObject pObject)
|
||||
{
|
||||
if (!pObject)
|
||||
return 0;
|
||||
|
||||
if (pObject.IsPlayer())
|
||||
return ((EC_Player)pObject).GetCharacterID();
|
||||
else if (pObject.IsNPC())
|
||||
return ((CECNPC)pObject).GetNPCID();
|
||||
//else if (pObject.IsMatter())
|
||||
// return ((CECMatter*)pObject)->GetMatterID();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected int m_iCID; // Class ID
|
||||
protected bool m_bAdjustOrient; // Is adjusting orientation
|
||||
//protected A3DQUATERNION m_quOrientStart; // Orientation start
|
||||
//protected A3DQUATERNION m_quOrientEnd; // Orientation end
|
||||
protected float m_dwOrientTime; // Orientation adjusting time counter
|
||||
protected uint m_dwOrientTimeCnt; // Orientation adjusting time counter
|
||||
|
||||
protected bool m_bBornInSight; // Born in my sight
|
||||
protected uint m_dwBornStamp; // Born time stamp
|
||||
protected bool m_bVisible; // Render flag
|
||||
|
||||
protected bool m_bUseGroundNormal; // flag indicates whether we use a ground normal as up
|
||||
protected A3DVECTOR3 m_vecGroundNormal; // current ground normal
|
||||
protected A3DVECTOR3 m_vecGroundNormalSet; // ground normal set
|
||||
|
||||
protected bool m_bSelectable; // whether the object can be selected
|
||||
|
||||
public A3DVECTOR3 GetGroundNormal(){ return m_vecGroundNormal; }
|
||||
public bool GetUseGroundNormal(){ return m_bUseGroundNormal; }
|
||||
|
||||
public void SetUseGroundNormal(bool bFlag)
|
||||
{
|
||||
//if (m_bUseGroundNormal == bFlag)
|
||||
// return;
|
||||
|
||||
//m_bUseGroundNormal = bFlag;
|
||||
//if (m_bUseGroundNormal)
|
||||
//{
|
||||
// // now reset dir and up to make the object show correct pose
|
||||
// SetDirAndUp(GetDir(), GetUp());
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// // now reset dir and up to make the player show correct pose
|
||||
// A3DVECTOR3 vLeft = CrossProduct(GetDir(), g_vAxisY);
|
||||
// A3DVECTOR3 vDir = Normalize(CrossProduct(g_vAxisY, vLeft));
|
||||
// SetDirAndUp(vDir, g_vAxisY);
|
||||
//}
|
||||
}
|
||||
public void SetGroundNormal(A3DVECTOR3 vecNormal)
|
||||
{
|
||||
m_vecGroundNormalSet = vecNormal;
|
||||
}
|
||||
|
||||
protected void AdjustOrientation(float dwDeltaTime)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c36b379029c2c70458f3cb8d204f53d8
|
||||
@@ -0,0 +1,64 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class CECObjectWork
|
||||
{
|
||||
// Attributes
|
||||
protected int m_iWorkID; // Work ID
|
||||
protected bool m_bFinished; // true, Work is finished
|
||||
protected uint m_dwMask; // Mask of this work
|
||||
protected uint m_dwTransMask; // Work transfer masks
|
||||
protected bool m_bFirstTick;
|
||||
// Constructor
|
||||
public CECObjectWork(int iWorkID)
|
||||
{
|
||||
m_iWorkID = iWorkID;
|
||||
m_bFinished = false;
|
||||
m_dwMask = 0;
|
||||
m_dwTransMask = 0;
|
||||
m_bFinished = true;
|
||||
}
|
||||
|
||||
public virtual bool Tick(float dwDeltaTime)
|
||||
{
|
||||
if (m_bFirstTick)
|
||||
{
|
||||
m_bFirstTick = false;
|
||||
OnFirstTick();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Reset work
|
||||
public virtual void Reset()
|
||||
{
|
||||
m_bFinished = false;
|
||||
m_bFirstTick = true;
|
||||
}
|
||||
|
||||
// Work is cancel
|
||||
public virtual void Cancel() { }
|
||||
|
||||
// Can work transfer to another work with specified mask
|
||||
public virtual bool CanTransferTo(uint dwMask)
|
||||
{
|
||||
return (m_dwTransMask & dwMask) != 0;
|
||||
}
|
||||
|
||||
// On work shift to
|
||||
public virtual void OnWorkShift() { }
|
||||
|
||||
// Get work ID
|
||||
public int GetWorkID() => m_iWorkID;
|
||||
|
||||
// Is work finished?
|
||||
public bool IsFinished() => m_bFinished;
|
||||
|
||||
// Get work mask
|
||||
public uint GetWorkMask() => m_dwMask;
|
||||
|
||||
// Get work transfer works
|
||||
public uint GetTransferMask() => m_dwTransMask;
|
||||
|
||||
// On first tick
|
||||
protected virtual void OnFirstTick() { }
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d658d501be8b9f45be5ed066a6efc23
|
||||
@@ -0,0 +1,6 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class EC_RoleTypes
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a00af48d21485d46bf5bae22e8b09f9
|
||||
@@ -0,0 +1,6 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class CECSkill
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a33568a349c4ee9488a562e2c67002e7
|
||||
@@ -13,7 +13,7 @@ public class CECMonster : CECNPC
|
||||
public override void SetUpCECNPC(CECNPCMan pNPCMan)
|
||||
{
|
||||
base.SetUpCECNPC(pNPCMan);
|
||||
m_iCID = (int)ClassID.OCID_MONSTER;
|
||||
m_iCID = (int)Class_ID.OCID_MONSTER;
|
||||
m_pDBEssence = default;
|
||||
}
|
||||
public override bool Init(int tid, in info_npc info, ReadOnlySpan<byte> packet, int infoOffset)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using CSNetwork.GPDataType;
|
||||
using System.Text;
|
||||
using System;
|
||||
using UnityEditor.Rendering;
|
||||
using UnityEngine;
|
||||
using BrewMonster;
|
||||
using CSNetwork;
|
||||
@@ -22,7 +21,7 @@ public class CECNPC : CECObject
|
||||
protected float m_fDistToHost;
|
||||
protected float m_fDistToHostH;
|
||||
protected OtherPlayer_Move_Info m_cdr;
|
||||
protected float m_fTouchRad;
|
||||
protected float m_fTouchRad = 1f;
|
||||
protected ROLEBASICPROP m_BasicProps;
|
||||
protected Vector3 m_vMoveDir;
|
||||
protected int m_iPassiveMove;
|
||||
@@ -44,11 +43,12 @@ public class CECNPC : CECObject
|
||||
protected static CECStringTab m_ActionNames;
|
||||
|
||||
|
||||
|
||||
public virtual void SetUpCECNPC(CECNPCMan pNPCMan)
|
||||
{
|
||||
base.SetUpCECObject();
|
||||
m_vServerPos = new Vector3();
|
||||
m_iCID = (int)ClassID.OCID_NPC;
|
||||
m_iCID = (int)Class_ID.OCID_NPC;
|
||||
}
|
||||
public virtual bool Init(int tid, in info_npc info, ReadOnlySpan<byte> packet, int infoOffset)
|
||||
{
|
||||
@@ -73,9 +73,9 @@ public class CECNPC : CECObject
|
||||
|
||||
_characterController = GetComponent<CharacterController>();
|
||||
|
||||
m_iMoveEnv = (int)((info.state & PlayerNPCState.GP_STATE_NPC_FLY) != 0 ? EnviromentMoveType.MOVEENV_AIR
|
||||
: (info.state & PlayerNPCState.GP_STATE_NPC_SWIM) != 0 ? EnviromentMoveType.MOVEENV_WATER
|
||||
: EnviromentMoveType.MOVEENV_GROUND);
|
||||
m_iMoveEnv = (int)((info.state & PlayerNPCState.GP_STATE_NPC_FLY) != 0 ? Move_environment.MOVEENV_AIR
|
||||
: (info.state & PlayerNPCState.GP_STATE_NPC_SWIM) != 0 ? Move_environment.MOVEENV_WATER
|
||||
: Move_environment.MOVEENV_GROUND);
|
||||
|
||||
var npcVisual = GetComponent<NPCVisual>();
|
||||
m_pNPCModelPolicy.SetNpcVisual(npcVisual);
|
||||
@@ -797,8 +797,10 @@ public class CECNPC : CECObject
|
||||
}
|
||||
}
|
||||
bool IsMonsterOrPet() { return IsMonsterNPC() || IsPetNPC(); }
|
||||
bool IsMonsterNPC() { return (int)ClassID.OCID_MONSTER == m_iCID; }
|
||||
bool IsPetNPC() { return (int)ClassID.OCID_PET == m_iCID; }
|
||||
bool IsMonsterNPC() { return (int)Class_ID.OCID_MONSTER == m_iCID; }
|
||||
bool IsPetNPC() { return (int)Class_ID.OCID_PET == m_iCID; }
|
||||
|
||||
public bool IsDead(){ return (m_dwStates & PlayerNPCState.GP_STATE_CORPSE) != 0; }
|
||||
public void PlayMoveAction(int iMoveMode)
|
||||
{
|
||||
BrewMonster.BMLogger.LogError($"HoangDev: PlayMoveAction {iMoveMode}");
|
||||
@@ -850,6 +852,8 @@ public class CECNPC : CECObject
|
||||
}
|
||||
bool IsDisappearing() { return m_DisappearCnt == 0 ? true : false; }
|
||||
|
||||
public float GetTouchRadius() { return m_fTouchRad; }
|
||||
|
||||
bool IsLag(float fDist)
|
||||
{
|
||||
return m_iPassiveMove == 0 && fDist > MAX_LAGDIST;
|
||||
@@ -863,6 +867,41 @@ public class CECNPC : CECObject
|
||||
public int vis_tid;// template id for shape
|
||||
};
|
||||
public const float MAX_LAGDIST = 25.0f;
|
||||
|
||||
// Get NPC's real position on server
|
||||
public A3DVECTOR3 GetServerPos()
|
||||
{
|
||||
return EC_Utility.ToA3DVECTOR3(m_vServerPos);
|
||||
}
|
||||
|
||||
// Get master id
|
||||
public int GetMasterID() { return m_idMaster; }
|
||||
// Is monster in invader camp in battle ?
|
||||
public virtual bool IsInBattleInvaderCamp() { return false; }
|
||||
// Is monster in defender camp in battle ?
|
||||
public virtual bool IsInBattleDefenderCamp() { return false; }
|
||||
// Get role in battle
|
||||
public virtual int GetRoleInBattle() { return 0; }
|
||||
public int GetOwnerFaction(){ return m_idOwnerFaction; }
|
||||
|
||||
public bool IsFactionPVPMineCar()
|
||||
{
|
||||
//if (const MONSTER_ESSENCE* pMonsterEssence = GetMonsterEssence()){
|
||||
// return (pMonsterEssence.faction & (1 << 19)) != 0;
|
||||
//}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsFactionPVPMineBase()
|
||||
{
|
||||
//if (const MONSTER_ESSENCE *pMonsterEssence = GetMonsterEssence()){
|
||||
// return (pMonsterEssence->faction & (1 << 20)) != 0;
|
||||
//}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get NPC ID
|
||||
public int GetNPCID() { return m_NPCInfo.nid; }
|
||||
}
|
||||
public enum WorkType
|
||||
{
|
||||
|
||||
@@ -1323,6 +1323,16 @@ namespace CSNetwork.S2CCommand
|
||||
// public byte size;
|
||||
// public char data[1];
|
||||
//};
|
||||
|
||||
public struct cmd_sevnpc_hello
|
||||
{
|
||||
public int id;
|
||||
};
|
||||
|
||||
public struct cmd_normal_attack
|
||||
{
|
||||
public byte pvp_mask;
|
||||
};
|
||||
}
|
||||
|
||||
// Player and NPC state
|
||||
@@ -403,5 +403,28 @@ namespace CSNetwork.C2SCommand
|
||||
// Serialize the command and return the serialized data
|
||||
return SerializeCommand(CommandID.GET_ALL_DATA, cmd);
|
||||
}
|
||||
|
||||
public static Octets CreateNPCSevHelloDataCommand(int iD)
|
||||
{
|
||||
var cmd = new cmd_sevnpc_hello
|
||||
{
|
||||
id = iD
|
||||
};
|
||||
return SerializeCommand(CommandID.SEVNPC_HELLO, cmd);
|
||||
}
|
||||
|
||||
public static Octets CreateNormalAttackDataCmd(byte byPVPMask)
|
||||
{
|
||||
var cmd = new cmd_normal_attack
|
||||
{
|
||||
pvp_mask = byPVPMask
|
||||
};
|
||||
return SerializeCommand(CommandID.NORMAL_ATTACK, cmd);
|
||||
}
|
||||
|
||||
public static Octets CreateNakeCmd(CommandID iCmd)
|
||||
{
|
||||
return SerializeCommand(iCmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0c06c588e2a6442488a3542551fb243
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -892,7 +892,7 @@ namespace CSNetwork.GPDataType
|
||||
public byte index_equip;
|
||||
public uint amount;
|
||||
};
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct cmd_player_drop_item
|
||||
{
|
||||
@@ -912,9 +912,9 @@ namespace CSNetwork.GPDataType
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_matter_enter_world
|
||||
{
|
||||
public info_matter Info;
|
||||
public info_matter Info;
|
||||
};
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct cmd_pickup_item
|
||||
{
|
||||
@@ -1075,9 +1075,33 @@ namespace CSNetwork.GPDataType
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ISPLAYERID(int id)
|
||||
{
|
||||
return id != 0 && (id & 0x80000000) == 0;
|
||||
}
|
||||
public static bool ISNPCID(int id)
|
||||
{
|
||||
return (id & 0x80000000) != 0 && (id & 0x40000000) == 0;
|
||||
}
|
||||
|
||||
public static bool ISMATTERID(int id)
|
||||
{
|
||||
return (id & 0xC0000000) == 0xC0000000;
|
||||
}
|
||||
|
||||
public static A3DVECTOR3 g_vOrigin = new A3DVECTOR3(0.0f);
|
||||
public static A3DVECTOR3 g_vAxisX = new A3DVECTOR3(1.0f, 0.0f, 0.0f);
|
||||
public static A3DVECTOR3 g_vAxisY = new A3DVECTOR3(0.0f, 1.0f, 0.0f);
|
||||
public static A3DVECTOR3 g_vAxisZ = new A3DVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
|
||||
// Move length minimum threshold
|
||||
public const float MIN_MOVELEN_IN_AIR_WATER = 0.5f;
|
||||
public const float MIN_MOVELEN_ON_GROUND = 0.5f;
|
||||
public const float MIN_MOVELEN_FOR_DETECT_VIBRATION = 0.05f;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_npc_info_list
|
||||
{
|
||||
public ushort count;
|
||||
@@ -1121,10 +1145,10 @@ namespace CSNetwork.GPDataType
|
||||
};
|
||||
public struct cmd_npc_info_00
|
||||
{
|
||||
public int idNPC;
|
||||
public int iHP;
|
||||
public int iMaxHP;
|
||||
public int iTargetID;
|
||||
public int idNPC;
|
||||
public int iHP;
|
||||
public int iMaxHP;
|
||||
public int iTargetID;
|
||||
};
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)] // sizeof = 36 với padding 1 byte sau dir
|
||||
public struct info_npc
|
||||
@@ -1216,5 +1240,30 @@ namespace CSNetwork.GPDataType
|
||||
{
|
||||
OBJECT_EXT_STATE_COUNT = 6, // Íæ¼Ò/NPC ÉíÉÏ״̬¹âЧ DWORD ¸öÊý
|
||||
};
|
||||
|
||||
// Player camp in battle
|
||||
public static class Player_camp_in_battle
|
||||
{
|
||||
public const int GP_BATTLE_CAMP_NONE = 0,
|
||||
GP_BATTLE_CAMP_INVADER = 1,
|
||||
GP_BATTLE_CAMP_DEFENDER = 2;
|
||||
};
|
||||
|
||||
// PVP mask
|
||||
[Flags]
|
||||
public enum PVP_mask : byte
|
||||
{
|
||||
GP_PVPMASK_FORCE = 0x0001, // Ç¿Á¦¹¥»÷
|
||||
GP_PVPMASK_NOMAFIA = 0x0002,
|
||||
GP_PVPMASK_NOWHITE = 0x0004,
|
||||
GP_PVPMASK_NOALLIANCE = 0x0008,
|
||||
GP_PVPMASK_NOFORCE = 0x0010,//²»¹¥»÷Í¬ÊÆÁ¦µÄ
|
||||
|
||||
GP_BLSMASK_NORED = 0x0008,
|
||||
GP_BLSMASK_NOMAFIA = 0x0010,
|
||||
GP_BLSMASK_SELF = 0x0020,
|
||||
GP_BLSMASK_NOALLIANCE = 0x0040,
|
||||
GP_BLSMASK_NOFORCE = 0x0080 // ÊÆÁ¦ÆÁ±Î
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -727,5 +727,26 @@ namespace CSNetwork
|
||||
_logger.Log(LogType.Warning, $"[Dat]- SendCmdGetAllData {byPack},{byEquip},{byTask}");
|
||||
SendProtocol(gamedatasend);
|
||||
}
|
||||
|
||||
public void c2s_SendCmdNPCSevHello(int nid)
|
||||
{
|
||||
gamedatasend gamedatasend = new gamedatasend();
|
||||
gamedatasend.Data = C2SCommandFactory.CreateNPCSevHelloDataCommand(nid);
|
||||
SendProtocol(gamedatasend);
|
||||
}
|
||||
|
||||
public void c2s_CmdNormalAttack(byte byPVPMask)
|
||||
{
|
||||
gamedatasend gamedatasend = new gamedatasend();
|
||||
gamedatasend.Data = C2SCommandFactory.CreateNormalAttackDataCmd(byPVPMask);
|
||||
SendProtocol(gamedatasend);
|
||||
}
|
||||
|
||||
public void c2s_CmdCancelAction()
|
||||
{
|
||||
gamedatasend gamedatasend = new gamedatasend();
|
||||
gamedatasend.Data = C2SCommandFactory.CreateNakeCmd(CSNetwork.C2SCommand.CommandID.CANCEL_ACTION);
|
||||
SendProtocol(gamedatasend);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
-2
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3cf084cf53b24fe7a6bffb17846d608
|
||||
@@ -2,6 +2,9 @@ using System;
|
||||
using UnityEngine;
|
||||
using CSNetwork;
|
||||
using PerfectWorld.Scripts.Managers.BrewMonster.Managers;
|
||||
using BrewMonster.Network;
|
||||
using UnityEngine.SceneManagement;
|
||||
using CSNetwork.GPDataType;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
@@ -50,5 +53,35 @@ namespace BrewMonster
|
||||
{
|
||||
EC_ManMessage.Tick();
|
||||
}
|
||||
|
||||
// Get object by specified ID
|
||||
// iAliveFlag: 0, both alive and dead; 1, must be alive; 2, must be dead
|
||||
public CECObject GetObject(int idObject, int iAliveFlag)
|
||||
{
|
||||
CECObject pObject = null;
|
||||
|
||||
if (GPDataTypeHelper.ISNPCID(idObject))
|
||||
{
|
||||
if (!(pObject = _CECNPCMan.GetNPC(idObject)))
|
||||
return null;
|
||||
|
||||
if ((iAliveFlag == 1 && (pObject as CECNPC).IsDead()) ||
|
||||
(iAliveFlag == 2 && !(pObject as CECNPC).IsDead()))
|
||||
return null;
|
||||
}
|
||||
else if (GPDataTypeHelper.ISPLAYERID(idObject))
|
||||
{
|
||||
if (!(pObject = EC_ManPlayer.GetPlayer(idObject)))
|
||||
return null;
|
||||
|
||||
if ((iAliveFlag == 1 && (pObject as EC_Player).IsDead()) ||
|
||||
(iAliveFlag == 2 && !(pObject as EC_Player).IsDead()))
|
||||
return null;
|
||||
}
|
||||
//else if (GPDataTypeHelper.ISMATTERID(idObject))
|
||||
// pObject = GetMatterMan()->GetMatter(idObject);
|
||||
|
||||
return pObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -179,6 +179,21 @@ namespace BrewMonster.Network
|
||||
}
|
||||
}
|
||||
|
||||
public static void c2s_CmdNPCSevHello(int nid)
|
||||
{
|
||||
Instance._gameSession.c2s_SendCmdNPCSevHello(nid);
|
||||
}
|
||||
|
||||
public static void c2s_CmdNormalAttack(byte byPVPMask)
|
||||
{
|
||||
Instance._gameSession.c2s_CmdNormalAttack(byPVPMask);
|
||||
}
|
||||
|
||||
public static void c2s_CmdCancelAction()
|
||||
{
|
||||
Instance._gameSession.c2s_CmdCancelAction();
|
||||
}
|
||||
|
||||
#region Task
|
||||
public static void c2s_CmdGetAllData(bool byPack, bool byEquip, bool byTask)
|
||||
{
|
||||
|
||||
@@ -30,9 +30,9 @@ namespace PerfectWorld.Scripts.Player
|
||||
int m_iGender; // Gender
|
||||
float m_fScaleBySkill = 1f;
|
||||
MOVECONST m_MoveConst; // Const used when moving control
|
||||
int m_iMoveEnv; // Move environment
|
||||
bool m_bWalkRun; // Walk-run switch, 0-walk, 1-run
|
||||
int m_iMoveMode; // Player's move mode
|
||||
//int m_iMoveEnv; // Move environment
|
||||
//bool m_bWalkRun; // Walk-run switch, 0-walk, 1-run
|
||||
//int m_iMoveMode; // Player's move mode
|
||||
|
||||
public MOVECONST[] aMoveConsts = new MOVECONST[PROFESSION.NUM_PROFESSION * GENDER.NUM_GENDER]
|
||||
{
|
||||
@@ -445,7 +445,7 @@ namespace PerfectWorld.Scripts.Player
|
||||
m_aabbServer.CompleteMinsMaxs();
|
||||
}
|
||||
|
||||
private A3DVECTOR3 GetPos()
|
||||
public A3DVECTOR3 GetPos()
|
||||
{
|
||||
A3DVECTOR3 result = new A3DVECTOR3();
|
||||
result.x = transform.position.x;
|
||||
@@ -454,70 +454,13 @@ namespace PerfectWorld.Scripts.Player
|
||||
return result;
|
||||
}
|
||||
|
||||
private int GetMoveStandAction(bool bMove, bool bFight = false)
|
||||
{
|
||||
int iMoveEnv = m_iMoveEnv;
|
||||
//if (m_AttachMode != enumAttachNone)
|
||||
//{
|
||||
// bFight = false;
|
||||
// if (m_bHangerOn)
|
||||
// iMoveEnv = MOVEENV_GROUND;
|
||||
//}
|
||||
// Get player's real position on server
|
||||
public A3DVECTOR3 GetServerPos() { return m_vServerPos; }
|
||||
|
||||
int iAction = (int)PLAYER_ACTION_TYPE.ACT_STAND;
|
||||
|
||||
if (bMove)
|
||||
{
|
||||
// Play appropriate actions
|
||||
if (iMoveEnv == (int)MoveEnvironment.MOVEENV_GROUND)
|
||||
{
|
||||
if (m_bWalkRun)
|
||||
iAction = (int)PLAYER_ACTION_TYPE.ACT_RUN;
|
||||
else
|
||||
iAction = (int)PLAYER_ACTION_TYPE.ACT_WALK;
|
||||
}
|
||||
//else if (iMoveEnv == MOVEENV_AIR)
|
||||
//{
|
||||
// //if (/*UsingWing()*/ m_wingType == WINGTYPE_WING)
|
||||
// // iAction = ACT_FLY;
|
||||
// //else
|
||||
// // iAction = ACT_FLY_SWORD;
|
||||
//}
|
||||
//else if (iMoveEnv == MOVEENV_WATER)
|
||||
//{
|
||||
// //if (CanCombineWithMoveForSkill())
|
||||
// //{
|
||||
// // iAction = ACT_SWIM_FOR_MOVESKILL;
|
||||
// //}
|
||||
// //else
|
||||
// //{
|
||||
// // iAction = ACT_SWIM;
|
||||
// //}
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Play appropriate actions
|
||||
if (iMoveEnv == (int)MoveEnvironment.MOVEENV_GROUND)
|
||||
{
|
||||
if (bFight)
|
||||
iAction = (int)PLAYER_ACTION_TYPE.ACT_FIGHTSTAND;
|
||||
else
|
||||
iAction = (int)PLAYER_ACTION_TYPE.ACT_STAND;
|
||||
}
|
||||
//else if (iMoveEnv == MOVEENV_AIR)
|
||||
//{
|
||||
// if (/*UsingWing()*/ m_wingType == WINGTYPE_WING)
|
||||
// iAction = ACT_HANGINAIR;
|
||||
// else
|
||||
// iAction = ACT_HANGINAIR_SWORD;
|
||||
//}
|
||||
//else if (iMoveEnv == MOVEENV_WATER)
|
||||
// iAction = ACT_HANGINWATER;
|
||||
}
|
||||
|
||||
return iAction;
|
||||
}
|
||||
//public A3DVECTOR3 GetPos()
|
||||
//{
|
||||
// return new A3DVECTOR3(transform.position.x, transform.position.y, transform.position.z);
|
||||
//}
|
||||
}
|
||||
|
||||
// Player appear flag
|
||||
|
||||
+463
-45
@@ -1,16 +1,17 @@
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster;
|
||||
using BrewMonster.Network;
|
||||
using CSNetwork;
|
||||
using CSNetwork.GPDataType;
|
||||
using CSNetwork.Protocols;
|
||||
using CSNetwork.Protocols.RPCData;
|
||||
using PerfectWorld.Scripts.Managers;
|
||||
using PerfectWorld.Scripts.Player;
|
||||
using PerfectWorld.Scripts.Task;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using TMPro;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.SceneManagement;
|
||||
@@ -30,7 +31,18 @@ public class CECHostPlayer : EC_Player
|
||||
PlayerStateMachine _playerStateMachine;
|
||||
PlayerMoveState _moveState;
|
||||
PlayerIdleState _idleState;
|
||||
CECHostMove m_MoveCtrl;
|
||||
public CECHostMove m_MoveCtrl;
|
||||
|
||||
CECHPWorkMan m_pWorkMan; // Host work manager
|
||||
uint m_dwLIES; // Logic-influence extend states
|
||||
FACTION_FORTRESS_ENTER m_fortressEnter; // ½øÈë»ùµØÐÅÏ¢
|
||||
PVPINFO m_pvp; // pvp information
|
||||
bool m_bInSanctuary = false; // true, player is in sanctuary
|
||||
int m_idFaction = 0; // ID of player's faction
|
||||
public bool m_bPrepareFight = false; // true, prepare to fight
|
||||
int m_iJumpCount = 0;
|
||||
bool m_bJumpInWater = false;
|
||||
public A3DVECTOR3 m_vVelocity; // Velocity
|
||||
|
||||
float playerSpeed = 5.0f;
|
||||
float jumpHeight = 1.5f;
|
||||
@@ -40,6 +52,9 @@ public class CECHostPlayer : EC_Player
|
||||
bool isGrounded = false;
|
||||
bool isRun = false;
|
||||
Vector3 m_vLastSevPos;
|
||||
public CDR_INFO m_CDRInfo;
|
||||
public GNDINFO m_GndInfo;
|
||||
public float m_fVertSpeed = 0f;
|
||||
|
||||
// ====== Ground cast config ======
|
||||
[Header("Ground Cast")]
|
||||
@@ -214,7 +229,7 @@ public class CECHostPlayer : EC_Player
|
||||
case int value when value == EC_MsgDef.MSG_HST_TASKDATA:
|
||||
{
|
||||
OnMsgHstTaskData(Msg);
|
||||
Debug.Log("[Dat]- OnMsgHstTaskData");
|
||||
Debug.LogError("[Dat]- OnMsgHstTaskData");
|
||||
break;
|
||||
}
|
||||
case int value when value == EC_MsgDef.MSG_HST_ITEMOPERATION:
|
||||
@@ -331,34 +346,34 @@ public class CECHostPlayer : EC_Player
|
||||
break;
|
||||
}
|
||||
case CommandID.EQUIP_ITEM:
|
||||
{
|
||||
{
|
||||
byte index_inv = data[0];
|
||||
byte index_equip = data[1];
|
||||
// Update client-side data: move item between PACK_INVENTORY and PACK_EQUIPMENT
|
||||
var invItem = EC_Inventory.GetItem(EC_Inventory.PACK_INVENTORY, index_inv, true);
|
||||
var equipItem = EC_Inventory.GetItem(EC_Inventory.PACK_EQUIPMENT, index_equip, true);
|
||||
if (invItem != null)
|
||||
{
|
||||
invItem.Package = EC_Inventory.PACK_EQUIPMENT;
|
||||
invItem.Slot = index_equip;
|
||||
EC_Inventory.SetItem(EC_Inventory.PACK_EQUIPMENT, index_equip, invItem);
|
||||
}
|
||||
if (equipItem != null)
|
||||
{
|
||||
equipItem.Package = EC_Inventory.PACK_INVENTORY;
|
||||
equipItem.Slot = index_inv;
|
||||
EC_Inventory.SetItem(EC_Inventory.PACK_INVENTORY, index_inv, equipItem);
|
||||
}
|
||||
// Update client-side data: move item between PACK_INVENTORY and PACK_EQUIPMENT
|
||||
var invItem = EC_Inventory.GetItem(EC_Inventory.PACK_INVENTORY, index_inv, true);
|
||||
var equipItem = EC_Inventory.GetItem(EC_Inventory.PACK_EQUIPMENT, index_equip, true);
|
||||
if (invItem != null)
|
||||
{
|
||||
invItem.Package = EC_Inventory.PACK_EQUIPMENT;
|
||||
invItem.Slot = index_equip;
|
||||
EC_Inventory.SetItem(EC_Inventory.PACK_EQUIPMENT, index_equip, invItem);
|
||||
}
|
||||
if (equipItem != null)
|
||||
{
|
||||
equipItem.Package = EC_Inventory.PACK_INVENTORY;
|
||||
equipItem.Slot = index_inv;
|
||||
EC_Inventory.SetItem(EC_Inventory.PACK_INVENTORY, index_inv, equipItem);
|
||||
}
|
||||
|
||||
// Trigger UI refresh if an EC_InventoryUI is present in scene
|
||||
var ui = GameObject.FindObjectOfType<EC_InventoryUI>();
|
||||
if (ui != null)
|
||||
{
|
||||
ui.RefreshAll();
|
||||
}
|
||||
// Trigger UI refresh if an EC_InventoryUI is present in scene
|
||||
var ui = GameObject.FindObjectOfType<EC_InventoryUI>();
|
||||
if (ui != null)
|
||||
{
|
||||
ui.RefreshAll();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public void OnMsgHstOwnItemInfo(ECMSG Msg)
|
||||
@@ -428,7 +443,7 @@ public class CECHostPlayer : EC_Player
|
||||
|
||||
}
|
||||
|
||||
private void SetPos(Vector3 pos)
|
||||
public void SetPos(Vector3 pos)
|
||||
{
|
||||
transform.position = pos;
|
||||
}
|
||||
@@ -461,6 +476,13 @@ public class CECHostPlayer : EC_Player
|
||||
{
|
||||
visual.InitHostPlayerEventDoneHandler();
|
||||
}
|
||||
|
||||
// Create work manager
|
||||
m_pWorkMan = new CECHPWorkMan(this);
|
||||
if (m_pWorkMan == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void JoystickStartDrag(JoystickPressEvent joystickPressEvent)
|
||||
@@ -497,7 +519,7 @@ public class CECHostPlayer : EC_Player
|
||||
//cmd_task_data* pCmd = (cmd_task_data*)Msg.dwParam1;
|
||||
//ASSERT(pCmd);
|
||||
|
||||
//int iActiveListSize = (int)pCmd->active_list_size;
|
||||
//int iActiveListSize = (int)pCmd.active_list_size;
|
||||
//BYTE* pData = (BYTE*)pCmd + sizeof(size_t);
|
||||
//void* pActiveListbuf = pData;
|
||||
//pData += iActiveListSize;
|
||||
@@ -523,30 +545,30 @@ public class CECHostPlayer : EC_Player
|
||||
//pData += iStorageTasksListSize;
|
||||
|
||||
//A3DRELEASE(m_pTaskInterface);
|
||||
|
||||
return;
|
||||
var m_pTaskInterface = new CECTaskInterface(this);
|
||||
|
||||
if (!m_pTaskInterface.Init(null, 0, null, 0,
|
||||
null, 0, null, 0, null, 0))
|
||||
{
|
||||
//a_LogOutput(1, "CECHostPlayer::OnMsgHstTaskData, failed to initialize task interface");
|
||||
return;
|
||||
}
|
||||
//todo
|
||||
//var m_pTaskInterface = new CECTaskInterface(this);
|
||||
|
||||
m_pTaskInterface.CheckPQEnterWorldInit();
|
||||
//if (!m_pTaskInterface.Init(null, 0, null, 0,
|
||||
// null, 0, null, 0, null, 0))
|
||||
//{
|
||||
// //a_LogOutput(1, "CECHostPlayer::OnMsgHstTaskData, failed to initialize task interface");
|
||||
// return;
|
||||
//}
|
||||
|
||||
//m_pTaskInterface.CheckPQEnterWorldInit();
|
||||
|
||||
//// check if player has equipped goblin
|
||||
//if (m_pEquipPack->GetItem(EQUIPIVTR_GOBLIN) != NULL)
|
||||
//if (m_pEquipPack.GetItem(EQUIPIVTR_GOBLIN) != NULL)
|
||||
//{
|
||||
// CECIvtrGoblin* pIvtrGoblin = (CECIvtrGoblin*)m_pEquipPack->GetItem(EQUIPIVTR_GOBLIN);
|
||||
// CECIvtrGoblin* pIvtrGoblin = (CECIvtrGoblin*)m_pEquipPack.GetItem(EQUIPIVTR_GOBLIN);
|
||||
// m_pGoblin = new CECHostGoblin();
|
||||
// m_pGoblin->Init(pIvtrGoblin->GetTemplateID(), pIvtrGoblin, this);
|
||||
// m_pGoblin.Init(pIvtrGoblin.GetTemplateID(), pIvtrGoblin, this);
|
||||
//}
|
||||
|
||||
//// Note: this command now is also used as the end flag of responding
|
||||
//// for GET_ALL_DATA request
|
||||
//g_pGame->GetGameSession()->LoadConfigData();
|
||||
//g_pGame.GetGameSession().LoadConfigData();
|
||||
|
||||
//// ¸ù¾Ý×°±¸°ü¹ü¸üÐÂ×°±¸¼¼Äܵ½¼¼ÄÜÁбí
|
||||
//if (UpdateEquipSkills())
|
||||
@@ -557,12 +579,357 @@ public class CECHostPlayer : EC_Player
|
||||
//cmd_task_var_data* pCmd = (cmd_task_var_data*)Msg.dwParam1;
|
||||
//ASSERT(pCmd);
|
||||
//if (m_pTaskInterface)
|
||||
// OnServerNotify(m_pTaskInterface, pCmd->data, pCmd->size);
|
||||
// OnServerNotify(m_pTaskInterface, pCmd.data, pCmd.size);
|
||||
//else
|
||||
// ASSERT(m_pTaskInterface);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private bool NormalAttackObject(int idTarget, bool bForceAttack, bool bMoreClose = false)
|
||||
{
|
||||
if (idTarget == 0 || idTarget == m_PlayerInfo.cid)
|
||||
{
|
||||
// We should have check target isn't dead
|
||||
return false;
|
||||
}
|
||||
//if (!EC_Game.GetGameRun().GetWorld().GetObject(idTarget, 1))
|
||||
// return false;
|
||||
bool bStartNewWork = false;
|
||||
|
||||
bool bUseAutoPF = false;
|
||||
//CECPlayerWrapper* pWrapper = CECAutoPolicy::GetInstance().GetPlayerWrapper();
|
||||
//if (CECAutoPolicy::GetInstance().IsAutoPolicyEnabled() && pWrapper.GetAttackError() >= 2)
|
||||
bUseAutoPF = true;
|
||||
|
||||
CECHPWorkTrace pWorkTrace = null;
|
||||
CECHPWork pWork = null;
|
||||
if ((pWork = m_pWorkMan.GetWork(CECHPWork.Host_work_ID.WORK_TRACEOBJECT)) != null)
|
||||
{
|
||||
pWorkTrace = pWork as CECHPWorkTrace;
|
||||
}
|
||||
else if ((pWork = m_pWorkMan.GetWork(CECHPWork.Host_work_ID.WORK_HACKOBJECT)) != null)
|
||||
{
|
||||
if ((pWork as CECHPWorkMelee).GetTarget() == idTarget)
|
||||
return false; // Host is attacking the target
|
||||
|
||||
pWorkTrace = (CECHPWorkTrace)m_pWorkMan.CreateWork(CECHPWork.Host_work_ID.WORK_TRACEOBJECT);
|
||||
bStartNewWork = true;
|
||||
}
|
||||
else if (m_pWorkMan.CanStartWork(CECHPWork.Host_work_ID.WORK_TRACEOBJECT))
|
||||
{
|
||||
pWorkTrace = (CECHPWorkTrace)m_pWorkMan.CreateWork(CECHPWork.Host_work_ID.WORK_TRACEOBJECT);
|
||||
bStartNewWork = true;
|
||||
}
|
||||
|
||||
if (pWorkTrace != null)
|
||||
{
|
||||
pWorkTrace.SetTraceTarget(pWorkTrace.CreatTraceTarget(idTarget, CECHPWorkTrace.Trace_reason.TRACE_ATTACK, bForceAttack), bUseAutoPF);
|
||||
pWorkTrace.SetMoveCloseFlag(bMoreClose);
|
||||
|
||||
if (bStartNewWork)
|
||||
m_pWorkMan.StartWork_p1(pWorkTrace);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int AttackableJudge(int idTarget, bool bForceAttack)
|
||||
{
|
||||
if (CannotAttack())
|
||||
return 0;
|
||||
|
||||
//if (CDlgAutoHelp::IsAutoHelp())
|
||||
// return 0;
|
||||
|
||||
if (idTarget == 0 || idTarget == m_PlayerInfo.cid)
|
||||
return -1;
|
||||
|
||||
CECObject pObject = EC_ManMessageMono.Instance.GetObject(idTarget, 1);
|
||||
if (!pObject)
|
||||
return -1;
|
||||
|
||||
// If target is pet, it's attacked possibility depends on it's monster
|
||||
if (GPDataTypeHelper.ISNPCID(idTarget))
|
||||
{
|
||||
CECNPC pNPC = (CECNPC)pObject;
|
||||
int idMaster = pNPC.GetMasterID();
|
||||
if (idMaster != 0)
|
||||
{
|
||||
// master¿ÉÄÜÊÇhostplayer
|
||||
if (idMaster == m_PlayerInfo.cid)
|
||||
return 0;
|
||||
|
||||
//// Follow pet cannot be attacked
|
||||
//if (pNPC.IsPetNPC() && ((CECPet)pNPC).IsFollowPet())
|
||||
// return 0;
|
||||
|
||||
idTarget = idMaster;
|
||||
pObject = EC_ManMessageMono.Instance.GetObject(idTarget, 1);
|
||||
if (!pObject)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int iRet = 0;
|
||||
|
||||
if (GPDataTypeHelper.ISNPCID(idTarget))
|
||||
{
|
||||
CECNPC pNPC = (CECNPC)pObject;
|
||||
|
||||
// If this npc is host's pet, cannot be attacked
|
||||
//if (pNPC.GetMasterID() == m_PlayerInfo.cid)
|
||||
// return 0;
|
||||
|
||||
// If it's a pet and can not be attacked, pet can be attacked only if it's a fighting pet
|
||||
//if (pNPC.IsPetNPC() && !((CECPet)pNPC).CanBeAttacked())
|
||||
// return 0;
|
||||
|
||||
if (IsInBattle()) // Host is in battle
|
||||
{
|
||||
if (InSameBattleCamp(pNPC))
|
||||
iRet = 0;
|
||||
else
|
||||
{
|
||||
if (pNPC.IsMonsterNPC())
|
||||
iRet = 1;
|
||||
else if (pNPC.IsServerNPC() && (IsInFortress() || pNPC.GetRoleInBattle() == 8)) // ¶Ô·þÎñÐÍNPCµÄ¹¥»÷£¬°ïÅÉ»ùµØ»ò³Çսʱ¿ÉÓÃ
|
||||
iRet = 1;
|
||||
else
|
||||
iRet = 0;
|
||||
}
|
||||
}
|
||||
else if (pNPC.IsServerNPC())
|
||||
{
|
||||
// In sanctuary we cannot attack NPCs
|
||||
if (!IsPVPOpen() || m_bInSanctuary || !bForceAttack)
|
||||
iRet = 0;
|
||||
else
|
||||
iRet = 1;
|
||||
}
|
||||
else // Is monster
|
||||
{
|
||||
iRet = 1;
|
||||
}
|
||||
if (iRet == 1 && pNPC.GetOwnerFaction() > 0)
|
||||
{
|
||||
// Õë¶Ô°ïÅÉ PVP Õ½ÕùÖнûÖ¹²¿·Ö¹¥»÷
|
||||
if (GetFactionID() == pNPC.GetOwnerFaction() || // ²»¹¥»÷ͬ°ï¹Ö
|
||||
pNPC.IsFactionPVPMineCar() && !CanAttackFactionPVPMineCar() || // ÎÞ·¨ÔÙ¹¥»÷Ëû°ï¿ó³µÇé¿ö
|
||||
pNPC.IsFactionPVPMineBase() && !CanAttackFactionPVPMineBase())
|
||||
{ // ÎÞ·¨ÔÙ¹¥»÷Ëû°ï´æ¿óµãÇé¿ö
|
||||
iRet = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TO DO: fix later
|
||||
//else if (GPDataTypeHelper.ISPLAYERID(idTarget))
|
||||
//{
|
||||
// // Check duel at first
|
||||
// if (m_pvp.iDuelState == Duel_state.DUEL_ST_INDUEL && m_pvp.idDuelOpp == idTarget)
|
||||
// return 1;
|
||||
// else if (m_pvp.iDuelState == Duel_state.DUEL_ST_STOPPING && m_pvp.idDuelOpp == idTarget)
|
||||
// return 0;
|
||||
|
||||
// // In sanctuary we cannot attack other players
|
||||
// if (m_bInSanctuary)
|
||||
// return 0;
|
||||
|
||||
// //ASSERT(pObject.GetClassID() == CECObject::OCID_ELSEPLAYER);
|
||||
// EC_ElsePlayer pPlayer = (EC_ElsePlayer)pObject;
|
||||
// ROLEBASICPROP bp = pPlayer.GetBasicProps();
|
||||
// EC_GAME_SETTING gs = g_pGame.GetConfigs().GetGameSettings();
|
||||
|
||||
// if (m_pvp.bFreePVP)
|
||||
// {
|
||||
// if (IsTeamMember(idTarget))
|
||||
// return 0;
|
||||
|
||||
// // In free pvp mode, for example, host is in arena.
|
||||
// if (bForceAttack)
|
||||
// iRet = 1;
|
||||
// else if (gs.bAtk_NoMafia && IsFactionMember(pPlayer.GetFactionID()))
|
||||
// iRet = 0;
|
||||
// else if (gs.bAtk_NoWhite && !pPlayer.IsInvader() && !pPlayer.IsPariah())
|
||||
// iRet = 0;
|
||||
// else if (gs.bAtk_NoAlliance && g_pGame.GetFactionMan().IsFactionAlliance(pPlayer.GetFactionID()))
|
||||
// iRet = 0;
|
||||
// else if (gs.bAtk_NoForce && GetForce() > 0 && GetForce() == pPlayer.GetForce())
|
||||
// iRet = 0;
|
||||
// else
|
||||
// iRet = 1;
|
||||
// }
|
||||
// else if (m_iBattleCamp != GP_BATTLE_CAMP_NONE)
|
||||
// {
|
||||
// // Host is in battle
|
||||
// int iCamp = pPlayer.GetBattleCamp();
|
||||
// if (iCamp != GP_BATTLE_CAMP_NONE && iCamp != m_iBattleCamp)
|
||||
// iRet = 1;
|
||||
// else
|
||||
// iRet = 0;
|
||||
// }
|
||||
// else // Normal mode
|
||||
// {
|
||||
// if (IsTeamMember(idTarget))
|
||||
// return 0;
|
||||
|
||||
// if (!IsPVPOpen() || !pPlayer.IsPVPOpen() || m_BasicProps.iLevel < EC_MAXNOPKLEVEL || bp.iLevel < EC_MAXNOPKLEVEL)
|
||||
// iRet = 0;
|
||||
// else if (bForceAttack)
|
||||
// iRet = 1;
|
||||
// else if (!gs.bAtk_Player)
|
||||
// iRet = 0;
|
||||
// else if (gs.bAtk_NoMafia && IsFactionMember(pPlayer.GetFactionID()))
|
||||
// iRet = 0;
|
||||
// else if (gs.bAtk_NoWhite && !pPlayer.IsInvader() && !pPlayer.IsPariah())
|
||||
// iRet = 0;
|
||||
// else if (gs.bAtk_NoAlliance && g_pGame.GetFactionMan().IsFactionAlliance(pPlayer.GetFactionID()))
|
||||
// iRet = 0;
|
||||
// else if (gs.bAtk_NoForce && GetForce() > 0 && GetForce() == pPlayer.GetForce())
|
||||
// iRet = 0;
|
||||
// else
|
||||
// iRet = 1;
|
||||
// }
|
||||
//}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return iRet;
|
||||
}
|
||||
|
||||
private float A3d_Magnitude(A3DVECTOR3 v)
|
||||
{
|
||||
return Mathf.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
|
||||
}
|
||||
|
||||
public int GetCharacterID(){ return m_PlayerInfo.cid; }
|
||||
|
||||
public bool CannotAttack() { return (m_dwLIES & (uint)Logic_Influence_Extned_states.LIES_DISABLEFIGHT) != 0; }
|
||||
|
||||
public bool CanTouchTarget(A3DVECTOR3 vHostPos, A3DVECTOR3 vTargetPos, float fTargetRad, int iReason, float fMaxCut = 1.0f)
|
||||
{
|
||||
float fDist = A3d_Magnitude(vTargetPos - vHostPos);
|
||||
switch (iReason)
|
||||
{
|
||||
case 1: // melee
|
||||
{
|
||||
float fRange;
|
||||
if (fMaxCut >= 0.0f)
|
||||
{
|
||||
float fCutDist = m_ExtProps.ak.AttackRange * 0.3f;
|
||||
if (fCutDist > fMaxCut)
|
||||
fCutDist = fMaxCut;
|
||||
|
||||
fRange = m_ExtProps.ak.AttackRange - fCutDist;
|
||||
}
|
||||
|
||||
else
|
||||
fRange = m_ExtProps.ak.AttackRange * 0.7f;
|
||||
|
||||
if (fDist - fTargetRad <= fRange)
|
||||
return true;
|
||||
|
||||
break;
|
||||
}
|
||||
//case 2: // cast magic
|
||||
//{
|
||||
// if (m_pPrepSkill)
|
||||
// {
|
||||
// float fRange = m_pPrepSkill->GetCastRange(m_ExtProps.ak.AttackRange, GetPrayDistancePlus());
|
||||
// if (fRange > 0.0f)
|
||||
// {
|
||||
// if (fDist - fTargetRad <= fRange)
|
||||
// return true;
|
||||
// }
|
||||
// else
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// break;
|
||||
//}
|
||||
case 3: // talk
|
||||
{
|
||||
if (fDist - fTargetRad <= 5.0f)
|
||||
return true;
|
||||
|
||||
break;
|
||||
}
|
||||
default: // no special reason
|
||||
{
|
||||
if (fDist < (fTargetRad + m_fTouchRad) * 3.0f)
|
||||
return true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CanTouchTarget(A3DVECTOR3 vTargetPos, float fTargetRad, int iReason, float fMaxCut = 1.0f)
|
||||
{
|
||||
A3DVECTOR3 vector = new A3DVECTOR3(gameObject.transform.position.x, gameObject.transform.position.y, gameObject.transform.position.z);
|
||||
return CanTouchTarget(vector, vTargetPos, fTargetRad, iReason, fMaxCut);
|
||||
}
|
||||
public bool IsRooting() {
|
||||
var mask = (uint)(Logic_Influence_Extned_states.LIES_ROOT
|
||||
| Logic_Influence_Extned_states.LIES_SLEEP
|
||||
| Logic_Influence_Extned_states.LIES_STUN);
|
||||
return (m_dwLIES & mask) != 0; }
|
||||
|
||||
bool IsInFortress() { return m_fortressEnter.role_in_war != 0; }
|
||||
|
||||
bool IsPVPOpen() { return m_pvp.bEnable; }
|
||||
// Get faction ID
|
||||
int GetFactionID(){ return m_idFaction; }
|
||||
|
||||
public bool IsJumping() { return m_iJumpCount > 0; }
|
||||
|
||||
public bool IsPlayingAction(int iAction)
|
||||
{
|
||||
if (iAction == (int)PLAYER_ACTION_TYPE.ACT_WALK && _playerStateMachine.State is PlayerMoveState)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (iAction == (int)PLAYER_ACTION_TYPE.ACT_STAND && _playerStateMachine.State is PlayerIdleState)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void ResetJump() { m_iJumpCount = 0; m_bJumpInWater = false; }
|
||||
// Get move speed
|
||||
public float GetFlySpeed() { return m_ExtProps.mv.flight_speed; }
|
||||
public float GetSwimSpeed() { return m_ExtProps.mv.swim_speed; }
|
||||
|
||||
//public float GetSwimSpeedSev()
|
||||
//{
|
||||
// float fSpeedSev = GetSwimSpeed();
|
||||
// while (true)
|
||||
// {
|
||||
// if (!IsUnderWater()) break;
|
||||
// //CECWorld* pWorld = g_pGame->GetGameRun()->GetWorld();
|
||||
// //if (!pWorld) break;
|
||||
|
||||
// const A3DVECTOR3 vPos = GetPos();
|
||||
// float fTerrainHeight = pWorld->GetTerrainHeight(vPos);
|
||||
// float fWaterHeight = pWorld->GetWaterHeight(vPos);
|
||||
// if (fWaterHeight <= fTerrainHeight) break;
|
||||
|
||||
// float fBorderLine = fWaterHeight - 2.0f;
|
||||
// if (vPos.y <= fBorderLine) break;
|
||||
|
||||
// // ·þÎñÆ÷¶Ë½«Ë®ÃæÒÔÏÂ2Ã×ÒÔÉÏ´¦ÀíΪ run_speed£¨ÓÐÎÊÌ⣩
|
||||
// // µ«Î´Ê¹ÓüÓËÙ¼¼ÄÜʱ swim_speed СÓÚ run_speed£¬
|
||||
// // ¿ÉÒÔÔÚË®ÃæÒÔÏÂ2Ã×ÒÔÉÏ»ñÈ¡³¬¹ý swim_speed µÄËÙ¶È£¬Òò´Ë£¬´Ë´¦È¡Á½Õß½ÏСֵΪºÏÀí×ö·¨
|
||||
// fSpeedSev = min(m_ExtProps.mv.run_speed, fSpeedSev);
|
||||
// break;
|
||||
// }
|
||||
// return fSpeedSev;
|
||||
//}
|
||||
}
|
||||
|
||||
public enum StateAnim
|
||||
@@ -572,3 +939,54 @@ public enum StateAnim
|
||||
Run = 3,
|
||||
Jump = 4
|
||||
}
|
||||
|
||||
// Mask of some special extend states which will influence host game logic.
|
||||
// Logic Influence Extned states
|
||||
[Flags]
|
||||
public enum Logic_Influence_Extned_states
|
||||
{
|
||||
LIES_SLEEP = 0x0001,
|
||||
LIES_STUN = 0x0002,
|
||||
LIES_ROOT = 0x0004,
|
||||
LIES_NOFGIHT = 0x0008,
|
||||
|
||||
LIES_DISABLEFIGHT = 0x000B,
|
||||
}
|
||||
|
||||
// ½øÈë»ùµØÐÅÏ¢
|
||||
public struct FACTION_FORTRESS_ENTER
|
||||
{
|
||||
public int faction_id;
|
||||
public int role_in_war; // 0 : ÖÐÁ¢»ò²»ÔÚ»ùµØ 1:¹¥·½ 2: ÊØ·½
|
||||
public int end_time;
|
||||
|
||||
public FACTION_FORTRESS_ENTER(int faction_id, int role_in_war, int end_time)
|
||||
{
|
||||
this.faction_id = faction_id;
|
||||
this.role_in_war = role_in_war;
|
||||
this.end_time = end_time;
|
||||
}
|
||||
}
|
||||
|
||||
// PVP infomation
|
||||
public struct PVPINFO
|
||||
{
|
||||
public bool bEnable; // PVP switch
|
||||
public uint dwCoolTime;
|
||||
public uint dwMaxCoolTime;
|
||||
public bool bFreePVP; // Free PVP flag, ignore bEnable flag
|
||||
public bool bInPVPCombat; // true, in PVP combat
|
||||
public int iDuelState; // Duel state
|
||||
public int idDuelOpp; // Duel opponent
|
||||
public int iDuelTimeCnt; // Duel time counter
|
||||
public int iDuelRlt; // Duel result. 0, no defined; 1-win; 2-lose; 3-draw
|
||||
};
|
||||
|
||||
// Current ground information
|
||||
public struct GNDINFO
|
||||
{
|
||||
public float fGndHei; // Ground height
|
||||
public float fWaterHei; // Water height
|
||||
public A3DVECTOR3 vGndNormal; // Terrain normal
|
||||
public bool bOnGround; // On ground flag
|
||||
};
|
||||
@@ -86,4 +86,45 @@ public static class EC_Utility
|
||||
|
||||
return $"{prefix}_{suffix}";
|
||||
}
|
||||
|
||||
// Build pvp mask
|
||||
public static byte glb_BuildPVPMask(bool bForceAttack)
|
||||
{
|
||||
byte byMask = 0;
|
||||
if (bForceAttack)
|
||||
byMask |= (byte)PVP_mask.GP_PVPMASK_FORCE;
|
||||
//else
|
||||
//{
|
||||
// CECConfigs* pConfigs = g_pGame->GetConfigs();
|
||||
|
||||
// if (pConfigs->GetGameSettings().bAtk_Player)
|
||||
// {
|
||||
// byMask |= GP_PVPMASK_FORCE;
|
||||
|
||||
// if (pConfigs->GetGameSettings().bAtk_NoMafia)
|
||||
// byMask |= GP_PVPMASK_NOMAFIA;
|
||||
|
||||
// if (pConfigs->GetGameSettings().bAtk_NoWhite)
|
||||
// byMask |= GP_PVPMASK_NOWHITE;
|
||||
|
||||
// if (pConfigs->GetGameSettings().bAtk_NoAlliance)
|
||||
// byMask |= GP_PVPMASK_NOALLIANCE;
|
||||
|
||||
// if (pConfigs->GetGameSettings().bAtk_NoForce)
|
||||
// byMask |= GP_PVPMASK_NOFORCE;
|
||||
// }
|
||||
//}
|
||||
|
||||
return byMask;
|
||||
}
|
||||
|
||||
public static T a_ClampFloor<T>(T x, T min) where T : IComparable<T>
|
||||
{
|
||||
return (x.CompareTo(min) < 0) ? min : x;
|
||||
}
|
||||
|
||||
public static T a_Min<T>(T x, T y) where T : IComparable<T>
|
||||
{
|
||||
return (y.CompareTo(x) < 0) ? y : x;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
using BrewMonster.Network;
|
||||
using CSNetwork;
|
||||
using CSNetwork.C2SCommand;
|
||||
using CSNetwork.GPDataType;
|
||||
using CSNetwork.Protocols;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using CSNetwork.Protocols;
|
||||
using CSNetwork;
|
||||
|
||||
public class CECHostMove
|
||||
{
|
||||
@@ -23,7 +24,12 @@ public class CECHostMove
|
||||
ulong m_dwLastTime;
|
||||
Vector3 m_vLastPos;
|
||||
float m_fAverSpeedH;
|
||||
|
||||
int m_iBlockedCnt; // Move blocked counter
|
||||
bool m_bSlideLock; // Locked when slide
|
||||
float m_fBlockTime; // Block time counter
|
||||
float m_fBlockMove; // Block move counter
|
||||
A3DVECTOR3 m_vBlockMove;
|
||||
bool m_bLocalMove; // true, Moving info isn't sent to server
|
||||
|
||||
public CECHostMove(CECHostPlayer pHost)
|
||||
{
|
||||
@@ -41,8 +47,8 @@ public class CECHostMove
|
||||
{
|
||||
var m = m_DelayedStop;
|
||||
|
||||
// a_GetTime() -> Environment.TickCount (ms)
|
||||
ulong dwCurrent = (ulong)Mathf.RoundToInt( Time.time * 1000);
|
||||
// a_GetTime() . Environment.TickCount (ms)
|
||||
ulong dwCurrent = (ulong)Mathf.RoundToInt(Time.time * 1000);
|
||||
|
||||
// iTime: thời gian tích lũy (ms) + delta từ timestamp đến hiện tại
|
||||
int iTime = (int)((m.fTime * 1000f)
|
||||
@@ -56,9 +62,9 @@ public class CECHostMove
|
||||
// make a potential check with tuojigua
|
||||
iMoveMode |= (int)GPMoveMode.GP_MOVE_DEAD;
|
||||
|
||||
UnityGameSession.Instance.c2s_SendCmdStopMove(
|
||||
m.vPos, fSpeed, iMoveMode, m.byDir, m_wMoveStamp++, iTime
|
||||
);
|
||||
UnityGameSession.Instance.c2s_SendCmdStopMove(
|
||||
m.vPos, fSpeed, iMoveMode, m.byDir, m_wMoveStamp++, iTime
|
||||
);
|
||||
|
||||
// Record this position
|
||||
m_vLastSevPos = m.vPos;
|
||||
@@ -72,6 +78,33 @@ public class CECHostMove
|
||||
m_vLastPos = m_pHost.transform.position;
|
||||
m_dwLastTime = dwDeltaTime;
|
||||
}
|
||||
|
||||
public void SendStopMoveCmd()
|
||||
{
|
||||
int iMoveMode = (int)GPMoveMode.GP_MOVE_RUN;
|
||||
float fSpeed = 0f;
|
||||
switch (m_pHost.GetMoveEnv())
|
||||
{
|
||||
case EC_Player.Move_environment.MOVEENV_AIR:
|
||||
|
||||
iMoveMode |= (int)GPMoveMode.GP_MOVE_AIR;
|
||||
fSpeed = m_pHost.GetFlySpeed();
|
||||
break;
|
||||
|
||||
//case EC_Player.Move_environment.MOVEENV_WATER:
|
||||
|
||||
// iMoveMode |= (int)GPMoveMode.GP_MOVE_WATER;
|
||||
// fSpeed = m_pHost.GetSwimSpeedSev();
|
||||
// break;
|
||||
|
||||
default:
|
||||
|
||||
fSpeed = m_pHost.GetGroundSpeed();
|
||||
break;
|
||||
}
|
||||
SendStopMoveCmd(EC_Utility.ToVector3(m_pHost.GetPos()), fSpeed, iMoveMode);
|
||||
}
|
||||
|
||||
public void SendStopMoveCmd(in Vector3 vPos, float fSpeed, int iMoveMode)
|
||||
{
|
||||
Debug.LogWarning("HoangDev : SendStopMoveCmd");
|
||||
@@ -86,7 +119,7 @@ public class CECHostMove
|
||||
|
||||
UnityGameSession.Instance.c2s_SendCmdStopMove(vPos, fSpeed, iMoveMode, byDir, m_wMoveStamp++, iTime);
|
||||
|
||||
m_vLastSevPos = vPos;
|
||||
m_vLastSevPos = vPos;
|
||||
Reset();
|
||||
}
|
||||
else
|
||||
@@ -114,14 +147,31 @@ public class CECHostMove
|
||||
float fSpeed = vMoveDir.magnitude;
|
||||
SendMoveCmd(vCurPos, fSpeed, iMoveMode, bForceSend);
|
||||
}
|
||||
|
||||
public void SendMoveCmd(A3DVECTOR3 vCurPos, int iDestType, A3DVECTOR3 vDest, A3DVECTOR3 vVel, int iMoveMode, bool bForceSend = false)
|
||||
{
|
||||
|
||||
A3DVECTOR3 vMoveDir = vVel;
|
||||
float fSpeed = vMoveDir.Normalize();
|
||||
SendMoveCmd(vCurPos, iDestType, vDest, vMoveDir, fSpeed, iMoveMode, bForceSend);
|
||||
}
|
||||
|
||||
void SendMoveCmd(A3DVECTOR3 vCurPos, int iDestType, A3DVECTOR3 vDest,
|
||||
A3DVECTOR3 vMoveDir, float fSpeed, int iMoveMode, bool bForceSend)
|
||||
|
||||
{
|
||||
Vector3 pos = new Vector3(vCurPos.x, vCurPos.y, vCurPos.z);
|
||||
SendMoveCmd(pos, fSpeed, iMoveMode, bForceSend);
|
||||
}
|
||||
|
||||
void SendMoveCmd(in Vector3 vCurPos,
|
||||
float fSpeed, int iMoveMode, bool bForceSend)
|
||||
float fSpeed, int iMoveMode, bool bForceSend)
|
||||
{
|
||||
|
||||
if (m_bStop)
|
||||
{
|
||||
// m_CmdTimeCnt.Reset();
|
||||
cmdmovedelayCounter = (ulong)( m_fMoveTime * 1000);
|
||||
cmdmovedelayCounter = (ulong)(m_fMoveTime * 1000);
|
||||
m_bStop = false;
|
||||
}
|
||||
if (!bForceSend && cmdmovedelayCounter < 500)
|
||||
@@ -150,7 +200,7 @@ public class CECHostMove
|
||||
|
||||
m_vLastSevPos = vCurPos;
|
||||
}
|
||||
|
||||
|
||||
float l_CalcAverageSpeed(in Vector3 p1, in Vector3 p2, float fTime, float fDefSpeed)
|
||||
{
|
||||
if (Mathf.Approximately(fTime, 0f))
|
||||
@@ -182,14 +232,107 @@ public class CECHostMove
|
||||
|
||||
struct STOPMOVE
|
||||
{
|
||||
public bool bValid; // Valid flag
|
||||
public Vector3 vPos;
|
||||
public float fSpeed;
|
||||
public int iMoveMode;
|
||||
public byte byDir;
|
||||
public ulong dwTimeStamp;
|
||||
public float fTime;
|
||||
public bool bValid; // Valid flag
|
||||
public Vector3 vPos;
|
||||
public float fSpeed;
|
||||
public int iMoveMode;
|
||||
public byte byDir;
|
||||
public ulong dwTimeStamp;
|
||||
public float fTime;
|
||||
};
|
||||
|
||||
// Check whether host meet a slope
|
||||
// vMoveDirH: normalized horizontal moving direction
|
||||
// fMaxSpeed (out): maximum vertical speed
|
||||
public bool MeetSlope(A3DVECTOR3 vMoveDirH, float fMaxSpeedV)
|
||||
{
|
||||
A3DVECTOR3 vTangent = m_pHost.m_GndInfo.vGndNormal;
|
||||
|
||||
float d = vTangent.MagnitudeH();
|
||||
float tan = d / (float)Math.Abs(vTangent.y);
|
||||
float max = m_pHost.GetGroundSpeed() * tan * 0.96f;
|
||||
// Prevent max is too small, tan60 = 1.732
|
||||
EC_Utility.a_ClampFloor(max, m_pHost.GetGroundSpeed() * 1.732f);
|
||||
fMaxSpeedV = EC_Utility.a_Min(max, 19.5f);
|
||||
|
||||
// fMaxSpeedV = 100.0f;
|
||||
|
||||
vTangent.y = 0.0f;
|
||||
vTangent.Normalize();
|
||||
|
||||
if (A3DVECTOR3.DotProduct(vMoveDirH, vTangent) <= -0.85f)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public A3DVECTOR3 GroundMove(A3DVECTOR3 vDirH, float fSpeedH, float fTime, float fSpeedV = 0f, float fGravity = 9.8f)
|
||||
{
|
||||
A3DVECTOR3 vRealDirH = vDirH;
|
||||
|
||||
if (Math.Abs(vRealDirH.y) > 0.0001)
|
||||
{
|
||||
vRealDirH.y = 0.0f;
|
||||
vRealDirH.Normalize();
|
||||
}
|
||||
|
||||
// OnGroundMove only accept positive speed value
|
||||
if (fSpeedH < 0.0f)
|
||||
{
|
||||
vRealDirH = -vDirH;
|
||||
fSpeedH = -fSpeedH;
|
||||
}
|
||||
|
||||
//int idInst = g_pGame.GetGameRun().GetWorld().GetInstanceID();
|
||||
//CECInstance pInstance = g_pGame.GetGameRun().GetInstance(idInst);
|
||||
//if (pInstance.GetLimitJump())
|
||||
fGravity *= 4.0f;
|
||||
|
||||
CDR_INFO cdr = m_pHost.m_CDRInfo;
|
||||
var pos = m_pHost.m_aabbServer.Center;
|
||||
cdr.vCenter = new Vector3(pos.x, pos.y, pos.z);
|
||||
cdr.vXOZVelDir = new Vector3(vRealDirH.x, vRealDirH.y, vRealDirH.z);
|
||||
cdr.fSpeed = fSpeedH;
|
||||
cdr.t = fTime;
|
||||
cdr.fGravityAccel = fGravity;
|
||||
cdr.fYVel += fSpeedV;
|
||||
|
||||
EC_CDR.OnGroundMove(ref cdr);
|
||||
|
||||
//if (g_pGame.GetGameRun().GetWorld().GetAssureMove())
|
||||
// g_pGame.GetGameRun().GetWorld().GetAssureMove().AssureMove(m_pHost.m_aabbServer.Center, cdr.vCenter);
|
||||
|
||||
if (cdr.vTPNormal != Vector3.zero)
|
||||
m_pHost.SetGroundNormal(new A3DVECTOR3(cdr.vTPNormal.x, cdr.vTPNormal.y, cdr.vTPNormal.z));
|
||||
else
|
||||
m_pHost.SetGroundNormal(GPDataTypeHelper.g_vAxisY);
|
||||
|
||||
A3DVECTOR3 vNewPos = new A3DVECTOR3(cdr.vCenter.x, cdr.vCenter.y, cdr.vCenter.z) - GPDataTypeHelper.g_vAxisY * m_pHost.m_aabbServer.Extents.y;
|
||||
|
||||
m_iBlockedCnt = 0;
|
||||
m_fBlockMove += (vNewPos - m_pHost.GetPos()).Magnitude();
|
||||
m_vBlockMove += vNewPos - m_pHost.GetPos();
|
||||
if ((m_fBlockTime += fTime) >= 1.0f)
|
||||
{
|
||||
if (m_fBlockMove < GPDataTypeHelper.MIN_MOVELEN_ON_GROUND || m_vBlockMove.Magnitude() < GPDataTypeHelper.MIN_MOVELEN_FOR_DETECT_VIBRATION)
|
||||
{
|
||||
m_iBlockedCnt = 5;
|
||||
}
|
||||
|
||||
m_fBlockTime = 0.0f;
|
||||
m_fBlockMove = 0.0f;
|
||||
m_vBlockMove.Clear();
|
||||
}
|
||||
|
||||
m_fMoveTime += fTime;
|
||||
|
||||
return vNewPos;
|
||||
}
|
||||
|
||||
public int MoveBlocked() { return m_iBlockedCnt; }
|
||||
public void SetSlideLock(bool bLock) { m_bSlideLock = bLock; }
|
||||
// Is stoping ?
|
||||
public bool IsStop() { return m_bStop; }
|
||||
}
|
||||
public struct CDR_INFO
|
||||
{
|
||||
|
||||
@@ -1,18 +1,30 @@
|
||||
using BrewMonster;
|
||||
using CSNetwork.GPDataType;
|
||||
using ModelRenderer.Scripts.GameData;
|
||||
using PerfectWorld.Scripts.Player;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public abstract class EC_Player : MonoBehaviour
|
||||
public abstract class EC_Player : CECObject
|
||||
{
|
||||
private static PLAYER_ACTION[] _default_actions;
|
||||
private static PLAYER_ACTION[] _turning_actions;
|
||||
PLAYER_ACTION[] m_PlayerActions;
|
||||
[SerializeField] protected INFO m_PlayerInfo;
|
||||
[SerializeField] internal INFO m_PlayerInfo;
|
||||
protected GameObject m_pPlayerModel;
|
||||
protected float rotationSpeed = 5;
|
||||
|
||||
internal int m_iMoveMode; // Player's move mode
|
||||
internal int m_idSelTarget; // Ñ¡ÖÐÄ¿±êµÄID
|
||||
uint m_dwStates; // Player's basic states
|
||||
protected ROLEEXTPROP m_ExtProps; // Extend properties
|
||||
protected float m_fTouchRad = 0.3f; // Touch radius
|
||||
protected int m_iBattleCamp = Player_camp_in_battle.GP_BATTLE_CAMP_NONE; // Battle this player belongs to
|
||||
byte m_factionPVPMask; // pvp mask
|
||||
protected ROLEBASICPROP m_BasicProps;
|
||||
public int m_iMoveEnv = Move_environment.MOVEENV_GROUND; // Move environment
|
||||
public bool m_bWalkRun;
|
||||
public A3DAABB m_aabbServer; // Óë·þÎñÆ÷±£³ÖÒ»ÖµÄaabb£¬ ²»ÊÜËõ·ÅÓ°Ïì
|
||||
protected void Awake()
|
||||
{
|
||||
m_PlayerActions = _default_actions;
|
||||
@@ -30,7 +42,10 @@ public abstract class EC_Player : MonoBehaviour
|
||||
{
|
||||
BuildActionList();
|
||||
}
|
||||
public bool IsValidAction(int iIndex) { return (iIndex >= 0 && iIndex < (int)PLAYER_ACTION_TYPE.ACT_MAX) ? true : false; }
|
||||
|
||||
public bool IsDead(){ return (m_dwStates & PlayerNPCState.GP_STATE_CORPSE) != 0; }
|
||||
|
||||
public bool IsValidAction(int iIndex) { return (iIndex >= 0 && iIndex < (int)PLAYER_ACTION_TYPE.ACT_MAX) ? true : false; }
|
||||
private static void BuildActionList()
|
||||
{
|
||||
if (_default_actions == null)
|
||||
@@ -270,6 +285,102 @@ public abstract class EC_Player : MonoBehaviour
|
||||
ACT_CASTSKILL // Chỉ là placeholder cho skill actions
|
||||
}
|
||||
|
||||
public float GetTouchRadius(){ return m_fTouchRad; }
|
||||
// Is player in battle
|
||||
public bool IsInBattle() { return m_iBattleCamp != Player_camp_in_battle.GP_BATTLE_CAMP_NONE; }
|
||||
|
||||
// Check whether specified npc in a same battle camp
|
||||
public bool InSameBattleCamp(CECNPC pNPC)
|
||||
{
|
||||
if (!pNPC || m_iBattleCamp == Player_camp_in_battle.GP_BATTLE_CAMP_NONE ||
|
||||
(m_iBattleCamp == Player_camp_in_battle.GP_BATTLE_CAMP_INVADER && !pNPC.IsInBattleInvaderCamp()) ||
|
||||
(m_iBattleCamp == Player_camp_in_battle.GP_BATTLE_CAMP_DEFENDER && !pNPC.IsInBattleDefenderCamp()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
public bool IsInFactionPVP() => (m_factionPVPMask & 0x01) != 0;
|
||||
public bool CanAttackFactionPVPMineCar() => (m_factionPVPMask & 0x02) != 0;
|
||||
public bool CanAttackFactionPVPMineBase() => (m_factionPVPMask & 0x04) != 0;
|
||||
|
||||
// Get basic properties
|
||||
public ROLEBASICPROP GetBasicProps() { return m_BasicProps; }
|
||||
|
||||
public int GetMoveStandAction(bool bMove, bool bFight = false)
|
||||
{
|
||||
int iMoveEnv = m_iMoveEnv;
|
||||
//if (m_AttachMode != enumAttachNone)
|
||||
//{
|
||||
// bFight = false;
|
||||
// if (m_bHangerOn)
|
||||
// iMoveEnv = MOVEENV_GROUND;
|
||||
//}
|
||||
|
||||
int iAction = (int)PLAYER_ACTION_TYPE.ACT_STAND;
|
||||
|
||||
if (bMove)
|
||||
{
|
||||
// Play appropriate actions
|
||||
if (iMoveEnv == (int)MoveEnvironment.MOVEENV_GROUND)
|
||||
{
|
||||
if (m_bWalkRun)
|
||||
iAction = (int)PLAYER_ACTION_TYPE.ACT_RUN;
|
||||
else
|
||||
iAction = (int)PLAYER_ACTION_TYPE.ACT_WALK;
|
||||
}
|
||||
//else if (iMoveEnv == MOVEENV_AIR)
|
||||
//{
|
||||
// //if (/*UsingWing()*/ m_wingType == WINGTYPE_WING)
|
||||
// // iAction = ACT_FLY;
|
||||
// //else
|
||||
// // iAction = ACT_FLY_SWORD;
|
||||
//}
|
||||
//else if (iMoveEnv == MOVEENV_WATER)
|
||||
//{
|
||||
// //if (CanCombineWithMoveForSkill())
|
||||
// //{
|
||||
// // iAction = ACT_SWIM_FOR_MOVESKILL;
|
||||
// //}
|
||||
// //else
|
||||
// //{
|
||||
// // iAction = ACT_SWIM;
|
||||
// //}
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Play appropriate actions
|
||||
if (iMoveEnv == (int)MoveEnvironment.MOVEENV_GROUND)
|
||||
{
|
||||
if (bFight)
|
||||
iAction = (int)PLAYER_ACTION_TYPE.ACT_FIGHTSTAND;
|
||||
else
|
||||
iAction = (int)PLAYER_ACTION_TYPE.ACT_STAND;
|
||||
}
|
||||
//else if (iMoveEnv == MOVEENV_AIR)
|
||||
//{
|
||||
// if (/*UsingWing()*/ m_wingType == WINGTYPE_WING)
|
||||
// iAction = ACT_HANGINAIR;
|
||||
// else
|
||||
// iAction = ACT_HANGINAIR_SWORD;
|
||||
//}
|
||||
//else if (iMoveEnv == MOVEENV_WATER)
|
||||
// iAction = ACT_HANGINWATER;
|
||||
}
|
||||
|
||||
return iAction;
|
||||
}
|
||||
|
||||
public float GetGroundSpeed()
|
||||
{
|
||||
// return m_bWalkRun ? g_pGame->GetConfigs()->GetHostRunSpeed() : m_ExtProps.mv.walk_speed;
|
||||
return m_bWalkRun ? m_ExtProps.mv.run_speed : m_ExtProps.mv.walk_speed;
|
||||
}
|
||||
|
||||
// Get move environment
|
||||
public int GetMoveEnv(){ return m_iMoveEnv; }
|
||||
// Get character ID
|
||||
public int GetCharacterID(){ return m_PlayerInfo.cid; }
|
||||
}
|
||||
public struct PlayActionEvent
|
||||
{
|
||||
@@ -291,4 +402,22 @@ public struct INFO
|
||||
this.crc_c = crc_c;
|
||||
this.crc_e = crc_;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static class Duel_state // Duel state
|
||||
{
|
||||
public const int DUEL_ST_NONE = 0,
|
||||
DUEL_ST_PREPARE = 1,
|
||||
DUEL_ST_INDUEL = 2,
|
||||
DUEL_ST_STOPPING = 3;
|
||||
}
|
||||
|
||||
//// Move mode
|
||||
//public static class Move_Mode
|
||||
//{
|
||||
// public const int MOVE_STAND = 0,
|
||||
// MOVE_MOVE = 1, // Normal move, walk, run, swim or fly
|
||||
// MOVE_JUMP = 2,
|
||||
// MOVE_FREEFALL = 3,
|
||||
// MOVE_SLIDE = 4;
|
||||
//}
|
||||
@@ -5,6 +5,8 @@ public class PlayerStateMachine
|
||||
PlayerState _state;
|
||||
CECHostPlayer _characterCtrl;
|
||||
|
||||
public PlayerState State { get => _state; }
|
||||
|
||||
public void InitState(PlayerState state)
|
||||
{
|
||||
if (_state != null)
|
||||
|
||||
Reference in New Issue
Block a user