Merge remote-tracking branch 'origin/develop' into feature/movement

# Conflicts:
#	Assets/PerfectWorld/Scripts/Common/CECObject.cs
#	Assets/PerfectWorld/Scripts/NPC/CECNPC.cs
#	Assets/Scripts/Move/CECHostMove.cs
This commit is contained in:
VDH
2025-10-09 11:31:55 +07:00
46 changed files with 4505 additions and 232 deletions
-8
View File
@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 95c82a23114631b428b9fff51c373a39
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
-8
View File
@@ -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.
+39 -45
View File
@@ -1,49 +1,43 @@
using CSNetwork.GPDataType;
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,
}
protected void TurnFaceTo(int idTarget, float dwTime)
{
// Face to target
A3DVECTOR3 vTarget;
}
}
// 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)
+47 -7
View File
@@ -23,7 +23,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;
@@ -47,11 +47,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)
{
@@ -76,9 +77,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);
@@ -853,8 +854,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}");
@@ -906,6 +909,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;
@@ -919,6 +924,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);
}
}
}
@@ -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;
}
}
}
@@ -180,6 +180,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
View File
@@ -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
};
+41
View File
@@ -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;
}
}
+162 -17
View File
@@ -1,9 +1,12 @@
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;
@@ -24,7 +27,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)
{
@@ -42,8 +50,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)
@@ -57,9 +65,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;
@@ -73,6 +81,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");
@@ -87,7 +122,7 @@ public class CECHostMove
UnityGameSession.Instance.c2s_SendCmdStopMove(vPos, fSpeed, iMoveMode, byDir, m_wMoveStamp++, iTime);
m_vLastSevPos = vPos;
m_vLastSevPos = vPos;
Reset();
}
else
@@ -115,14 +150,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)
@@ -151,7 +203,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))
@@ -183,14 +235,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
{
+134 -5
View File
@@ -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;
//}
+2
View File
@@ -5,6 +5,8 @@ public class PlayerStateMachine
PlayerState _state;
CECHostPlayer _characterCtrl;
public PlayerState State { get => _state; }
public void InitState(PlayerState state)
{
if (_state != null)