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

This commit is contained in:
VDH
2025-10-22 09:26:38 +07:00
61 changed files with 3981 additions and 1377 deletions
+109
View File
@@ -164,6 +164,114 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
_nextSceneName: LoginScene
--- !u!1 &428240946
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 428240950}
- component: {fileID: 428240949}
- component: {fileID: 428240948}
- component: {fileID: 428240947}
m_Layer: 0
m_Name: Cube
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!65 &428240947
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 428240946}
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_IsTrigger: 0
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 3
m_Size: {x: 1, y: 1, z: 1}
m_Center: {x: 0, y: 0, z: 0}
--- !u!23 &428240948
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 428240946}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!33 &428240949
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 428240946}
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!4 &428240950
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 428240946}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &506356661
PrefabInstance:
m_ObjectHideFlags: 0
@@ -590,3 +698,4 @@ SceneRoots:
- {fileID: 591506937}
- {fileID: 105404091}
- {fileID: 506356661}
- {fileID: 428240950}
@@ -1,4 +1,5 @@
using BrewMonster;
using BrewMonster.Scripts.World;
using CSNetwork.GPDataType;
using System;
using UnityEngine;
@@ -1,5 +1,5 @@
using ModelRenderer.Scripts.GameData;
using PerfectWorld.Scripts.Task;
using BrewMonster.Scripts.Task;
using UnityEngine;
namespace BrewMonster.Network
{
@@ -0,0 +1,545 @@
using BrewMonster.Scripts.Player;
using CSNetwork.GPDataType;
using NUnit.Framework;
using PerfectWorld.Scripts.Player;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using ARectF = BrewMonster.Scripts.ARect<float>;
using ARectI = BrewMonster.Scripts.ARect<int>;
using BlockArray = System.Collections.Generic.List<BrewMonster.Scripts.World.A3DTerrain2Block>;
using WORD = System.UInt16;
namespace BrewMonster.Scripts.World
{
public class A3DTerrain2Block
{
// Trerrain2 vertex format when use lightmap
public struct A3DTRN2VERTEX1
{
public float vPosX; // PositionX
public float vPosY; // PositionY
public float vPosZ; // PositionZ
public float vNormalX; // NormalX
public float vNormalY; // NormalY
public float vNormalZ; // NormalZ
public float u1, v1; // Texture coordinates project on xz
public float u2, v2; // Texture coordinates project on xy
public float u3, v3; // Texture coordinates project on yz
public float u4, v4; // Texture coordinate of layer mask
};
// Terrain2 vertex format when use vertex-light (not lightmap)
public struct A3DTRN2VERTEX2
{
public float vPosX; // Position X
public float vPosY; // Position Y
public float vPosZ; // Position Z
public uint dwDiffuse; // Diffuse color
public uint dwSpecular; // Specular color
public float u1, v1; // Texture coordinates project on xz
public float u2, v2; // Texture coordinates project on xy
public float u3, v3; // Texture coordinates project on yz
public float u4, v4; // Texture coordinate of layer mask
};
public bool m_bDataLoaded = false; // Data loaded flag
public bool IsDataLoaded() { return m_bDataLoaded; }
public uint m_dwBlockFlags; // Block flags
public A3DAABB m_aabbBlock; // Block postion and size in whole world
public A3DTRN2VERTEX1[] m_aVertices1; // Vertex buffer, ps version
public A3DTRN2VERTEX2[] m_aVertices2; // Vertex buffer, non-ps version
public A3DTerrain2 m_pTerrain; // Terrain object
public int m_iBlockGrid; // Each block has m_iBlockGrid * m_iBlockGrid terrain grids
// Get block's position and size in whole world
public A3DAABB GetBlockAABB() { return m_aabbBlock; }
// Get flag for this whole block unable for GetPosHeight
public bool IsNoPosHeight()
{
return (m_dwBlockFlags & Block_flags_masks.T2BKFLAG_NOPOSHEIGHT) != 0;
}
// Get vertex
public A3DVECTOR3 GetVertexPos(int n)
{
if (m_aVertices1 != null && m_aVertices1.Length > n)
return new A3DVECTOR3(m_aVertices1[n].vPosX, m_aVertices1[n].vPosY, m_aVertices1[n].vPosZ);
else
{
//ASSERT(m_aVertices2);
return new A3DVECTOR3(m_aVertices2[n].vPosX, m_aVertices2[n].vPosY, m_aVertices2[n].vPosZ);
}
}
/* Copy block vertices to destination buffer. This function works like BitBlt.
Copy vertex positions in a rectangle grid area to destination buffer, every
vertex is like a pixel in BitBlt;
pDestBuf: destination vertex buffer
iWid, iHei: vertex rectangle area's size
iDestPitch: destination vertex buffer pitch in A3DVECTOR3
sx, sy: grid rectangle area's left-top corner in block
*/
public bool CopyVertexPos(ref A3DVECTOR3[] pDestBuf, int iWid, int iHei,
int iDestPitch, int sx, int sy)
{
WORD[] aIndexMaps = m_pTerrain.GetLODManager().GetIndexMaps();
int pDestLine = 0;
int iSrcLine = sy * (m_iBlockGrid + 1) + sx;
if (m_pTerrain.UseLightmapTech())
{
//ASSERT(m_aVertices1);
for (int i = 0; i < iHei; i++)
{
int destIndex = pDestLine;
int iSrc = iSrcLine;
pDestLine += iDestPitch;
iSrcLine += m_iBlockGrid + 1;
for (int j = 0; j < iWid; j++, destIndex++, iSrc++)
{
// Note: here we map index
A3DTRN2VERTEX1 pSrc = m_aVertices1[aIndexMaps[iSrc]];
pDestBuf[destIndex].x = pSrc.vPosX;
pDestBuf[destIndex].y = pSrc.vPosY;
pDestBuf[destIndex].z = pSrc.vPosZ;
}
}
}
else
{
for (int i = 0; i < iHei; i++)
{
int pDest = pDestLine;
int iSrc = iSrcLine;
pDestLine += iDestPitch;
iSrcLine += m_iBlockGrid + 1;
for (int j = 0; j < iWid; j++, pDest++, iSrc++)
{
var pSrc = m_aVertices2[aIndexMaps[iSrc]];
pDestBuf[pDest].x = pSrc.vPosX;
pDestBuf[pDest].y = pSrc.vPosY;
pDestBuf[pDest].z = pSrc.vPosZ;
}
}
}
return true;
}
/* Copy grid faces to destination buffer. This function works like BitBlt.
Copy face in a rectangle grid area to destination buffer, every face is
like a pixel in BitBlt;
pDestVert: destination vertex buffer
pDestIdx: destination index buffer
iWid, iHei: grid rectangle area's size
iDstVertPitch: destination vertex buffer pitch in A3DVECTOR3
iBaseVert: Index of left-top corner vertex in vertex buffer
sx, sy: grid rectangle area's left-top corner in block
*/
public bool CopyFaces(ref A3DVECTOR3[] pDestVert, ref WORD[] pDestIdx, int iWid, int iHei,
int iDstVertPitch, int iBaseVert, int sx, int sy)
{
// Copy vertices at first. Notice the difference of iWid and iHei in this
// function and in CopyVertexPos()
CopyVertexPos(ref pDestVert, iWid + 1, iHei + 1, iDstVertPitch, sx, sy);
// Build indices
int pIndices = 0;
for (int i = 0; i < iHei; i++)
{
WORD v0 = (WORD)iBaseVert;
iBaseVert += iDstVertPitch;
for (int j = 0; j < iWid; j++, pIndices += 6, v0++)
{
// v3 v0----v1
// | \ \ |
// | \ \ |
// | \ \ |
// | \ \ |
// v5---v4 v2
pDestIdx[pIndices] = v0;
pDestIdx[pIndices + 1] = (WORD)(v0 + 1);
pDestIdx[pIndices + 2] = (WORD)(v0 + iDstVertPitch + 1);
pDestIdx[pIndices + 3] = v0;
pDestIdx[pIndices + 4] = (WORD)(v0 + iDstVertPitch + 1);
pDestIdx[pIndices + 5] = (WORD)(v0 + iDstVertPitch);
}
}
// If this area contain block's right-top corner grid or left-bottom
// corner grid, then we have to adjust index so that they are in
// rendering order
if (sx == 0 && sy + iHei == m_iBlockGrid)
{
// Contain left-bottom corner grid
// v0----v1
// | / |
// | / |
// | / |
// | / |
// v2----v3
int offer = (iHei - 1) * iWid * 6;
WORD v0 = pDestIdx[offer];
WORD v1 = pDestIdx[offer + 1];
WORD v2 = pDestIdx[offer + 5];
WORD v3 = pDestIdx[offer + 2];
pDestIdx[offer] = v0;
pDestIdx[offer + 1] = v1;
pDestIdx[offer + 2] = v2;
pDestIdx[offer + 3] = v1;
pDestIdx[offer + 4] = v3;
pDestIdx[offer + 5] = v2;
}
if (sx + iWid == m_iBlockGrid && sy == 0)
{
// Contain right-top corner grid
// v0----v1
// | / |
// | / |
// | / |
// | / |
// v2----v3
int offer = (iWid - 1) * 6;
WORD v0 = pDestIdx[offer];
WORD v1 = pDestIdx[offer + 1];
WORD v2 = pDestIdx[offer + 5];
WORD v3 = pDestIdx[offer + 2];
pDestIdx[offer + 0] = v0;
pDestIdx[offer + 1] = v1;
pDestIdx[offer + 2] = v2;
pDestIdx[offer + 3] = v1;
pDestIdx[offer + 4] = v3;
pDestIdx[offer + 5] = v2;
}
return true;
}
}
public class A3DTerrain2
{
public ACTBLOCKS m_pCurActBlocks; // Currently active block array
public ARectF m_rcTerrain; // Whole terrain area in logic unit (metres)
public float m_fBlockSize = 0; // Block size (on x and z axis) in logic unit (metres)
public int m_iBlockGrid = 0; // Each block has m_iBlockGrid * m_iBlockGrid terrain grids
public float m_fGridSize; // Terrain grid size (on x and z axis) in logic unit (metres)
public A3DTerrain2LOD m_pLODMan; // LOD manager
public int m_iNumActBlockRow; // Row and column number of active blocks
public int m_iNumAllBlockRow = 0; // Row number of all blocks
public int m_iNumAllBlockCol = 0; // Column number of all blocks
public bool m_bVertexLight = false; // true, force to use vertex light rather than lightmap
public List<MeshFilter> m_lstMesh;
// Check lightmap or vertex-light is used
public bool UseLightmapTech() { return !m_bVertexLight; }
public A3DTerrain2LOD GetLODManager() { return m_pLODMan; }
// Get grid faces of specified area
public bool GetFacesOfArea(A3DVECTOR3 vCenter, int iGridWid, int iGridLen, ref A3DVECTOR3[] pVertBuf, ref WORD[] pIdxBuf)
{
//if (m_pCurActBlocks.rcArea.IsEmpty())
// return false;
if(m_lstMesh == null || m_lstMesh.Count == 0)
{
return false;
}
float halfW = (iGridWid * m_fGridSize) / 2f;
float halfL = (iGridLen * m_fGridSize) / 2f;
Bounds area = new Bounds(EC_Utility.ToVector3(vCenter), new Vector3(halfW * 2, 1000f, halfL * 2));
float fInvGridSize = 1.0f / m_fGridSize;
ARectI rcGrid = new ARectI();
rcGrid.left = (int)((vCenter.x - m_rcTerrain.left) * fInvGridSize) - (iGridWid >> 1);
rcGrid.top = (int)((m_rcTerrain.top - vCenter.z) * fInvGridSize) - (iGridLen >> 1);
rcGrid.right = rcGrid.left + iGridWid;
rcGrid.bottom = rcGrid.top + iGridLen;
return GetFacesOfArea(rcGrid, ref pVertBuf, ref pIdxBuf);
}
public bool GetFacesOfArea(ARectI rcGridArea, ref A3DVECTOR3[] pVertBuf, ref WORD[] pIdxBuf)
{
if (m_pCurActBlocks.rcArea.IsEmpty())
return false;
float fInvGridSize = 1.0f / m_fGridSize;
ARectI rcGrid = rcGridArea;
int iMaxGrid = m_iNumAllBlockCol * m_iBlockGrid;
AAssist.a_Clamp(ref rcGrid.left, 0, iMaxGrid);
AAssist.a_Clamp(ref rcGrid.right, 0, iMaxGrid);
iMaxGrid = m_iNumAllBlockRow * m_iBlockGrid;
AAssist.a_Clamp(ref rcGrid.top, 0, iMaxGrid);
AAssist.a_Clamp(ref rcGrid.bottom, 0, iMaxGrid);
if (rcGrid.IsEmpty())
return false;
ARectI rcBlock = new ARectI();
rcBlock.left = rcGrid.left / m_iBlockGrid;
rcBlock.top = rcGrid.top / m_iBlockGrid;
rcBlock.right = (rcGrid.right - 1) / m_iBlockGrid;
rcBlock.bottom = (rcGrid.bottom - 1) / m_iBlockGrid;
int r, c;
// Ensure all blocks in active area and have been loaded
for (r = rcBlock.top; r <= rcBlock.bottom; r++)
{
for (c = rcBlock.left; c <= rcBlock.right; c++)
{
if (!m_pCurActBlocks.rcArea.PtInRect(c, r) ||
m_pCurActBlocks.GetBlock(r, c, false) == null)
return false;
}
}
int pDestIdx = 0;
A3DVECTOR3[] pVertDest = new A3DVECTOR3[0];
WORD[] pIdxTemp = new WORD[0];
for (r = rcBlock.top; r <= rcBlock.bottom; r++)
{
ARectI rect = new ARectI();
rect.left = rcBlock.left * m_iBlockGrid;
rect.top = r * m_iBlockGrid;
rect.right = rect.left + m_iBlockGrid;
rect.bottom = rect.top + m_iBlockGrid;
for (c = rcBlock.left; c <= rcBlock.right; c++)
{
A3DTerrain2Block pBlock = m_pCurActBlocks.GetBlock(r, c, false);
//ASSERT(pBlock);
ARectI rc = rcGrid & rect;
//ASSERT(!rc.IsEmpty());
int dx = rc.left - rcGrid.left;
int dy = rc.top - rcGrid.top;
int iBaseVert = dy * (rcGrid.Width() + 1) + dx;
pVertDest = pVertBuf.Skip(iBaseVert).ToArray();
pIdxTemp = pIdxBuf.Skip(pDestIdx).ToArray();
int sx = rc.left - rect.left;
int sy = rc.top - rect.top;
pBlock.CopyFaces(ref pVertDest, ref pIdxTemp, rc.Width(), rc.Height(), rcGrid.Width() + 1, iBaseVert, sx, sy);
for (int i = iBaseVert; i < pVertBuf.Length; i++)
{
pVertBuf[i] = pVertDest[i - iBaseVert];
}
for (int i = 0; i < pIdxBuf.Length; i++)
{
pIdxBuf[i] = pIdxTemp[i - pDestIdx];
}
pDestIdx += rc.Width() * rc.Height() * 6;
rect.left += m_iBlockGrid;
rect.right += m_iBlockGrid;
}
}
return true;
}
// Get height and normal of specified position
public float GetPosHeight(A3DVECTOR3 vPos, ref A3DVECTOR3 pvNormal)
{
// Give a default value to normal
if (pvNormal != null)
pvNormal.Clear();
if (m_pCurActBlocks.rcArea.IsEmpty())
return 0.0f;
// Currenly active area AABB
ARectF rcActive = new ARectF();
rcActive.left = m_rcTerrain.left + m_pCurActBlocks.rcArea.left * m_fBlockSize;
rcActive.top = m_rcTerrain.top - m_pCurActBlocks.rcArea.top * m_fBlockSize;
rcActive.right = rcActive.left + m_pCurActBlocks.rcArea.Width() * m_fBlockSize;
rcActive.bottom = rcActive.top - m_pCurActBlocks.rcArea.Height() * m_fBlockSize;
if (vPos.x < rcActive.left || vPos.x > rcActive.right ||
vPos.z > rcActive.top || vPos.z < rcActive.bottom)
return 0.0f;
// Get block this position is in
float fInvBlockSize = 1.0f / m_fBlockSize;
int iCol = (int)((vPos.x - rcActive.left) * fInvBlockSize);
int iRow = (int)(-(vPos.z - rcActive.top) * fInvBlockSize);
AAssist.a_Clamp(ref iCol, 0, m_pCurActBlocks.rcArea.Width() - 1);
AAssist.a_Clamp(ref iRow, 0, m_pCurActBlocks.rcArea.Height() - 1);
int iBlock = iRow * m_pCurActBlocks.rcArea.Width() + iCol;
A3DTerrain2Block pBlock = m_pCurActBlocks.aBlocks[iBlock];
if (pBlock == null || !pBlock.IsDataLoaded())
return 0.0f;
// If whole block is a hole, return as if there is no block here
if (pBlock.IsNoPosHeight())
return 0.0f;
// Get block's AABB
A3DAABB aabb = pBlock.GetBlockAABB();
// Get grid this position is in
float fInvGridSize = 1.0f / m_fGridSize;
iCol = (int)((vPos.x - aabb.Mins.x) * fInvGridSize);
iRow = (int)(-(vPos.z - aabb.Maxs.z) * fInvGridSize);
AAssist.a_Clamp(ref iCol, 0, m_iBlockGrid - 1);
AAssist.a_Clamp(ref iRow, 0, m_iBlockGrid - 1);
int iGrid = iRow * m_iBlockGrid + iCol;
GRID Grid = m_pLODMan.GetGrids()[iGrid];
A3DVECTOR3 v0 = pBlock.GetVertexPos(Grid.v0);
A3DVECTOR3 v1 = pBlock.GetVertexPos(Grid.v1);
A3DVECTOR3 v2 = pBlock.GetVertexPos(Grid.v2);
A3DVECTOR3 v3 = pBlock.GetVertexPos(Grid.v3);
A3DVECTOR3 v4 = pBlock.GetVertexPos(Grid.v4);
A3DVECTOR3 v5 = pBlock.GetVertexPos(Grid.v5);
A3DVECTOR3 vDest;
float dx, dz;
if (iGrid == m_iBlockGrid - 1 || iGrid == m_iBlockGrid * (m_iBlockGrid - 1))
{
// The grid is on right-top corner or left-bottom corner
dx = vPos.x - v2.x;
dz = vPos.z - v2.z;
if (dx > dz)
{
vDest = v5 + (v4 - v5) * (dx / (v4.x - v5.x));
vDest += (v3 - v4) * (dz / (v3.z - v4.z));
if (pvNormal != null)
{
pvNormal = A3DVECTOR3.CrossProduct(v4 - v3, v5 - v3);
pvNormal.Normalize();
}
}
else
{
vDest = v2 + (v0 - v2) * (dz / (v0.z - v2.z));
vDest += (v1 - v0) * (dx / (v1.x - v0.x));
if (pvNormal != null)
{
pvNormal = A3DVECTOR3.CrossProduct(v1 - v0, v2 - v0);
pvNormal.Normalize();
}
}
}
else
{
dx = vPos.x - v0.x;
dz = vPos.z - v0.z;
if (dx > -dz)
{
vDest = v0 + (v1 - v0) * (dx / (v1.x - v0.x));
vDest += (v2 - v1) * (dz / (v2.z - v1.z));
if (pvNormal != null)
{
pvNormal = A3DVECTOR3.CrossProduct(v1 - v0, v2 - v0);
pvNormal.Normalize();
}
}
else
{
vDest = v3 + (v5 - v3) * (dz / (v5.z - v3.z));
vDest += (v4 - v5) * (dx / (v4.x - v5.x));
if (pvNormal != null)
{
pvNormal = A3DVECTOR3.CrossProduct(v4 - v3, v5 - v3);
pvNormal.Normalize();
}
}
}
return vDest.y;
}
}
// Active blocks
public struct ACTBLOCKS
{
public ARectI rcArea; // Active area represented in blocks
public BlockArray aBlocks; // Active block array
public ACTBLOCKS(ARectI rcArea, BlockArray aBlocks)
{
this.rcArea = rcArea;
this.aBlocks = aBlocks;
}
// Get block object at specified row, column.
public A3DTerrain2Block GetBlock(int r, int c, bool bClear)
{
//ASSERT(rcArea.PtInRect(c, r));
int iIndex = GetBlockIndex(r, c);
A3DTerrain2Block pBlock = aBlocks[iIndex];
if (bClear)
aBlocks[iIndex] = null;
return pBlock;
}
// Set block object at specified row, column
void SetBlock(int r, int c, A3DTerrain2Block pBlock)
{
//ASSERT(rcArea.PtInRect(c, r));
int iIndex = GetBlockIndex(r, c);
aBlocks[iIndex] = pBlock;
}
// Get block index in aBlocks
int GetBlockIndex(int r, int c)
{
return (r - rcArea.top) * rcArea.Width() + c - rcArea.left;
}
};
// Block flags & masks
public class Block_flags_masks
{
public static uint T2BKFLAG_DEFAULT = 0x00, // The block flag default value
T2BKFLAG_NORENDER = 0x01, // The whole block is not rendered
T2BKFLAG_NOTRACE = 0x02, // The whole block is out of RayTrace
T2BKFLAG_NOPOSHEIGHT = 0x04, // The whole block is unable to GetPosHeight
T2BKFLAG_NORENDERWITHWATER = 0x08; // The whole block is not rendered with water
};
// Vertex indices in a terrain grid
public struct GRID
{
public int v0, v1, v2; // Face 1
public int v3, v4, v5; // Face 2
};
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 828eeca29c5904541bdb0f5162832508
@@ -0,0 +1,12 @@
using BrewMonster.Scripts.World;
using WORD = System.UInt16;
public class A3DTerrain2LOD
{
public GRID[] m_aGrids; // Grid of a block
public WORD[] m_aIndexMaps; // Index map
// Get grids
public GRID[] GetGrids() { return m_aGrids; }
public WORD[] GetIndexMaps() { return m_aIndexMaps; }
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ea4c2d97d77797548b9de5443e250290
@@ -0,0 +1,281 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace BrewMonster.Scripts
{
public class ARect<T> where T : IComparable<T>
{
public T left, top, right, bottom;
public ARect()
{
left = default(T);
top = default(T);
right = default(T);
bottom = default(T);
}
public ARect(ARect<T> rc)
{
left = rc.left; top = rc.top; right = rc.right; bottom = rc.bottom;
}
public ARect(T left, T top, T right, T bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
// == and != operator
public static bool operator !=(ARect<T> rc1, ARect<T> rc2)
{
return !(rc1 == rc2);
}
public static bool operator ==(ARect<T> rc1, ARect<T> rc2)
{
return EqualityComparer<T>.Default.Equals(rc1.left, rc2.left) &&
EqualityComparer<T>.Default.Equals(rc1.top, rc2.top) &&
EqualityComparer<T>.Default.Equals(rc1.right, rc2.right) &&
EqualityComparer<T>.Default.Equals(rc1.bottom, rc2.bottom);
}
// + and - operator
public static ARect<T> operator +(ARect<T> rc1, ARect<T> rc2)
{
dynamic l = rc1.left, t = rc1.top, r = rc1.right, b = rc1.bottom;
dynamic l2 = rc2.left, t2 = rc2.top, r2 = rc2.right, b2 = rc2.bottom;
ARect<T> result = new ARect<T>(l + l2, t + t2, r + r2, b + b2);
return result;
}
public static ARect<T> operator -(ARect<T> rc1, ARect<T> rc2)
{
return new ARect<T>((dynamic)rc1.left - (dynamic)rc2.left,
(dynamic)rc1.top - (dynamic)rc2.top,
(dynamic)rc1.right - (dynamic)rc2.right,
(dynamic)rc1.bottom - (dynamic)rc2.bottom);
}
//public static ARect<T> operator +(ARect<T> rc1, APoint<T> pt)
//{
// return new ARect<T>((dynamic)rc1.left + (dynamic)pt.x,
// (dynamic)rc1.top + (dynamic)pt.y,
// (dynamic)rc1.right + (dynamic)pt.x,
// (dynamic)rc1.bottom + (dynamic)pt.y);
//}
//public static ARect<T> operator -(ARect<T> rc1, APoint<T> pt)
//{
// return new ARect<T>((dynamic)rc1.left - (dynamic)pt.x,
// (dynamic)rc1.top - (dynamic)pt.y,
// (dynamic)rc1.right - (dynamic)pt.x,
// (dynamic)rc1.bottom - (dynamic)pt.y);
//}
// &= and |= operator
public ARect<T> AndAssign(ARect<T> rc) => this & rc;
public ARect<T> OrAssign(ARect<T> rc) => this | rc;
public static ARect<T> operator &(ARect<T> rc1, ARect<T> rc2)
{
if (rc1.IsEmpty() || rc2.IsEmpty())
return new ARect<T>(default, default, default, default);
dynamic l1 = rc1.left, r1 = rc1.right, t1 = rc1.top, b1 = rc1.bottom;
dynamic l2 = rc2.left, r2 = rc2.right, t2 = rc2.top, b2 = rc2.bottom;
if (l1 >= r2 || l2 >= r1 ||
t1 >= b2 || t2 >= b1)
return new ARect<T>(default, default, default, default);
return new ARect<T>(l1 > l2 ? l1 : l2,
t1 > t2 ? t1 : t2,
r1 < r2 ? r1 : r2,
b1 < b2 ? b1 : b2);
}
public static ARect<T> operator |(ARect<T> rc1, ARect<T> rc2)
{
if (rc1.IsEmpty())
return rc2;
if (rc2.IsEmpty())
return rc1;
dynamic l1 = rc1.left, r1 = rc1.right, t1 = rc1.top, b1 = rc1.bottom;
dynamic l2 = rc2.left, r2 = rc2.right, t2 = rc2.top, b2 = rc2.bottom;
return new ARect<T>(l1 < l2 ? l1 : l2,
t1 < t2 ? t1 : t2,
r1 > r2 ? r1 : r2,
b1 > b2 ? b1 : b2);
}
public static ARect<T> operator +(ARect<T> rc) { return rc; }
public static ARect<T> operator -(ARect<T> rc)
{
return new ARect<T>(-(dynamic)rc.left, -(dynamic)rc.top, -(dynamic)rc.right, -(dynamic)rc.bottom);
}
// = operator
//public static ARect<T> operator = (ARect<T> rc) { left = rc.left; top = rc.top; right = rc.right; bottom = rc.bottom; return *this; }
// += and -= operator
public ARect<T> AdditionAssign(ARect<T> rc)
{
left += (dynamic)rc.left;
top += (dynamic)rc.top;
right += (dynamic)rc.right;
bottom += (dynamic)rc.bottom;
return this;
}
public ARect<T> SubtractionAssign(ARect<T> rc)
{
left -= (dynamic)rc.left;
top -= (dynamic)rc.top;
right -= (dynamic)rc.right;
bottom -= (dynamic)rc.bottom;
return this;
}
//public ARect<T> AdditionAssign(APoint<T> pt) { left += pt.x; top += pt.y; right += pt.x; bottom += pt.y; return this; }
//public ARect<T> SubtractionAssign(APoint<T> pt) { left -= pt.x; top -= pt.y; right -= pt.x; bottom -= pt.y; return this; }
// Get width of rectangle
public T Width()
{
return (dynamic)right - (dynamic)left;
}
// Get height of rectangle
public T Height()
{
return (dynamic)bottom - (dynamic)top;
}
// Get center point of rectangle
//public APoint<T> CenterPoint() { return new APoint<T>((left + right) / 2, (top + bottom) / 2); }
// Set rectangle value
public void SetRect(T _left, T _top, T _right, T _bottom)
{
left = _left;
top = _top;
right = _right;
bottom = _bottom;
}
// Point in rectangle
public bool PtInRect(T x, T y)
{
dynamic valueX = x;
dynamic valueY = y;
return (valueX >= left && valueX < right && valueY >= top && valueY < bottom) ? true : false;
}
//public bool PtInRect(APoint<T> pt) { return PtInRect(pt.x, pt.y); }
// Normalize rectangle. Note: The following CRect member functions require
// normalized rectangles in order to work properly: Height, Width, Size,
// IsEmpty, PtInRect, SetUnion, SetIntersect, operator ==, operator !=,
// operator |, operator |=, operator &, and operator &=
void Normalize()
{
if ((dynamic)left > right)
a_Swap(left, right);
if ((dynamic)top > bottom)
a_Swap(top, bottom);
}
private void a_Swap(T lhs, T rhs)
{
T tmp;
tmp = lhs;
lhs = rhs;
rhs = tmp;
}
// All members are 0 ?
public bool IsRectNull()
{
return ((dynamic)left == 0 && (dynamic)top == 0 && (dynamic)right == 0 && (dynamic)bottom == 0);
}
// Rectangle is empty ?
public bool IsEmpty()
{
return ((dynamic)Width() == 0 || (dynamic)Height() == 0);
}
// Set all members to 0
public void Clear()
{
left = top = right = bottom = default(T);
}
// Deflate rectangle
public void Deflate(T x, T y)
{
left += (dynamic)x;
top += (dynamic)y;
right -= (dynamic)x;
bottom -= (dynamic)y;
}
public void Deflate(ARect<T> rc)
{
left += (dynamic)rc.left;
top += (dynamic)rc.top;
right -= (dynamic)rc.right;
bottom -= (dynamic)rc.bottom;
}
public void Deflate(T l, T t, T r, T b)
{
left += (dynamic)l;
top += (dynamic)t;
right -= (dynamic)r;
bottom -= (dynamic)b;
}
// Inflate rectangle
public void Inflate(T x, T y)
{
left -= (dynamic)x;
top -= (dynamic)y;
right += (dynamic)x;
bottom += (dynamic)y;
}
public void Inflate(ARect<T> rc)
{
left -= (dynamic)rc.left;
top -= (dynamic)rc.top;
right += (dynamic)rc.right;
bottom += (dynamic)rc.bottom;
}
public void Inflate(T l, T t, T r, T b)
{
left -= (dynamic)l;
top -= (dynamic)t;
right += (dynamic)r;
bottom += (dynamic)b;
}
// Offset rectangle
public void Offset(T x, T y)
{
left += (dynamic)x;
top += (dynamic)y;
right += (dynamic)x;
bottom += (dynamic)y;
}
//public void Offset(APoint<T> pt) { this += pt; }
// Set rectangle as union result
public void SetUnion(ARect<T> rc1, ARect<T> rc2)
{
var result = rc1 | rc2;
left = result.left;
right = result.right;
bottom = result.bottom;
top = result.top;
}
// Set rectangle as intersect result
public void SetIntersect(ARect<T> rc1, ARect<T> rc2)
{
var result = rc1 & rc2;
left = result.left;
right = result.right;
bottom = result.bottom;
top = result.top;
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 00eedf309b0008346a58412f4aad4dec
@@ -1,4 +1,5 @@
using BrewMonster;
using BrewMonster.Managers;
using CSNetwork.GPDataType;
using System;
using System.Collections;
@@ -1,4 +1,5 @@
using BrewMonster;
using BrewMonster.Scripts.World;
using CSNetwork;
using CSNetwork.GPDataType;
using DG.Tweening;
@@ -0,0 +1,55 @@
using System.Collections.Generic;
using System.Numerics;
using UnityEngine;
namespace BrewMonster.Scripts
{
//@desc : using grid to manage the brushes. By Kuiwu[2/11/2005]
public class CBrushGrid
{
//public CBrushGrid(int iCellSize = 80, int iW = 11, int iH = 11);
// void AddProvider(CBrushProvider* pProvider);
// bool RemoveProvider(CBrushProvider* pProvider);
// void Build(const A3DVECTOR3& vCenter, bool bForce = false);
public bool Trace(BrushTraceInfo pInfo, bool bCheckFlag = true)
{
return false;
}
#if BMAN_VERBOSE_STAT
CBManStat * GetStat()
{
return &m_Stat;
}
#endif
// private int m_iCellSize;
// private int m_iW, m_iH; //in cell
// private short m_iCenterX, m_iCenterZ;
// private float m_fTraceRange2;
// private CBrushCell m_pBrushCell; //as a brush cell buffer
// //@note : use hash table to accelerate searching cell buffer. By Kuiwu[2/11/2005]
// private Dictionary<CBrushCell , uint> CellTable;
// private CellTable m_CellTbl;
// private vector<CBrushProvider*> m_UnOrganizedProvider; //to be built.
// private vector<CCDBrush*> m_OutOfRangeBrush;
// private void _GetCellIndex(const A3DVECTOR3& vPos, short& x, short& z);
//private CBrushCell * _FindCell(short x, short z);
// private bool _UpdateCenter(const A3DVECTOR3& vCenter, bool bForce);
// private bool _AddBrush(CCDBrush pBrush);
#if BMAN_VERBOSE_STAT
CBManStat m_Stat;
#endif
}
public class CECBrushMan
{
public CBrushGrid m_pBrushGrid;
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: dbb7777494908644db0a9f59f533162d
@@ -0,0 +1,714 @@
using CSNetwork.GPDataType;
using PerfectWorld.Scripts.Player;
using System;
namespace BrewMonster.Scripts
{
using WorkList = System.Collections.Generic.List<CECEPWork>;
public abstract class CECEPWorkMatcher
{
public abstract bool Match(CECEPWork work, int workType);
}
// class CECEPWorkMelee
public class CECEPWorkMelee : CECEPWork
{
int m_iAttackTarget;
public CECEPWorkMelee(CECEPWorkMan pWorkMan, int attackTarget) : base(EP_work_ID.WORK_HACKOBJECT, pWorkMan)
{
m_iAttackTarget = attackTarget;
}
public override void Start()
{
GetPlayer().m_iMoveMode = (int)MoveMode.MOVE_STAND;
GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_ATTACK_1 + UnityEngine.Random.Range(0, 3));
GetPlayer().EnterFightState();
}
public override void Tick(float dwDeltaTime)
{
GetPlayer().TurnFaceTo(m_iAttackTarget);
// Slide to server position
A3DVECTOR3 vDir = GetPlayer().m_vServerPos - GetPlayer().GetPos();
float fDist = vDir.Normalize();
if (fDist > 0.0001f)
{
float fMoveDist = 10.0f * dwDeltaTime * 0.001f;
if (fMoveDist > fDist)
fMoveDist = fDist;
GetPlayer().SetPos(GetPlayer().GetPos() + vDir * fMoveDist);
}
if (GetPlayer().m_FightCnt.IncCounter(dwDeltaTime))
{
Finish();
}
}
public override void Cancel()
{
GetPlayer().TurnFaceTo(0);
}
};
public class CECEPWorkIDMatcher : CECEPWorkMatcher
{
int m_workID;
public CECEPWorkIDMatcher(int workID)
{
m_workID = workID;
}
public override bool Match(CECEPWork work, int workType)
{
return work != null && work.GetWorkID() == m_workID;
}
}
// class CECEPWorkCongregate
public class CECEPWorkCongregate : CECEPWork
{
int m_iType;
public CECEPWorkCongregate(CECEPWorkMan pWorkMan, int iType) : base(EP_work_ID.WORK_CONGREGATE, pWorkMan)
{
m_iType = iType;
}
public override void Start()
{
}
public int GetType()
{
return m_iType;
}
}
public class CECEPCongregateWorkMatcher : CECEPWorkMatcher
{
int m_iType;
public CECEPCongregateWorkMatcher(int iType)
{
m_iType = iType;
}
public override bool Match(CECEPWork work, int workType)
{
if (work != null && work.GetWorkID() == CECEPWork.EP_work_ID.WORK_CONGREGATE)
{
CECEPWorkCongregate pCongregateWork = work as CECEPWorkCongregate;
return pCongregateWork.GetType() == m_iType;
}
return false;
}
}
// class CECEPWorkIdle
public class CECEPWorkIdle : CECEPWork
{
int m_iType;
bool m_bOTCheck;
CECCounter m_OTCnt;
uint m_dwParam;
public CECEPWorkIdle(CECEPWorkMan pWorkMan, int iType, int iOTTime, uint dwParam) : base(EP_work_ID.WORK_IDLE, pWorkMan)
{
m_dwParam = dwParam;
m_iType = iType;
m_bOTCheck = iOTTime > 0 ? true : false;
if (m_bOTCheck)
{
m_OTCnt.SetPeriod(iOTTime);
m_OTCnt.Reset();
}
switch (iType)
{
case Idle_work_type.IDLE_SITDOWN:
GetPlayer().m_iMoveMode = (int)MoveMode.MOVE_STAND;
if (m_dwParam != 0)
GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_SITDOWN_LOOP);
else
{
GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_SITDOWN);
GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_SITDOWN_LOOP, true, 200, true);
}
break;
case Idle_work_type.IDLE_REVIVE:
GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_REVIVE);
break;
case Idle_work_type.IDLE_BOOTH:
GetPlayer().m_iMoveMode = (int)MoveMode.MOVE_STAND;
break;
}
}
public override void Tick(float dwDeltaTime)
{
base.Tick(dwDeltaTime);
}
public int GetType()
{
return m_iType;
}
}
public class CECEPIdleWorkMatcher : CECEPWorkMatcher
{
int m_iType;
public CECEPIdleWorkMatcher(int iType)
{
m_iType = iType;
}
public override bool Match(CECEPWork work, int workType)
{
if (work != null && work.GetWorkID() == CECEPWork.EP_work_ID.WORK_IDLE)
{
CECEPWorkIdle pIdleWork = work as CECEPWorkIdle;
return pIdleWork.GetType() == m_iType;
}
return false;
}
}
public class CECEPWork
{
public static class EP_work_ID
{
public const int WORK_INVALID = -1,
WORK_STAND = 0, // Stand and do nothing
WORK_MOVE = 1, // Move
WORK_HACKOBJECT = 2, // Hack specified object (NPC, player etc.)
WORK_SPELL = 3, // Spell magic
WORK_PICKUP = 4, // Pickup matter
WORK_DEAD = 5, // Dead
WORK_USEITEM = 6, // Use item
WORK_IDLE = 7, // Idle works
WORK_FLASHMOVE = 8, // Flash move
WORK_PASSIVEMOVE = 9, // Move controlled by server
WORK_CONGREGATE = 10, // Congregate reply
WORK_SKILLSTATEACT = 11, // skill buff action
NUM_WORK = 12;
}
// Idle work type
public static class Idle_work_type
{
public const int IDLE_SITDOWN = 0,
IDLE_REVIVE = 1,
IDLE_BOOTH = 2;
}
static string[] l_WorkName = new string[EP_work_ID.NUM_WORK]
{
"WORK_STAND",
"WORK_MOVE",
"WORK_HACKOBJECT",
"WORK_SPELL",
"WORK_PICKUP",
"WORK_DEAD",
"WORK_USEITEM",
"WORK_IDLE",
"WORK_FLASHMOVE",
"WORK_PASSIVEMOVE",
"WORK_CONGREGATE",
"WORK_SKILLSTATEACT",
};
protected int m_iWorkID;
protected CECEPWorkMan m_pWorkMan;
protected bool m_bFinished;
protected EC_ElsePlayer GetPlayer()
{
return m_pWorkMan.GetPlayer();
}
public CECEPWork(int iWorkID, CECEPWorkMan pWorkMan)
{
m_iWorkID = iWorkID;
m_pWorkMan = pWorkMan;
m_bFinished = false;
}
public static string GetWorkName(int iWork)
{
if (iWork >= EP_work_ID.WORK_STAND && iWork < l_WorkName.Length)
{
return l_WorkName[iWork];
}
else
{
return "Invalid Work";
}
}
public string GetWorkName()
{
return GetWorkName(GetWorkID());
}
public int GetWorkID()
{
return m_iWorkID;
}
public bool IsFinished()
{
return m_bFinished;
}
public virtual void Start() { }
public virtual void Tick(float dwDeltaTime) { }
public virtual void Cancel() { }
public virtual void Finish()
{
m_bFinished = true;
}
static bool Validate(int iWork)
{
return iWork >= EP_work_ID.WORK_STAND && iWork < EP_work_ID.NUM_WORK;
}
}
// class CECEPWorkSpell
public class CECEPWorkSpell : CECEPWork
{
CECCounter m_SkillCnt;
CECSkill m_pCurSkill;
int m_idCurSkillTarget;
public CECEPWorkSpell(CECEPWorkMan pWorkMan, uint dwPeriod, CECSkill pSkill, int target) : base(CECEPWork.EP_work_ID.WORK_SPELL, pWorkMan)
{
m_pCurSkill = pSkill;
m_idCurSkillTarget = target;
m_SkillCnt.SetPeriod(dwPeriod);
m_SkillCnt.Reset();
}
public override void Start()
{
GetPlayer().m_iMoveMode = (int)MoveMode.MOVE_STAND;
}
public override void Tick(float dwDeltaTime)
{
//TO DO: fix later
//GetPlayer().m_FightCnt.IncCounter(dwDeltaTime);
//int iRealTime = g_pGame.GetRealTickTime();
//if (m_SkillCnt.IncCounter(iRealTime))
//{
// Finish();
//}
//else
//{
// if (m_idCurSkillTarget != 0)
// {
// GetPlayer().TurnFaceTo(m_idCurSkillTarget);
// }
// if (GetPlayer().IsPlayingMoveAction() && !GetPlayer().IsWorkMoveRunning())
// { // 从移动施法到停止移动、会一直在持续播放移动动作,此处暂停
// GetPlayer().PlayAction(CECPlayer::ACT_FIGHTSTAND);
// }
// if (!GetPlayer().IsPlayingAction())
// {
// GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_FIGHTSTAND); // 技能动作播放完成后、播放战斗站立动作
// }
//}
}
public override void Cancel()
{
//TO DO: fix later
//if (m_pCurSkill != null)
//{
// m_pCurSkill = null;
//}
//m_idCurSkillTarget = 0;
//GetPlayer().StopSkillAttackAction();
//GetPlayer().TurnFaceTo(0);
}
public CECSkill GetSkill()
{
return m_pCurSkill;
}
}
public class CECEPWorkMan
{
public static class Work_type
{
public const int WT_NOTHING = 0, // Do thing
WT_NORMAL = 1, // Normal type work
WT_INTERRUPT = 2, // Interrupt type work
NUM_WORKTYPE = 3;
}
private EC_ElsePlayer m_pElsePlayer;
private WorkList[] m_WorkStack = new WorkList[Work_type.NUM_WORKTYPE];
private int m_iCurWorkType;
public CECEPWorkMan(EC_ElsePlayer pElsePlayer)
{
m_pElsePlayer = pElsePlayer;
m_iCurWorkType = -1;
}
public EC_ElsePlayer GetPlayer()
{
return m_pElsePlayer;
}
public bool ValidateWorkType(int iWorkType)
{
return iWorkType >= 0 && iWorkType < Work_type.NUM_WORKTYPE;
}
public bool FindWork(int iWorkType, int iWorkID)
{
if (!ValidateWorkType(iWorkType))
{
return false;
}
WorkList workList = m_WorkStack[iWorkType];
if (workList != null)
{
for (int i = 0; i < workList.Count; ++i)
{
if (iWorkID == workList[i].GetWorkID())
{
return true;
}
}
}
return false;
}
public void StartNormalWork(CECEPWork pWork)
{
StartWork(Work_type.WT_NORMAL, ref pWork);
}
private bool CanRunSimultaneously(CECEPWork pWork1, CECEPWork pWork2)
{
if (pWork1.GetWorkID() == CECEPWork.EP_work_ID.WORK_MOVE &&
pWork2.GetWorkID() == CECEPWork.EP_work_ID.WORK_SPELL)
{
return CanSpellWhileMoving(pWork2 as CECEPWorkSpell);
}
if (pWork2.GetWorkID() == CECEPWork.EP_work_ID.WORK_MOVE &&
pWork1.GetWorkID() == CECEPWork.EP_work_ID.WORK_SPELL)
{
return CanSpellWhileMoving(pWork1 as CECEPWorkSpell);
}
return false;
}
private bool CanReplace(CECEPWork pNewWork, CECEPWork pExistWork)
{
if (pNewWork.GetWorkID() == CECEPWork.EP_work_ID.WORK_SPELL &&
pExistWork.GetWorkID() == CECEPWork.EP_work_ID.WORK_SPELL)
{
return CanSpellWhileMoving(pNewWork as CECEPWorkSpell)
&& CanSpellWhileMoving(pExistWork as CECEPWorkSpell);
}
return false;
}
private bool CanSpellWhileMoving(CECEPWorkSpell pWorkSpell)
{
return false;
// TO DO: fix later
// return pWorkSpell.GetSkill()
// && CECCastSkillWhenMove.Instance().IsSkillSupported(pWorkSpell.GetSkill().GetSkillID(), GetPlayer());
}
private bool CanMergeWithCurrentWork(int iWorkType, CECEPWork pWork)
{
if (!ValidateWorkType(iWorkType) || iWorkType != m_iCurWorkType)
{
return false;
}
WorkList workList = m_WorkStack[iWorkType];
if (workList == null || workList.Count == 0)
{
return false;
}
for (int i = 0; i < workList.Count; ++i)
{
if (!CanRunSimultaneously(pWork, workList[i]) && // 要么同时共存
!CanReplace(pWork, workList[i]))
{ // 要么可以替换
return false;
}
}
return true;
}
private void KillWork(int iWorkType, int index)
{
if (!ValidateWorkType(iWorkType))
{
//ASSERT(false);
return;
}
WorkList workList = m_WorkStack[iWorkType];
if (index < 0 || index >= (int)workList.Count)
{
//ASSERT(false);
return;
}
CECEPWork pWork = workList[index];
pWork.Cancel();
//LOG_DEBUG_INFO(AString().Format("CECEPWorkMan::%s(%s) killed", pWork.GetWorkName(), GetWorkTypeName(iWorkType)));
//delete pWork;
pWork = null;
workList.RemoveAt(index);
}
private void MergeWork(int iWorkType, CECEPWork pWork)
{
if (!CanMergeWithCurrentWork(iWorkType, pWork))
{
//ASSERT(false);
return;
}
WorkList workList = m_WorkStack[iWorkType];
for (int i = 0; i < workList.Count; ++i)
{
if (CanReplace(pWork, workList[i]))
{
//LOG_DEBUG_INFO(AString().Format("CECEPWorkMan::MergeWork %s replacing %s at %s", pWork.GetWorkName(), workList[i].GetWorkName(), GetWorkTypeName(iWorkType)));
KillWork(iWorkType, i);
workList.Insert(i, pWork);
return;
}
}
workList.Add(pWork);
//LOG_DEBUG_INFO(AString().Format("CECEPWorkMan::MergeWork %s appended to %s", pWork.GetWorkName(), GetWorkTypeName(iWorkType)));
}
private void FinishWorkAtWorkType(int iWorkType)
{
if (!ValidateWorkType(iWorkType))
{
//ASSERT(false);
return;
}
WorkList workList = m_WorkStack[iWorkType];
while (workList != null && workList.Count != 0)
{
KillWork(iWorkType, 0);
}
if (m_iCurWorkType == iWorkType)
{
m_iCurWorkType = -1;
}
}
private void AppendWork(int iWorkType, CECEPWork pWork)
{
if (!ValidateWorkType(iWorkType) || pWork == null)
{
//ASSERT(false);
return;
}
m_WorkStack[iWorkType].Add(pWork);
}
private void CancelWorkAtWorkType(int iWorkType)
{
if (!ValidateWorkType(iWorkType))
{
return;
}
WorkList workList = m_WorkStack[iWorkType];
for (int i = 0; i < workList.Count; ++i)
{
CancelWork(workList[i]);
//LOG_DEBUG_INFO(AString().Format("CECEPWorkMan::%s(%s) cancelled", workList[i].GetWorkName(), GetWorkTypeName(iWorkType)));
}
}
private void CancelWork(CECEPWork pWork)
{
if (pWork == null)
{
//ASSERT(false);
return;
}
pWork.Cancel();
}
public void StartWork(int iWorkType, ref CECEPWork pWork)
{
if (!ValidateWorkType(iWorkType))
{
pWork = null;
return;
}
if (CanMergeWithCurrentWork(iWorkType, pWork))
{
MergeWork(iWorkType, pWork);
}
else
{
if (pWork.GetWorkID() == CECEPWork.EP_work_ID.WORK_DEAD)
{
for (int i = iWorkType; i < Work_type.NUM_WORKTYPE; i++)
{
FinishWorkAtWorkType(i);
}
AppendWork(iWorkType, pWork);
m_iCurWorkType = iWorkType;
}
else
{
bool shouldStart = (iWorkType >= m_iCurWorkType);
FinishWorkAtWorkType(iWorkType);
AppendWork(iWorkType, pWork);
if (!shouldStart)
{
//LOG_DEBUG_INFO(AString().Format("CECEPWork::StartWork %s flushed %s", pWork.GetWorkName(), GetWorkTypeName(iWorkType)));
return;
}
if (iWorkType > m_iCurWorkType)
{
CancelWorkAtWorkType(m_iCurWorkType);
}
m_iCurWorkType = iWorkType;
}
}
pWork.Start();
}
private bool IsAnyWorkRunning()
{
return ValidateWorkType(m_iCurWorkType) && m_WorkStack != null && m_WorkStack[m_iCurWorkType] != null;
}
private void StartAwaitingWorks()
{
if (ValidateWorkType(m_iCurWorkType))
{
for (--m_iCurWorkType; m_iCurWorkType >= 0; --m_iCurWorkType)
{
WorkList workList = m_WorkStack[m_iCurWorkType];
if (workList == null || workList.Count == 0)
{
continue;
}
for (int j = 0; j < workList.Count; ++j)
{
workList[j].Start();
//LOG_DEBUG_INFO(AString().Format("CECElsePlayer::StartAwaitingWorks %s(%s) started by decrease priority", workList[j].GetWorkName(), GetWorkTypeName(m_iCurWorkType)));
}
break;
}
}
}
public void Tick(float dwDeltaTime)
{
if (!IsAnyWorkRunning())
{
return;
}
WorkList workList = m_WorkStack[m_iCurWorkType];
if (workList != null)
{
for (int i = 0; i < workList.Count;)
{
CECEPWork pWork = workList[i];
pWork.Tick(dwDeltaTime);
if (!pWork.IsFinished())
{
++i;
continue;
}
KillWork(m_iCurWorkType, i);
}
if (workList == null || workList.Count == 0)
{
StartAwaitingWorks();
}
}
}
public void FinishWork(CECEPWorkMatcher matcher)
{
bool bCurrentWorkFinished = false;
for (int i = Work_type.NUM_WORKTYPE - 1; i >= 0; --i)
{
WorkList workList = m_WorkStack[i];
if (workList == null || workList.Count == 0)
{
continue;
}
for (int j = 0; j < workList.Count;)
{
if (!matcher.Match(workList[j], i))
{
++j;
continue;
}
KillWork(i, j);
if (i == m_iCurWorkType && (workList == null || workList.Count == 0))
{
bCurrentWorkFinished = true;
}
}
}
if (bCurrentWorkFinished)
{
StartAwaitingWorks();
}
}
public void FinishWork(int idWork)
{
FinishWork(new CECEPWorkIDMatcher(idWork));
}
public bool IsWorkRunning(int iWork)
{
return FindWork(m_iCurWorkType, iWork);
}
public void FinishRunningWork(int idWork)
{
if (!IsWorkRunning(idWork))
{
return;
}
WorkList workList = m_WorkStack[m_iCurWorkType];
if (workList != null)
{
for (int i = 0; i < workList.Count;)
{
if (workList[i].GetWorkID() != idWork)
{
++i;
continue;
}
//LOG_DEBUG_INFO(AString().Format("CECEPWorkMan::FinishRunningWork %s(%s)", workList[i].GetWorkName(), GetWorkTypeName(m_iCurWorkType)));
KillWork(m_iCurWorkType, i);
}
if (workList == null)
{
StartAwaitingWorks();
}
}
}
public bool FinishIdleWork(int iType)
{
FinishWork(new CECEPIdleWorkMatcher(iType));
return true;
}
public bool FinishCongregateWork(int iType)
{
FinishWork(new CECEPCongregateWorkMatcher(iType));
return true;
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 9352b9911dad2d541b975297dcefa8d2
File diff suppressed because it is too large Load Diff
@@ -1,5 +1,7 @@
using BrewMonster;
using BrewMonster.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using PerfectWorld.Scripts.Managers;
using PerfectWorld.Scripts.Player;
@@ -1,367 +1,370 @@
using CSNetwork.GPDataType;
using UnityEngine;
public class CECHPWorkMove : CECHPWork
namespace BrewMonster.Scripts
{
public static class Types
public class CECHPWorkMove : CECHPWork
{
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)
public static class Types
{
m_vCurDir = vMoveDest;
if (m_bUseAutoMoveDialog)
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_bUseAutoMoveDialog = false;
m_bAutoLand = false;
m_fAutoHeight = -1.0f;
m_bAutoFly = false;
m_bReachedHeight = true;
m_bAutoFlyPending = false;
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())
{
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
//m_vCurDir = CECIntelligentRoute::Instance().GetCurDest() - m_pHost->GetPos();
//m_vCurDir.y = 0.0f;
//m_vCurDir.Normalize();
//if (m_bUseAutoMoveDialog)
//if (m_pHost.m_pMoveTargetGFX)
//{
// // 此处禁用 m_bUseAutoMoveDialog,见 SetUseAutoMoveDialog 中说明
// m_bUseAutoMoveDialog = false;
// m_bAutoLand = false;
// m_fAutoHeight = -1.0f;
// m_bAutoFly = false;
// m_bReachedHeight = true;
// m_bAutoFlyPending = false;
// if (iDestType != DEST_PUSH)
// m_pHost.m_pMoveTargetGFX.Stop();
//}
}
// TO DO: fix later
//if (m_pHost.m_pMoveTargetGFX)
//{
// if (iDestType != DEST_PUSH)
// m_pHost.m_pMoveTargetGFX.Stop();
//}
}
void ResetUseAutoPF()
{
m_bResetAutoPF = true;
}
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;
// }
//}
// 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);
//base.Tick(dwDeltaTime);
//if (m_pHost.IsRooting())
// return true;
//if (m_pHost.IsRooting())
// return true;
//if (m_bUseAutoMoveDialog)
//{
// if (m_pHost.IsFlying())
// {
// m_bAutoFly = false;
// m_bAutoFlyPending = false;
// }
//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);
//}
// 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;
// }
// }
// }
//}
////寻路过程中找到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);
// }
//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();
// 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);
// }
// // Play appropriate actions
// if (!m_bGliding)
// {
// int iAction = m_pHost.GetMoveStandAction(true);
// m_pHost.PlayAction(iAction, false);
// }
// Tick_FlySwim(fDeltaTime);
//}
// Tick_FlySwim(fDeltaTime);
//}
return true;
}
// Reset work
public virtual void Reset()
{
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();
}
}
// 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();
}
}
@@ -1,75 +1,78 @@
using UnityEngine;
///////////////////////////////////////////////////////////////////////////
//
// Class CECHPWorkSpell
//
///////////////////////////////////////////////////////////////////////////
public class CECHPWorkSpell : CECHPWork
namespace BrewMonster.Scripts
{
public static class Spell_magic_state
///////////////////////////////////////////////////////////////////////////
//
// Class CECHPWorkSpell
//
///////////////////////////////////////////////////////////////////////////
public class CECHPWorkSpell : CECHPWork
{
public const int ST_INCANT = 0,
ST_SPELL = 1;
}
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(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)
{
}
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
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)
{
// 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)
{
}
// Change state
public void ChangeState(int iState)
{
}
// Get state
public int GetState()
{
return m_iState;
}
public CECSkill GetSkill()
{
return m_pSkill;
}
}
// 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()
{
// 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()
{
}
// Copy work data
public virtual bool CopyData(CECHPWork pWork)
{
return false;
}
// Cancel work
public virtual void Cancel()
{
}
}
}
@@ -1,5 +1,7 @@
using BrewMonster;
using BrewMonster.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using PerfectWorld.Scripts.Player;
using System;
@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
using UnityEngine;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts.Managers
{
public static class EC_Inventory
@@ -7,7 +7,7 @@ using BrewMonster.Network;
using BrewMonster;
using ModelRenderer.Scripts.GameData;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts.Managers
{
public class EC_InventoryUI : MonoBehaviour
{
@@ -8,7 +8,7 @@ using ModelRenderer.Scripts.Common;
using ModelRenderer.Scripts.GameData;
using UnityEngine;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts.Managers
{
public class InventoryItemData
{
@@ -3,7 +3,7 @@ using UnityEngine;
using ModelRenderer.Scripts.GameData;
using BrewMonster;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts.Managers
{
public enum IndexOfIteminEquipmentInventory : byte
{
@@ -52,6 +52,7 @@ namespace PerfectWorld.Scripts.Managers
break;
}
case int value when value == EC_MsgDef.MSG_PM_FACTION_PVP_MASK_MODIFY:
case int value1 when value1 == EC_MsgDef.MSG_PM_PLAYERATKRESULT:
Debug.Log("EC_MsgDef.MSG_PM_FACTION_PVP_MASK_MODIFY");
TransmitMessage(Msg);
break;
@@ -437,7 +438,10 @@ namespace PerfectWorld.Scripts.Managers
else
cid = ((cmd_object_landing)msg.dwParam1).object_id;
break;*/
case long value when value == EC_MsgDef.MSG_PM_PLAYERATKRESULT:
cmd_object_atk_result pCmdAtk = GPDataTypeHelper.FromBytes<cmd_object_atk_result>((byte[])msg.dwParam1);
cid = pCmdAtk.attacker_id;
break;
// ⚠️ Các case khác cũng tương tự, chỉ việc lấy ra đúng trường id / caster / user ...
// Do quá dài nên bạn có thể copy dần từng case từ C++ sang.
@@ -446,7 +450,7 @@ namespace PerfectWorld.Scripts.Managers
return false;
}
/* if (cid == 0)
if (cid == 0)
{
System.Diagnostics.Debug.Assert(false, "cid = 0");
return false;
@@ -461,7 +465,7 @@ namespace PerfectWorld.Scripts.Managers
var elsePlayer = SeekOutElsePlayer(cid);
if (elsePlayer != null)
elsePlayer.ProcessMessage(msg);
}*/
}
return true;
}
@@ -1,4 +1,5 @@
using BrewMonster;
using BrewMonster.Managers;
using CSNetwork.GPDataType;
using CSNetwork.Protocols;
using UnityEngine;
@@ -1,64 +1,67 @@
using UnityEngine;
public class CECObjectWork
namespace BrewMonster.Scripts
{
// 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)
public class CECObjectWork
{
m_iWorkID = iWorkID;
m_bFinished = false;
m_dwMask = 0;
m_dwTransMask = 0;
m_bFinished = true;
}
public virtual bool Tick(float dwDeltaTime)
{
if (m_bFirstTick)
// 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_bFirstTick = false;
OnFirstTick();
m_iWorkID = iWorkID;
m_bFinished = false;
m_dwMask = 0;
m_dwTransMask = 0;
m_bFinished = true;
}
return 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() { }
}
// 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,99 @@
using CSNetwork.GPDataType;
using UnityEngine;
namespace BrewMonster.Scripts.Ornament
{
public class CECOrnamentMan
{
CECBrushMan m_pBrushMan;
// Trace for CD
public virtual bool TraceWithBrush(ref BrushTraceInfo pInfo)
{
bool bCollide = false;
//TO DO: fix later
//save original result
//bool bStartSolid = pInfo.bStartSolid; // Collide something at start point
//bool bAllSolid = pInfo.bAllSolid; // All in something
//int iClipPlane = pInfo.iClipPlane; // Clip plane's index
//float fFraction = 100.0f; // Fraction
//A3DVECTOR3 vNormal = pInfo.ClipPlane.GetNormal(); //clip plane normal
//float fDist = pInfo.ClipPlane.GetDist(); //clip plane dist
//if (m_pBrushMan != null && m_pBrushMan.Trace(pInfo)
// && (pInfo.fFraction < fFraction))
//{
// fFraction = pInfo.fFraction;
// bAllSolid = pInfo.bAllSolid;
// bStartSolid = pInfo.bStartSolid;
// iClipPlane = pInfo.iClipPlane;
// vNormal = pInfo.ClipPlane.GetNormal();
// fDist = pInfo.ClipPlane.GetDist();
// bCollide = true;
//}
//HomeOnmtTable::iterator it1 = m_HomeOrnamentTab.begin();
//for (; it1 != m_HomeOrnamentTab.end(); ++it1)
//{
// CECHomeOrnament* pHomeOrnament = *it1.value();
// if (!pHomeOrnament.IsLoaded())
// continue;
// CELBuildingWithBrush* pBuildingWithBrush = pHomeOrnament.GetBuildingWithBrush();
// if (pBuildingWithBrush && pBuildingWithBrush.TraceWithBrush(pInfo) && (pInfo.fFraction < fFraction))
// {
// fFraction = pInfo.fFraction;
// bAllSolid = pInfo.bAllSolid;
// bStartSolid = pInfo.bStartSolid;
// iClipPlane = pInfo.iClipPlane;
// vNormal = pInfo.ClipPlane.GetNormal();
// fDist = pInfo.ClipPlane.GetDist();
// bCollide = true;
// }
//}
//// now see if collide with forest
//CELForest* pForest = g_pGame.GetGameRun().GetWorld().GetForest();
//if ((fFraction > 0.0f) && pForest
// && pForest.TraceWithBrush(pInfo)
// && (pInfo.fFraction < fFraction))
//{
// fFraction = pInfo.fFraction;
// bAllSolid = pInfo.bAllSolid;
// bStartSolid = pInfo.bStartSolid;
// iClipPlane = pInfo.iClipPlane;
// vNormal = pInfo.ClipPlane.GetNormal();
// fDist = pInfo.ClipPlane.GetDist();
// bCollide = true;
//}
//// now see if collide with dynamic scene building
//ECModelTable::iterator it = m_ECModelTab.begin();
//for (; it != m_ECModelTab.end(); ++it)
//{
// ECMODELNODE* pNode = *it.value();
// if ((fFraction > 0.0f) && pNode
// && pNode.TraceWithBrush(pInfo)
// && (pInfo.fFraction < fFraction))
// {
// fFraction = pInfo.fFraction;
// bAllSolid = pInfo.bAllSolid;
// bStartSolid = pInfo.bStartSolid;
// iClipPlane = pInfo.iClipPlane;
// vNormal = pInfo.ClipPlane.GetNormal();
// fDist = pInfo.ClipPlane.GetDist();
// bCollide = true;
// }
//}
////set back
//pInfo.fFraction = fFraction;
//pInfo.bStartSolid = bStartSolid;
//pInfo.bAllSolid = bAllSolid;
//pInfo.iClipPlane = iClipPlane;
//pInfo.ClipPlane.SetNormal(vNormal);
//pInfo.ClipPlane.SetD(fDist);
return bCollide;
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 90848592c1c53d04e87291f2c1bfafdb
@@ -0,0 +1,6 @@
using UnityEngine;
//public class CECWorld
//{
//}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 4f8b18d59a72e044fbcf236fe5b2991c
@@ -0,0 +1,166 @@
using CSNetwork.GPDataType;
using System;
using UnityEngine;
using UnityEngine.UIElements;
namespace BrewMonster.Scripts
{
public class CHalfSpace
{
public static float DistThresh; //空间一顶点到halfspace平面的距离阈值,作为判断是在半空间内部、外部,or 边界上
//该阈值属于整个类而不是某一个对象,因此定义为静态成员
//根据三个顶点构造平面及半空间区域
//Attributes
public const float HS_DEFAULT_DISTTHRESH = 0.000001f; //距离差的阈值,作为判断是在半空间内部or边界上
protected A3DVECTOR3 m_vNormal;
protected float m_d;
public void Set(A3DVECTOR3 v1, A3DVECTOR3 v2)
{
m_vNormal = A3DVECTOR3.CrossProduct(v2 - v1, new A3DVECTOR3(0.0f, 0.0f, 1.0f));
m_vNormal.Normalize();
m_d = A3DVECTOR3.DotProduct(v1, m_vNormal);
}
public void Set(A3DVECTOR3 v1, A3DVECTOR3 v2, A3DVECTOR3 v3)
{
m_vNormal = A3DVECTOR3.CrossProduct(v2 - v1, v3 - v1);
m_vNormal.Normalize();
m_d = A3DVECTOR3.DotProduct(v1, m_vNormal);
}
//直接设置法向
public void SetNormal(A3DVECTOR3 n) { m_vNormal = n; m_vNormal.Normalize(); }
public float GetDist() { return m_d; }
//直接设置距离d
public void SetD(float d) { m_d = d; }
public CHalfSpace(A3DVECTOR3 v1, A3DVECTOR3 v2, A3DVECTOR3 v3)
{
Set(v1, v2, v3);
}
//根据两个顶点构造平行于Z轴的平面及半空间区域
public CHalfSpace(A3DVECTOR3 v1, A3DVECTOR3 v2)
{
Set(v1, v2);
}
public CHalfSpace()
{
}
public CHalfSpace(CHalfSpace hs)
{
m_vNormal = hs.m_vNormal;
m_d = hs.m_d;
}
// 对决定Halfspace的平面进行变换!变换矩阵为mtxTrans
public virtual void Transform(A3DMATRIX4 mtxTrans)
{
//从mtxTrans分解出Scale,Rotate,Translate分量
A3DVECTOR3 vTranslate = mtxTrans.GetRow(3);
float fScale = mtxTrans.GetCol(0).Magnitude();
// 与mtxTrans一样,仍定义为右乘矩阵
A3DMATRIX3 mtx3Rotate = new A3DMATRIX3();
mtx3Rotate.m = new float[3 * 3];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
mtx3Rotate.m[(i * 3) + j] = mtxTrans.m[(i * 4) + j] / fScale;
//对于平面方程N.X=D的变换(s,R,t)如下:
// N'=NR
SetNormal(m_vNormal * mtx3Rotate);
//D'=s*D+N'.t
SetD(fScale * m_d + A3DVECTOR3.DotProduct(m_vNormal, vTranslate));
}
public void Translate(float Delta) { m_d += Delta; } //沿法线方向作一个平移
public void Inverse() { m_d = -m_d; m_vNormal = -m_vNormal; } //翻转半空间的正反方向
//点v到半空间定义平面的距离,此距离带符号!
public float DistV2Plane(A3DVECTOR3 v)
{
float d = A3DVECTOR3.DotProduct(v, m_vNormal);
return (d - m_d);
}
//与线段求交
public int IntersectLineSeg(A3DVECTOR3 v1, A3DVECTOR3 v2, A3DVECTOR3 vIntersection)
{
vIntersection = new A3DVECTOR3(0.0f, 0.0f, 0.0f);
//先处理在平面上的情况
bool v1InPlane = OnPlane(v1);
bool v2InPlane = OnPlane(v2);
if (v1InPlane && v2InPlane) return 3;
if (v1InPlane) return 1;
if (v2InPlane) return 2;
if (Outside(v1) ^ Outside(v2))
{
//两顶点分别在两侧,计算交点
A3DVECTOR3 vd = v2 - v1;
float t = m_d - A3DVECTOR3.DotProduct(m_vNormal, v1);
t /= A3DVECTOR3.DotProduct(m_vNormal, vd);
//assert(t < 1.0f && t > 0.0f);
vIntersection = v1 + t * vd;
return 4;
}
else
return 0;
}
////////////////////////////////////////////////////////////
// 判断一个三维点是否处于半空间内部,或者说处于平面的一侧
// 注意halfspace的OutSide,Inside定义方式
// /\
// /||\
// ||
// || normal (Outside)
//------------------------------------------Plane
// (Inside)
//
public bool Inside(A3DVECTOR3 v)
{
float d = A3DVECTOR3.DotProduct(v, m_vNormal);
bool bInside = (m_d - d > DistThresh);
return (bInside);
}
public bool Outside(A3DVECTOR3 v)
{
float d = A3DVECTOR3.DotProduct(v, m_vNormal);
bool bOutside = (d - m_d > DistThresh);
return (bOutside);
}
public bool OnPlane(A3DVECTOR3 v)
{
float d = A3DVECTOR3.DotProduct(v, m_vNormal);
bool bOnPlane = (Math.Abs(m_d - d) <= DistThresh);
return bOnPlane;
}
//set && get operations
public static void SetDistThresh(float DThresh = HS_DEFAULT_DISTTHRESH) //并设定一个缺省值
{
DistThresh = DThresh;
}
public A3DVECTOR3 GetNormal() { return m_vNormal; }
//点法式
public void SetNV(A3DVECTOR3 n, A3DVECTOR3 v)
{
m_vNormal = n;
m_vNormal.Normalize();
m_d = A3DVECTOR3.DotProduct(m_vNormal, v);
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 495f51cd9612ff441a012f1aea98974d
@@ -1,6 +1,6 @@
using UnityEngine;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts.Managers
{
public class NPCManager : MonoBehaviour
{
@@ -0,0 +1,67 @@
using CSNetwork.GPDataType;
using BrewMonster.Scripts.Player;
using PerfectWorld.Scripts.Player;
namespace BrewMonster.Scripts
{
//////////////////////////////////////////////////////////////////////////
// define a new compact Convex Hull data type which is used in ElementClient!
//////////////////////////////////////////////////////////////////////////
public class BrushTraceInfo
{
//////////////////////////////////////////////////////////////////////////
// In
//////////////////////////////////////////////////////////////////////////
// aabb's info
public A3DVECTOR3 vStart; // Start point
public A3DVECTOR3 vDelta; // Move delta
public A3DVECTOR3 vExtents;
public A3DAABB BoundAABB;
// Dist Epsilon
public float fDistEpsilon; // Dist Epsilon
public bool bIsPoint; //raytrace
//////////////////////////////////////////////////////////////////////////
// Out
//////////////////////////////////////////////////////////////////////////
public bool bStartSolid; // Collide something at start point
public bool bAllSolid; // All in something
public CHalfSpace ClipPlane; // Clip plane
public int iClipPlane; // Clip plane's index
public float fFraction; // Fraction
public uint dwUser1; // User defined data 1
public uint dwUser2; // User defined data 2
public void Init(A3DVECTOR3 start, A3DVECTOR3 delta, A3DVECTOR3 ext, bool bRay = false, float epsilon = 0.03125f)
{
vStart = start;
vDelta = delta;
vExtents = ext;
fDistEpsilon = epsilon;
fFraction = 100.0f;
bIsPoint = bRay;
bStartSolid = false;
bAllSolid = false;
dwUser1 = 0;
dwUser2 = 0;
if (!bIsPoint)
{
BoundAABB.Clear();
BoundAABB.AddVertex(vStart);
BoundAABB.AddVertex(vStart + vExtents);
BoundAABB.AddVertex(vStart - vExtents);
BoundAABB.AddVertex(vStart + vDelta);
BoundAABB.AddVertex(vStart + vDelta + vExtents);
BoundAABB.AddVertex(vStart + vDelta - vExtents);
BoundAABB.CompleteCenterExts();
}
else
{
//@note : it cheats the caller. By Kuiwu[25/8/2005]
//@todo : refine me. By Kuiwu[25/8/2005]
fDistEpsilon = 1E-5f;
}
}
};
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 2ac2c48a14ff7e1478eb76c24ead3cc3
@@ -1,4 +1,5 @@
using BrewMonster.Network;
using BrewMonster.Scripts;
using CSNetwork;
using CSNetwork.C2SCommand;
using CSNetwork.GPDataType;
@@ -1,6 +1,7 @@
using Animancer;
using Animancer.Editor;
using BrewMonster;
using BrewMonster.Managers;
using BrewMonster.Scripts.Managers;
using CSNetwork.GPDataType;
using ModelRenderer.Scripts.GameData;
using PerfectWorld.Scripts.Managers;
+513 -204
View File
@@ -1,251 +1,560 @@
using CSNetwork.GPDataType;
using BrewMonster.Scripts.Ornament;
using BrewMonster.Scripts.Player;
using BrewMonster.Scripts.World;
using CSNetwork.GPDataType;
using System;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
public static class EC_CDR
using WORD = System.UInt16;
namespace BrewMonster.Scripts
{
// Cho phép CECHostMove gán mask theo scene (giữ linh hoạt nhưng không phá cấu trúc)
public static LayerMask BrushMask { get; set; } = ~0;
public static LayerMask TerrainMask { get; set; } = ~0;
static LayerMask UsedMask_Ground() => BrushMask | TerrainMask;
// == Thay CollideWithEnv (C++) bằng BoxCast ==
static bool CollideWithEnv_BoxCast(Vector3 vStart, Vector3 vDelta, Vector3 vExt,
LayerMask mask,
out RaycastHit hit, out float fFraction, out Vector3 vHitNormal, out bool bStartSolid,
float skin = 0.01f)
public static class EC_CDR
{
hit = default;
vHitNormal = Vector3.up;
bStartSolid = false;
fFraction = 1.0f;
// Cho phép CECHostMove gán mask theo scene (giữ linh hoạt nhưng không phá cấu trúc)
public static LayerMask BrushMask { get; set; } = ~0;
public static LayerMask TerrainMask { get; set; } = ~0;
float dist = vDelta.magnitude;
if (dist <= 1e-6f) return false;
// start-in-solid
var overlapped = Physics.OverlapBox(vStart, vExt - Vector3.one * skin, Quaternion.identity, mask, QueryTriggerInteraction.Ignore);
if (overlapped != null && overlapped.Length > 0)
const float LOCAL_EPSILON = 1e-5f;
//[Flags]
public class CDR_EVN
{
bStartSolid = true;
return true;
public const int CDR_BRUSH = 0x1,
CDR_TERRAIN = 0x2,
CDR_WATER = 0x4;
}
// sweep AABB
Vector3 dir = vDelta / Mathf.Max(dist, 1e-6f);
if (Physics.BoxCast(vStart, vExt - Vector3.one * skin, dir, out hit, Quaternion.identity, dist, mask, QueryTriggerInteraction.Ignore))
static LayerMask UsedMask_Ground() => BrushMask | TerrainMask;
static bool CollideWithEnv(env_trace_t pEnvTrc)
{
fFraction = Mathf.Clamp01(hit.distance / Mathf.Max(dist, 1e-6f));
vHitNormal = hit.normal;
return true;
}
return false;
}
// == Thay RetrieveSupportPlane (C++) bằng Raycast xuống ==
static bool DoGroundProbe(Vector3 vStart, Vector3 vExt, float fDeltaY, LayerMask mask,
out Vector3 vEnd, out Vector3 vHitNormal, out bool bSupport,
float skin = 0.01f)
{
vEnd = vStart;
vHitNormal = Vector3.up;
bSupport = false;
float dist = Mathf.Max(fDeltaY, 0f) + vExt.y + skin + 0.05f;
Vector3 origin = vStart + Vector3.up * 0.05f;
if (Physics.Raycast(origin, Vector3.down, out RaycastHit hit, dist, mask, QueryTriggerInteraction.Ignore))
{
vHitNormal = hit.normal;
vEnd = new Vector3(vStart.x, hit.point.y + vExt.y + skin, vStart.z);
bSupport = (vHitNormal.y >= 0f);
return true;
}
return true; // không thấy ground → bSupport=false
}
// ======= STATIC OnGroundMove GIỮ NGUYÊN VAI TRÒ TOÀN CỤC (C API) =======
public static void OnGroundMove(ref CDR_INFO CDRInfo)
{
const float VEL_EPSILON = 1e-4f;
const float DIST_EPSILON = 1e-4f;
const float NORMAL_EPSILON = 1e-2f;
const float VEL_MAX_SPEED = 200f;
const float VEL_REFLECT = 0.3f;
CDRInfo.fMoveDist = 0.0f;
bool bFreeFall = (CDRInfo.vTPNormal.y < CDRInfo.fSlopeThresh);
if (Mathf.Abs(CDRInfo.fYVel) < VEL_EPSILON && Mathf.Abs(CDRInfo.fSpeed) < VEL_EPSILON && !bFreeFall)
return;
float fYVel = CDRInfo.fYVel;
bool bJump = (fYVel > 0.5f);
Vector3 vVelocity = CDRInfo.fSpeed * new Vector3(CDRInfo.vXOZVelDir.x, 0f, CDRInfo.vXOZVelDir.z) + fYVel * Vector3.up;
if (bFreeFall)
{
vVelocity += -CDRInfo.fGravityAccel * CDRInfo.t * Vector3.up;
fYVel += -CDRInfo.fGravityAccel * CDRInfo.t;
}
Vector3 vVelDir = vVelocity;
float fVelSpeed = vVelDir.magnitude;
if (fVelSpeed > 1e-6f) vVelDir /= fVelSpeed; else vVelDir = Vector3.zero;
if (!bFreeFall) fVelSpeed = Mathf.Min(fVelSpeed, VEL_MAX_SPEED);
vVelocity = vVelDir * fVelSpeed;
float dtp = Vector3.Dot(vVelDir, CDRInfo.vTPNormal);
if (dtp < 0f || !bJump)
{
vVelocity = (vVelDir - CDRInfo.vTPNormal * dtp - CDRInfo.vTPNormal * dtp * 0.01f) * fVelSpeed;
}
CDRInfo.vAbsVelocity = vVelocity;
Vector3 vStart = CDRInfo.vCenter;
Vector3 vExt = CDRInfo.vExtent;
float fTime = CDRInfo.t;
Vector3 vDelta, vNormal = Vector3.up, vFinalPos = vStart;
bool bPull = false;
bool bTryPull = false;
int nTry = 0;
LayerMask mask = UsedMask_Ground();
while (nTry < 4)
{
vDelta = vVelocity * fTime;
float fDeltaDist = vDelta.magnitude;
if (fDeltaDist < DIST_EPSILON) break;
bool hasHit = CollideWithEnv_BoxCast(vStart, vDelta, vExt, mask,
out RaycastHit hit, out float fFraction, out Vector3 hitNormal, out bool bStartSolid);
nTry++;
if (bStartSolid)
pEnvTrc.fFraction = 100.0f;
pEnvTrc.bStartSolid = false;
pEnvTrc.dwClsFlag = 0;
if ((pEnvTrc.dwCheckFlag & CDR_EVN.CDR_BRUSH) == CDR_EVN.CDR_BRUSH)
{
CDRInfo.fMoveDist = 0f;
if (CDRInfo.vTPNormal.y < CDRInfo.fSlopeThresh) CDRInfo.vTPNormal = Vector3.up;
BrushTraceInfo bruInfo = new BrushTraceInfo();
bruInfo.Init(pEnvTrc.vStart, pEnvTrc.vDelta, pEnvTrc.vExt);
if (AABBCollideWithBrush(ref bruInfo))
{
pEnvTrc.fFraction = bruInfo.fFraction;
pEnvTrc.vHitNormal = bruInfo.ClipPlane.GetNormal();
pEnvTrc.bStartSolid = bruInfo.bStartSolid;
pEnvTrc.dwClsFlag = CDR_EVN.CDR_BRUSH;
}
}
if ((pEnvTrc.dwCheckFlag & CDR_EVN.CDR_TERRAIN) == CDR_EVN.CDR_TERRAIN)
{
float fFraction = 0f;
A3DVECTOR3 vTerNormal = new A3DVECTOR3();
bool bStart = false;
if (CollideWithTerrain(pEnvTrc.vTerStart, pEnvTrc.vDelta, ref fFraction, ref vTerNormal, ref bStart)
&& (fFraction < pEnvTrc.fFraction))
{
//assert(fFraction >= 0.0f);
//pEnvTrc.fFraction = a_Max(0.0f, fFraction - 1E-4f);
pEnvTrc.fFraction = fFraction;
pEnvTrc.vHitNormal = vTerNormal;
pEnvTrc.bStartSolid = bStart;
pEnvTrc.dwClsFlag = CDR_EVN.CDR_TERRAIN;
}
}
if ((pEnvTrc.dwCheckFlag & CDR_EVN.CDR_WATER) == CDR_EVN.CDR_WATER)
{
float fFraction = 0f;
A3DVECTOR3 vWatNormal = new A3DVECTOR3();
bool bStart = false;
//@todo : TBD: use center or foot? By Kuiwu[10/10/2005]
//if (CollideWithWater(pEnvTrc.vWatStart, pEnvTrc.vDelta, pEnvTrc.bWaterSolid, ref fFraction, ref vWatNormal, ref bStart)
// && fFraction < pEnvTrc.fFraction)
//{
// pEnvTrc.fFraction = fFraction;
// pEnvTrc.vHitNormal = vWatNormal;
// pEnvTrc.bStartSolid = bStart;
// pEnvTrc.dwClsFlag = CDR_EVN.CDR_WATER;
// //# ifdef CDR_DEBUG
// // A3DVECTOR3 vHitPos(pEnvTrc.vWatStart +pEnvTrc.vDelta * fFraction);
// // sprintf(msg, "collide water, fraction %f pos %f %f %f \n", fFraction, vHitPos.x, vHitPos.y, vHitPos.z);
// // OUTPUT_DEBUG_INFO(msg);
// //#endif
//}
}
return (pEnvTrc.fFraction < 1.0f + 1E-4f);
}
// == Thay CollideWithEnv (C++) bằng BoxCast ==
static bool CollideWithEnv_BoxCast(Vector3 vStart, Vector3 vDelta, Vector3 vExt,
LayerMask mask,
out RaycastHit hit, out float fFraction, out Vector3 vHitNormal, out bool bStartSolid,
float skin = 0.01f)
{
hit = default;
vHitNormal = Vector3.up;
bStartSolid = false;
fFraction = 1.0f;
float dist = vDelta.magnitude;
if (dist <= 1e-6f) return false;
// start-in-solid
var overlapped = Physics.OverlapBox(vStart, vExt - Vector3.one * skin, Quaternion.identity, mask, QueryTriggerInteraction.Ignore);
if (overlapped != null && overlapped.Length > 0)
{
bStartSolid = true;
return true;
}
// sweep AABB
Vector3 dir = vDelta / Mathf.Max(dist, 1e-6f);
if (Physics.BoxCast(vStart, vExt - Vector3.one * skin, dir, out hit, Quaternion.identity, dist, mask, QueryTriggerInteraction.Ignore))
{
fFraction = Mathf.Clamp01(hit.distance / Mathf.Max(dist, 1e-6f));
vHitNormal = hit.normal;
return true;
}
return false;
}
// == Thay RetrieveSupportPlane (C++) bằng Raycast xuống ==
static bool DoGroundProbe(Vector3 vStart, Vector3 vExt, float fDeltaY, LayerMask mask,
out Vector3 vEnd, out Vector3 vHitNormal, out bool bSupport,
float skin = 0.01f)
{
vEnd = vStart;
vHitNormal = Vector3.up;
bSupport = false;
float dist = Mathf.Max(fDeltaY, 0f) + vExt.y + skin + 0.05f;
Vector3 origin = vStart + Vector3.up * 0.05f;
if (Physics.Raycast(origin, Vector3.down, out RaycastHit hit, dist, mask, QueryTriggerInteraction.Ignore))
{
vHitNormal = hit.normal;
vEnd = new Vector3(vStart.x, hit.point.y + vExt.y + skin, vStart.z);
bSupport = (vHitNormal.y >= 0f);
return true;
}
return true; // không thấy ground → bSupport=false
}
// ======= STATIC OnGroundMove GIỮ NGUYÊN VAI TRÒ TOÀN CỤC (C API) =======
public static void OnGroundMove(ref CDR_INFO CDRInfo)
{
const float VEL_EPSILON = 1e-4f;
const float DIST_EPSILON = 1e-4f;
const float NORMAL_EPSILON = 1e-2f;
const float VEL_MAX_SPEED = 200f;
const float VEL_REFLECT = 0.3f;
CDRInfo.fMoveDist = 0.0f;
bool bFreeFall = (CDRInfo.vTPNormal.y < CDRInfo.fSlopeThresh);
if (Mathf.Abs(CDRInfo.fYVel) < VEL_EPSILON && Mathf.Abs(CDRInfo.fSpeed) < VEL_EPSILON && !bFreeFall)
return;
float fYVel = CDRInfo.fYVel;
bool bJump = (fYVel > 0.5f);
Vector3 vVelocity = CDRInfo.fSpeed * new Vector3(CDRInfo.vXOZVelDir.x, 0f, CDRInfo.vXOZVelDir.z) + fYVel * Vector3.up;
if (bFreeFall)
{
vVelocity += -CDRInfo.fGravityAccel * CDRInfo.t * Vector3.up;
fYVel += -CDRInfo.fGravityAccel * CDRInfo.t;
}
if (!hasHit)
Vector3 vVelDir = vVelocity;
float fVelSpeed = vVelDir.magnitude;
if (fVelSpeed > 1e-6f) vVelDir /= fVelSpeed; else vVelDir = Vector3.zero;
if (!bFreeFall) fVelSpeed = Mathf.Min(fVelSpeed, VEL_MAX_SPEED);
vVelocity = vVelDir * fVelSpeed;
float dtp = Vector3.Dot(vVelDir, CDRInfo.vTPNormal);
if (dtp < 0f || !bJump)
{
vFinalPos = vStart + vDelta;
CDRInfo.fMoveDist += fDeltaDist;
break;
vVelocity = (vVelDir - CDRInfo.vTPNormal * dtp - CDRInfo.vTPNormal * dtp * 0.01f) * fVelSpeed;
}
vStart += vDelta * fFraction;
CDRInfo.fMoveDist += (fDeltaDist * fFraction);
fTime -= fTime * fFraction;
vNormal = hitNormal;
CDRInfo.vAbsVelocity = vVelocity;
// Step-up (giữ tinh thần bản gốc)
if (!bFreeFall && !bTryPull && !bJump)
Vector3 vStart = CDRInfo.vCenter;
Vector3 vExt = CDRInfo.vExtent;
float fTime = CDRInfo.t;
Vector3 vDelta, vNormal = Vector3.up, vFinalPos = vStart;
bool bPull = false;
bool bTryPull = false;
int nTry = 0;
LayerMask mask = UsedMask_Ground();
while (nTry < 4)
{
float skin = 0.01f;
Vector3 vStartUp = vStart + new Vector3(0f, CDRInfo.fStepHeight, 0f);
bool upBlocked = Physics.CheckBox(vStartUp, vExt - Vector3.one * skin, Quaternion.identity, mask, QueryTriggerInteraction.Ignore);
if (!upBlocked)
vDelta = vVelocity * fTime;
float fDeltaDist = vDelta.magnitude;
if (fDeltaDist < DIST_EPSILON) break;
// TO DO: fix later beacuse logic in CollideWithEnv_BoxCast is wrong
//bool hasHit = CollideWithEnv_BoxCast(vStart, vDelta, vExt, mask,
// out RaycastHit hit, out float fFraction, out Vector3 hitNormal, out bool bStartSolid);
bool hasHit = false, bStartSolid = false;
float fFraction = 0f;
Vector3 hitNormal = Vector3.zero;
nTry++;
if (bStartSolid)
{
Vector3 vDelta2 = vVelocity;
bool hasHit2 = CollideWithEnv_BoxCast(vStartUp, vDelta2, vExt, mask,
out RaycastHit hit2, out float frac2, out Vector3 hitNormal2, out bool bStartSolid2);
if (hasHit2) vDelta2 *= frac2;
CDRInfo.fMoveDist = 0f;
if (CDRInfo.vTPNormal.y < CDRInfo.fSlopeThresh) CDRInfo.vTPNormal = Vector3.up;
return;
}
if (vDelta2.sqrMagnitude >= (vExt.x * vExt.x * 4f))
if (!hasHit)
{
vFinalPos = vStart + vDelta;
CDRInfo.fMoveDist += fDeltaDist;
break;
}
vStart += vDelta * fFraction;
CDRInfo.fMoveDist += (fDeltaDist * fFraction);
fTime -= fTime * fFraction;
vNormal = hitNormal;
// Step-up (giữ tinh thần bản gốc)
if (!bFreeFall && !bTryPull && !bJump)
{
float skin = 0.01f;
Vector3 vStartUp = vStart + new Vector3(0f, CDRInfo.fStepHeight, 0f);
bool upBlocked = Physics.CheckBox(vStartUp, vExt - Vector3.one * skin, Quaternion.identity, mask, QueryTriggerInteraction.Ignore);
if (!upBlocked)
{
vStart = vStartUp;
vDelta = vDelta2;
Vector3 vDelta2 = vVelocity;
bool hasHit2 = CollideWithEnv_BoxCast(vStartUp, vDelta2, vExt, mask,
out RaycastHit hit2, out float frac2, out Vector3 hitNormal2, out bool bStartSolid2);
if (hasHit2) vDelta2 *= frac2;
float distAll = vVelocity.magnitude;
float distMoved = vDelta.magnitude;
if (distAll > 1e-6f) fTime *= Mathf.Clamp01(distMoved / Mathf.Max(distAll, 1e-6f));
if (vDelta2.sqrMagnitude >= (vExt.x * vExt.x * 4f))
{
vStart = vStartUp;
vDelta = vDelta2;
bPull = true;
float distAll = vVelocity.magnitude;
float distMoved = vDelta.magnitude;
if (distAll > 1e-6f) fTime *= Mathf.Clamp01(distMoved / Mathf.Max(distAll, 1e-6f));
bPull = true;
}
}
bTryPull = true;
}
if (!bPull)
{
if (vVelocity.sqrMagnitude > 1e-12f)
{
vVelDir = vVelocity.normalized;
fVelSpeed = vVelocity.magnitude * (1f - nTry * 0.1f);
dtp = Vector3.Dot(vNormal, vVelDir);
float fRelSpeed = Mathf.Min(fVelSpeed, 5.0f);
if (dtp >= 0f && dtp < 1e-4f)
{
vVelocity += vNormal * VEL_REFLECT * fRelSpeed;
}
else
{
vVelocity = (vVelDir - vNormal * dtp) * fVelSpeed - vNormal * dtp * VEL_REFLECT * fRelSpeed;
}
}
if (fYVel > VEL_EPSILON)
{
if (vNormal.y >= CDRInfo.fSlopeThresh || vNormal.y < -NORMAL_EPSILON) fYVel = 0f;
}
else if (fYVel < -VEL_EPSILON)
{
if (vNormal.y >= CDRInfo.fSlopeThresh) fYVel = 0f;
}
}
bTryPull = true;
}
if (!bPull)
// “vertical ground trace” thay RetrieveSupportPlane
Vector3 vTPNormal = Vector3.zero;
Vector3 vFinal = vFinalPos;
float downDist = 0.3f;
if (bPull) downDist = CDRInfo.fStepHeight + 0.1f;
if (bJump) downDist = 0.0f;
if (downDist > 0f)
{
if (vVelocity.sqrMagnitude > 1e-12f)
if (!DoGroundProbe(vFinalPos, vExt, downDist, mask, out Vector3 vEnd, out Vector3 groundNormal, out bool bSupport))
{
vVelDir = vVelocity.normalized;
fVelSpeed = vVelocity.magnitude * (1f - nTry * 0.1f);
dtp = Vector3.Dot(vNormal, vVelDir);
float fRelSpeed = Mathf.Min(fVelSpeed, 5.0f);
if (dtp >= 0f && dtp < 1e-4f)
{
vVelocity += vNormal * VEL_REFLECT * fRelSpeed;
}
else
{
vVelocity = (vVelDir - vNormal * dtp) * fVelSpeed - vNormal * dtp * VEL_REFLECT * fRelSpeed;
}
CDRInfo.fMoveDist = 0f;
CDRInfo.vTPNormal = Vector3.up;
return;
}
if (fYVel > VEL_EPSILON)
if (bSupport)
{
if (vNormal.y >= CDRInfo.fSlopeThresh || vNormal.y < -NORMAL_EPSILON) fYVel = 0f;
}
else if (fYVel < -VEL_EPSILON)
{
if (vNormal.y >= CDRInfo.fSlopeThresh) fYVel = 0f;
vFinal = vEnd;
if (!bJump) vTPNormal = groundNormal;
}
}
if ((vTPNormal.y >= CDRInfo.fSlopeThresh && fYVel < 0.0f) || (!bJump && fYVel > 0.0f))
fYVel = 0.0f;
CDRInfo.vCenter = vFinal;
CDRInfo.fYVel = fYVel;
if (vTPNormal != Vector3.zero) CDRInfo.vTPNormal = vTPNormal;
}
// “vertical ground trace” thay RetrieveSupportPlane
Vector3 vTPNormal = Vector3.zero;
Vector3 vFinal = vFinalPos;
float downDist = 0.3f;
if (bPull) downDist = CDRInfo.fStepHeight + 0.1f;
if (bJump) downDist = 0.0f;
if (downDist > 0f)
static bool SegmentTriangleIntersect(A3DVECTOR3 vStart, A3DVECTOR3 vDelta, A3DVECTOR3[] vert, ref float fFraction, bool bCull)
{
if (!DoGroundProbe(vFinalPos, vExt, downDist, mask, out Vector3 vEnd, out Vector3 groundNormal, out bool bSupport))
float dist = 0f;
A3DVECTOR3 vDir = new A3DVECTOR3(vDelta);
dist = vDir.Normalize();
if (dist < 1E-5f)
{
CDRInfo.fMoveDist = 0f;
CDRInfo.vTPNormal = Vector3.up;
return;
//assert(0 && "too small dist!");
fFraction = 0.0f;
return true;
}
if (bSupport)
float t = 0f, u = 0f, v = 0f;
if (RayTriangleIntersect(vStart, vDir, vert, ref t, ref u, ref v, bCull) && (t >= 0.0f) && (t <= dist))
{
vFinal = vEnd;
if (!bJump) vTPNormal = groundNormal;
//fFraction = t/dist;
//fFraction = a_Max( 0.0f, fFraction -1E-4f); //put back
fFraction = (t - 5E-4f) / dist;
AAssist.a_ClampFloor(ref fFraction, 0.0f);
return true;
}
return false;
}
if ((vTPNormal.y >= CDRInfo.fSlopeThresh && fYVel < 0.0f) || (!bJump && fYVel > 0.0f))
fYVel = 0.0f;
/*
* ray: origin + t* dir, triangle: p(u,v) = (1-u -v)vert[0] + u*vert[1] + v*vert[2]
* @desc :
* @param vDir: normalized direction
* @param bCull: cull back face if true
* @return :
* @note:
* @todo:
* @author: kuiwu [8/10/2005]
* @ref: Tomas Moller's JGT code
*/
static bool RayTriangleIntersect(A3DVECTOR3 vOrigin, A3DVECTOR3 vDir, A3DVECTOR3[] vert, ref float t, ref float u, ref float v, bool bCull)
{
// find vectors for two edges sharing vert0
A3DVECTOR3 edge1 = vert[1] - vert[0];
A3DVECTOR3 edge2 = vert[2] - vert[0];
// begin calculating determinant - also used to calculate U parameter
A3DVECTOR3 pvec = A3DVECTOR3.CrossProduct(vDir, edge2);
// if determinant is near zero, ray lies in plane of triangle
float det = A3DVECTOR3.DotProduct(edge1, pvec);
if (bCull)
{
if (det < LOCAL_EPSILON)
return false;
// From here, det is > 0.
// Calculate distance from vert0 to ray origin
A3DVECTOR3 tvec = vOrigin - vert[0];
// Calculate U parameter and test bounds
u = A3DVECTOR3.DotProduct(tvec, pvec);
if ((u < 0.0f) || (u > det))
return false;
CDRInfo.vCenter = vFinal;
CDRInfo.fYVel = fYVel;
if (vTPNormal != Vector3.zero) CDRInfo.vTPNormal = vTPNormal;
// prepare to test V parameter
A3DVECTOR3 qvec = A3DVECTOR3.CrossProduct(tvec, edge1);
// calculate V parameter and test bounds
v = A3DVECTOR3.DotProduct(vDir, qvec);
if ((v < 0.0f) || (u + v > det))
return false;
// calculate t, ray intersects triangle
t = A3DVECTOR3.DotProduct(edge2, qvec);
// Det > 0 so we can early exit here
// Intersection point is valid if distance is positive
// (else it can just be a face behind the orig point)
if (t < 0.0f)
{
return false;
}
float OneOverDet = 1.0f / det;
t *= OneOverDet;
u *= OneOverDet;
v *= OneOverDet;
}
else
{
if (det > -LOCAL_EPSILON && det < LOCAL_EPSILON)
return false;
float OneOverDet = 1.0f / det;
// Calculate distance from vert0 to ray origin
A3DVECTOR3 tvec = vOrigin - vert[0];
// calculate U parameter and test bounds
u = A3DVECTOR3.DotProduct(tvec, pvec) * OneOverDet;
if ((u < 0.0f) || (u > 1.0f))
return false;
// prepare to test V parameter
A3DVECTOR3 qvec = A3DVECTOR3.CrossProduct(tvec, edge1);
// calculate V parameter and test bounds
v = A3DVECTOR3.DotProduct(vDir, qvec) * OneOverDet;
if ((v < 0.0f) || (u + v > 1.0f))
return false;
// calculate t, ray intersects triangle
t = A3DVECTOR3.DotProduct(edge2, qvec) * OneOverDet;
}
return true;
}
public static bool CollideWithTerrain(A3DVECTOR3 vStart, A3DVECTOR3 vDelta, ref float fFraction, ref A3DVECTOR3 vHitNormal, ref bool bStart)
{
CECWorld pWorld = CECWorld.Instance; //g_pGame.GetGameRun().GetWorld();
A3DTerrain2 pTerrain = pWorld.GetTerrain();
bStart = false;
float h1 = pTerrain.GetPosHeight(vStart, ref vHitNormal);
if (h1 > vStart.y + 1E-4f)
{//start under terrain
bStart = true;
fFraction = 0.0f;
return true;
}
int nWid, nHei; // in grid, 2 meters
float fMag = vDelta.Magnitude();
nWid = (int)Math.Ceiling(fMag / 2.0f);
nWid = Math.Max(3, nWid);
nHei = nWid;
int nTriangles = nWid * nHei * 2;
A3DVECTOR3[] pVerts = new A3DVECTOR3[(nWid + 1) * (nHei + 1)];
//assert(pVerts != NULL);
//memset(pVerts, 0, sizeof(A3DVECTOR3)* (nWid + 1) * (nHei + 1));
WORD[] pIndices = new WORD[nTriangles * 3];
//assert(pIndices != NULL);
//memset(pIndices, 0, sizeof(WORD)* nTriangles * 3);
if (!pTerrain.GetFacesOfArea(vStart, nWid, nHei, ref pVerts, ref pIndices))
{
//a_freetemp(pVerts);
// a_freetemp(pIndices);
return false;
}
int i;
A3DVECTOR3[] vert = new A3DVECTOR3[3];
//@note : Here init the fraction. By Kuiwu[9/10/2005]
fFraction = 100.0f;
float tmpFraction = fFraction;
for (i = 0; i < nTriangles; i++)
{
vert[0] = pVerts[pIndices[i * 3]];
vert[1] = pVerts[pIndices[i * 3 + 1]];
vert[2] = pVerts[pIndices[i * 3 + 2]];
//A3DVECTOR3 vPt;
//@note: Tomas Moller's JGT code : By Kuiwu[9/10/2005]
//@note: discard the engine version because it put back the hit point too much. By Kuiwu[13/10/2005]
// if(CLS_RayToTriangle(vStart, vDelta, *vert[0], *vert[1], *vert[2], vPt, true, &tmpFraction)
// && (tmpFraction <= 1.0f) && (tmpFraction < fFraction))
if (SegmentTriangleIntersect(vStart, vDelta, vert, ref tmpFraction, true) && (tmpFraction < fFraction))
{
//get the triangle normal
A3DVECTOR3 vEdge1 = vert[1] - vert[0];
A3DVECTOR3 vEdge2 = vert[2] - vert[0];
vHitNormal = A3DVECTOR3.CrossProduct(vEdge1, vEdge2);
vHitNormal.Normalize();
//@note : may be redundant, but to assure. By Kuiwu[17/10/2005]
A3DVECTOR3 vDir = new A3DVECTOR3();
A3DVECTOR3.Normalize(vDelta, out vDir);
if (A3DVECTOR3.DotProduct(vHitNormal, vDir) > 0.01f)
{//leave the hit plane
//assert(0 && "hit a plane with same direction!");
continue;
}
fFraction = Math.Max(0.0f, tmpFraction);
}
}
//a_freetemp(pVerts);
// a_freetemp(pIndices);
return (fFraction <= 1.0f);
}
public static bool AABBCollideWithBrush(ref BrushTraceInfo pInfo)
{
//TO DO: fix later
return false;
//CECWorld pWorld = CECWorld.Instance; //g_pGame.GetGameRun().GetWorld();
//CECOrnamentMan pOrnMan = pWorld.GetOrnamentMan();
//bool bBrush = pOrnMan.TraceWithBrush(ref pInfo);
//BrushTraceInfo info = pInfo;
//CECMatterMan pMatterMan = pWorld.GetMatterMan();
//if (pMatterMan.TraceWithBrush(ref info) && info.fFraction < pInfo.fFraction)
//{
// pInfo = info;
// bBrush = true;
//}
//info = pInfo;
//CECNPCMan pNPCMan = pWorld.GetNPCMan();
//if (pNPCMan.TraceWithBrush(ref info) && info.fFraction < pInfo.fFraction)
//{
// pInfo = info;
// bBrush = true;
//}
//return bBrush;
}
}
public struct OtherPlayer_Move_Info
{
// Bounding sphere of avator
public A3DVECTOR3 vCenter;
public A3DVECTOR3 vExts;
public float fStepHeight;
public A3DVECTOR3 vVelocity;
public float t;
public bool bTraceGround; // Whether trace the ground
public bool bTestTrnOnly; // Trace terrain only
public A3DVECTOR3 vecGroundNormal; // if bTraceGround is true, this will contain the ground normal when returned
};
//@desc :used to trace the environment, brush&terrain&water By Kuiwu[8/10/2005]
public struct env_trace_t
{
public A3DVECTOR3 vStart; // brush start
public A3DVECTOR3 vExt;
public A3DVECTOR3 vDelta;
public A3DVECTOR3 vTerStart;
public A3DVECTOR3 vWatStart;
public uint dwCheckFlag;
public bool bWaterSolid;
public float fFraction;
public A3DVECTOR3 vHitNormal;
public bool bStartSolid; //start in solid
public uint dwClsFlag; //collision flag
};
}
public struct OtherPlayer_Move_Info
{
// Bounding sphere of avator
public A3DVECTOR3 vCenter;
public A3DVECTOR3 vExts;
public float fStepHeight;
public A3DVECTOR3 vVelocity;
public float t;
public bool bTraceGround; // Whether trace the ground
public bool bTestTrnOnly; // Trace terrain only
public A3DVECTOR3 vecGroundNormal; // if bTraceGround is true, this will contain the ground normal when returned
};
+2 -4
View File
@@ -1,15 +1,13 @@
using Animancer;
using BrewMonster;
using BrewMonster.Managers;
using BrewMonster.Scripts;
using CSNetwork;
using CSNetwork.GPDataType;
using ModelRenderer.Scripts.Common;
using System;
using System.IO;
using System.Text;
using Unity.VisualScripting;
using UnityEditor.Playables;
using UnityEngine;
using static CECPlayer;
public class CECNPC : CECObject
{
@@ -15,6 +15,8 @@ using System.Numerics;
using CSNetwork.C2SCommand;
using CSNetwork.GPDataType;
using BrewMonster;
using BrewMonster.Managers;
using BrewMonster.Scripts.Player;
namespace CSNetwork
{
@@ -415,12 +417,13 @@ namespace CSNetwork
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_HURTRESULT, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
break;
case CommandID.OBJECT_ATTACK_RESULT:
int id = GPDataTypeHelper.FromBytes<int>(pDataBuf);
BMLogger.LogError($"OBJECT_ATTACK_RESULT: npc ? " + ISNPCID(id));
//int id = GPDataTypeHelper.FromBytes<int>(pDataBuf);
cmd_object_atk_result pCmdAtk = GPDataTypeHelper.FromBytes<cmd_object_atk_result>(pDataBuf);
//BMLogger.LogError($"OBJECT_ATTACK_RESULT: npc ? " + ISNPCID(id));
if (ISPLAYERID(id))
if (ISPLAYERID(pCmdAtk.attacker_id))
EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_PLAYERATKRESULT, MANAGER_INDEX.MAN_PLAYER, -1, pDataBuf, pCmdHeader);
else if (ISNPCID(id))
else if (ISNPCID(pCmdAtk.attacker_id))
EC_ManMessage.PostMessage(EC_MsgDef.MSG_NM_NPCATKRESULT, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
break;
case CommandID.HOST_ATTACKRESULT:
@@ -1,12 +1,11 @@
using System;
using UnityEngine;
using CSNetwork;
using PerfectWorld.Scripts.Managers.BrewMonster.Managers;
using BrewMonster.Network;
using UnityEngine.SceneManagement;
using CSNetwork.GPDataType;
using BrewMonster.Scripts.Player;
using PerfectWorld.Scripts.Managers.BrewMonster.Managers;
namespace BrewMonster
namespace BrewMonster.Managers
{
[Serializable]
public class EC_ManMessageMono : MonoBehaviour
@@ -1,3 +1,4 @@
using BrewMonster.Scripts.Player;
using UnityEngine;
using static CECPlayer;
@@ -1,3 +1,4 @@
using BrewMonster.Scripts.Player;
using UnityEngine;
using static CECPlayer;
@@ -1,13 +1,16 @@
using UnityEngine;
public abstract class PlayerState
namespace BrewMonster.Scripts.Player
{
protected readonly CECHostPlayer _characterCtrl;
public PlayerState(CECHostPlayer characterCtrl)
public abstract class PlayerState
{
_characterCtrl = characterCtrl;
protected readonly CECHostPlayer _characterCtrl;
public PlayerState(CECHostPlayer characterCtrl)
{
_characterCtrl = characterCtrl;
}
public abstract void Enter();
public abstract void Exit();
public abstract void Update();
}
public abstract void Enter();
public abstract void Exit();
public abstract void Update();
}
@@ -1,4 +1,6 @@
using BrewMonster;
using BrewMonster.Managers;
using BrewMonster.Scripts;
using CSNetwork;
using CSNetwork.GPDataType;
using CSNetwork.Protocols.RPCData;
@@ -10,7 +12,7 @@ namespace PerfectWorld.Scripts.Player
public class EC_ElsePlayer : CECPlayer
{
A3DVECTOR3 m_vMoveDir; // Player's velocity
A3DVECTOR3 m_vServerPos; // Player's real position on server
public A3DVECTOR3 m_vServerPos; // Player's real position on server
A3DVECTOR3 m_vStopDir; // The direction when player stop moving
// 是否是依附者 = Is it a dependent/attacher?
bool m_bHangerOn;
@@ -24,10 +26,13 @@ namespace PerfectWorld.Scripts.Player
OtherPlayer_Move_Info m_cdr = new OtherPlayer_Move_Info();
float m_fDistToHost = 0f; // Distance to host player
float m_fDistToHostH = 0f; // Horizontal distance to host player
CECCounter m_FightCnt;
public CECCounter m_FightCnt;
CECEPWorkMan m_pEPWorkMan;
CECHostPlayer pHost => EC_ManMessageMono.Instance?.GetECManPlayer?.GetHostPlayer();
public void Init(RoleInfo roleInfo, info_player_1 Info)
{
m_pEPWorkMan = new CECEPWorkMan(this);
m_iProfession = roleInfo.occupation;
m_iGender = roleInfo.gender;
@@ -69,7 +74,7 @@ namespace PerfectWorld.Scripts.Player
{
BrewMonster.BMLogger.Log("HoangDev : fDist >= MAX_LAGDIST");
SetPos(Cmd.dest);
//m_pEPWorkMan->FinishWork(CECEPWork::WORK_MOVE);
//m_pEPWorkMan.FinishWork(CECEPWork::WORK_MOVE);
return;
}
@@ -348,15 +353,16 @@ namespace PerfectWorld.Scripts.Player
private void Update()
{
MovingTo(Time.deltaTime);
CECHostPlayer pHost = EC_ManMessageMono.Instance.GetECManPlayer.GetHostPlayer();
if (pHost != null /*&& pHost->IsSkeletonReady()*/)
if (pHost != null /*&& pHost.IsSkeletonReady()*/)
{
m_fDistToHost = CalcDist(pHost.GetPos(), true);
m_fDistToHostH = CalcDist(pHost.GetPos(), false);
}
m_pEPWorkMan?.Tick(Time.deltaTime);
}
private void SetPos(A3DVECTOR3 vPos)
public void SetPos(A3DVECTOR3 vPos)
{
Vector3 vector = new Vector3();
vector.x = vPos.x;
@@ -382,6 +388,152 @@ namespace PerfectWorld.Scripts.Player
// Get player's real position on server
public A3DVECTOR3 GetServerPos() { return m_vServerPos; }
public bool ProcessMessage(ECMSG Msg)
{
switch (Msg.dwMsg)
{
case long value when value == EC_MsgDef.MSG_PM_PLAYERATKRESULT:
OnMsgPlayerAtkResult(Msg);
break;
}
return true;
}
void OnMsgPlayerAtkResult(ECMSG Msg)
{
cmd_object_atk_result pCmd = GPDataTypeHelper.FromBytes<cmd_object_atk_result>((byte[])Msg.dwParam1);
//ASSERT(pCmd && pCmd.attacker_id == m_PlayerInfo.cid);
// Face to target
TurnFaceTo(pCmd.target_id);
// TO DO: fix later
//PlayAttackEffect(pCmd.target_id, 0, 0, -1, pCmd.attack_flag, pCmd.speed* 50);
if (!m_pEPWorkMan.FindWork(CECEPWorkMan.Work_type.WT_NORMAL, CECEPWork.EP_work_ID.WORK_HACKOBJECT)){
m_pEPWorkMan.StartNormalWork(new CECEPWorkMelee(m_pEPWorkMan, pCmd.target_id));
}
// Enter fight state
EnterFightState();
}
// Play an attack effect
//void PlayAttackEffect(int idTarget, int idSkill, int skillLevel, int nDamage,
// uint dwModifier, int nAttackSpeed, int[] piAttackTime/* NULL */, int nSection)
//{
// if (!IsAllResReady())
// return;
// if (idSkill == 0)
// {
// int idWeapon = IsShapeChanged() ? 0 : GetWeaponID();
// int nTimeFly = 10;
// if (idWeapon != 0)
// {
// // ¿´¿´ÊDz»ÊÇÔ¶³ÌÎäÆ÷
// DATA_TYPE dt;
// WEAPON_ESSENCE pWeapon = (WEAPON_ESSENCE)g_pGame.GetElementDataMan().get_data_ptr(idWeapon, ID_SPACE_ESSENCE, dt);
// //ASSERT(dt == DT_WEAPON_ESSENCE);
// if (dt == DT_WEAPON_ESSENCE && pWeapon && pWeapon.require_projectile)
// {
// nTimeFly = 700;
// if (m_aEquips[EQUIPIVTR_PROJECTILE])
// idWeapon = m_aEquips[EQUIPIVTR_PROJECTILE]; // set weapon to the projectile
// }
// }
// if (g_pGame.GetGameRun().GetWorld().GetAttacksMan().FindAttackByAttacker(GetPlayerInfo().cid))
// {
// // signal early attack event
// ClearComActFlagAllRankNodes(true);
// }
// // melee attack
// CECAttackEvent pAttack = g_pGame.GetGameRun().GetWorld().GetAttacksMan().AddMeleeAttack(
// GetPlayerInfo().cid, idTarget, idWeapon, dwModifier, nDamage, nTimeFly);
// if (pAttack != null)
// {
// if (!IsDead() && (dwModifier & CECAttackEvent::MOD_RETORT) == 0
// && (dwModifier & CECAttackEvent::MOD_ATTACK_AURA) == 0
// && PlayAttackAction(nAttackSpeed, piAttackTime, &pAttack.m_bSignaled)
// && (dwModifier & CECAttackEvent::MOD_BEAT_BACK) == 0)
// {
// }
// else
// {
// pAttack.m_bSignaled = true;
// }
// }
// }
// else
// {
// if (skillLevel == 0)
// {
// if (m_pCurSkill)
// skillLevel = m_pCurSkill.GetSkillLevel();
// else
// skillLevel = 1;
// }
// CECAttackEvent pAttack = null;
// // first try to find if there is already a skill attack event in attackman
// CECAttackerEvents attackerEvents = g_pGame.GetGameRun().GetWorld().GetAttacksMan().FindAttackByAttacker(GetPlayerInfo().cid);
// if (attackerEvents)
// {
// CECAttackEvent pAttack = attackerEvents.Find(idSkill, nSection);
// if (() != null)
// {
// // Ãæ¹¥»÷µÄ·ÇµÚÒ»´ÎÉ˺¦ÏûÏ¢
// pAttack.AddTarget(idTarget, dwModifier, nDamage);
// goto EXIT;
// }
// else
// {
// attackerEvents.Signal();
// }
// }
// if (GNET::ElementSkill::IsGoblinSkill(idSkill) &&
// GNET::ElementSkill::GetType(idSkill) == 2)
// {
// pAttack = g_pGame.GetGameRun().GetWorld().GetAttacksMan().AddSkillAttack(
// GetPlayerInfo().cid, GetPlayerInfo().cid, idTarget, GetWeaponID(), idSkill, skillLevel, dwModifier, nDamage);
// }
// else
// {
// // begin a skill attack
// pAttack = g_pGame.GetGameRun().GetWorld().GetAttacksMan().AddSkillAttack(
// GetPlayerInfo().cid, m_idCurSkillTarget, idTarget, GetWeaponID(), idSkill, skillLevel, dwModifier, nDamage);
// }
// if (pAttack)
// {
// pAttack.SetSkillSection(nSection);
// if (!IsDead() && (dwModifier & CECAttackEvent::MOD_RETORT) == 0
// && (dwModifier & CECAttackEvent::MOD_ATTACK_AURA) == 0
// && PlaySkillAttackAction(idSkill, nAttackSpeed, NULL, nSection, &pAttack.m_bSignaled)
// && (dwModifier & CECAttackEvent::MOD_BEAT_BACK) == 0)
// {
// }
// else
// {
// pAttack.m_bSignaled = true;
// }
// }
// EXIT:
// // For skill attacking, time is always set to 0
// if (piAttackTime)
// *piAttackTime = 0;
// }
//}
//public A3DVECTOR3 GetPos()
//{
// return new A3DVECTOR3(transform.position.x, transform.position.y, transform.position.z);
@@ -4,7 +4,7 @@ using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace PerfectWorld.Scripts.Task
namespace BrewMonster.Scripts.Task
{
public class ATaskTemplMan
{
@@ -1,8 +1,9 @@
using BrewMonster.Network;
using BrewMonster.Scripts.Player;
using System.Collections.Generic;
using UnityEngine;
namespace PerfectWorld.Scripts.Task
namespace BrewMonster.Scripts.Task
{
public class CECTaskInterface : TaskInterface
{
@@ -1,4 +1,4 @@
namespace PerfectWorld.Scripts.Task
namespace BrewMonster.Scripts.Task
{
public struct TASK_EXPRESSION
{
@@ -1,4 +1,4 @@
namespace PerfectWorld.Scripts.Task
namespace BrewMonster.Scripts.Task
{
public interface TaskInterface
{
@@ -1,6 +1,6 @@
using System;
using System.Runtime.InteropServices;
using PerfectWorld.Scripts.Task;
using BrewMonster.Scripts.Task;
using UnityEngine;
public class TaskProcess
@@ -3,7 +3,7 @@ using System.IO;
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Task
namespace BrewMonster.Scripts.Task
{
public sealed class TaskConstant
{
+1 -1
View File
@@ -2,7 +2,7 @@ using System.IO;
using UnityEngine;
namespace PerfectWorld.Scripts.Task
namespace BrewMonster.Scripts.Task
{
public class TaskTest : MonoBehaviour
{
@@ -7,6 +7,8 @@ using CSNetwork.GPDataType;
using System.Collections.Generic;
using BrewMonster;
using TMPro;
using BrewMonster.Managers;
using BrewMonster.Scripts.Managers;
public class pickupItem : MonoBehaviour
{
+22 -4
View File
@@ -1,9 +1,27 @@
using BrewMonster;
using BrewMonster.Scripts.Ornament;
using UnityEngine;
public class CECWorld : MonoSingleton<CECWorld>
{
uint m_dwBornStamp = 0;
public uint GetBornStamp() { return m_dwBornStamp++; }
namespace BrewMonster.Scripts.World
{
public class CECWorld : MonoSingleton<CECWorld>
{
protected A3DTerrain2 m_pA3DTerrain; // Terrain object
CECOrnamentMan m_pOnmtMan;
uint m_dwBornStamp = 0;
public uint GetBornStamp() { return m_dwBornStamp++; }
// Get terrain object
public A3DTerrain2 GetTerrain()
{
return m_pA3DTerrain;
}
public CECOrnamentMan GetOrnamentMan()
{
return m_pOnmtMan;
}
}
}
+9 -7
View File
@@ -1,5 +1,9 @@
using BrewMonster;
using BrewMonster.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts.Player;
using CSNetwork;
using CSNetwork.Common;
using CSNetwork.GPDataType;
@@ -9,14 +13,12 @@ using NUnit.Framework;
using PerfectWorld.Scripts.Managers;
using PerfectWorld.Scripts.Managers.BrewMonster.Managers;
using PerfectWorld.Scripts.Player;
using PerfectWorld.Scripts.Task;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using TMPro;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
@@ -598,7 +600,7 @@ public class CECHostPlayer : CECPlayer
Debug.Log("[Inventory] OWN_ITEM_INFO received");
var data = Msg.dwParam1 as byte[];
int hostId = Convert.ToInt32(Msg.dwParam3);
PerfectWorld.Scripts.Managers.EC_Inventory.LogInventoryPacket("OWN_ITEM_INFO", data, hostId);
EC_Inventory.LogInventoryPacket("OWN_ITEM_INFO", data, hostId);
break;
}
@@ -614,20 +616,20 @@ public class CECHostPlayer : CECPlayer
{
case CommandID.OWN_IVTR_DATA:
{
PerfectWorld.Scripts.Managers.EC_Inventory.LogInventoryPacket("OWN_IVTR_DATA", data, hostId);
EC_Inventory.LogInventoryPacket("OWN_IVTR_DATA", data, hostId);
break;
}
case CommandID.OWN_IVTR_DETAIL_DATA:
{
PerfectWorld.Scripts.Managers.EC_Inventory.LogInventoryPacket("OWN_IVTR_DETAIL_DATA", data, hostId);
EC_Inventory.LogInventoryPacket("OWN_IVTR_DETAIL_DATA", data, hostId);
// Parse and store
if (data != null && data.Length >= 6)
{
byte byPackage = data[0];
byte ivtrSize = data[1];
if (PerfectWorld.Scripts.Managers.EC_IvtrItem.TryParseInventoryDetail(data, out var pkg, out var size, out var items))
if (EC_IvtrItem.TryParseInventoryDetail(data, out var pkg, out var size, out var items))
{
PerfectWorld.Scripts.Managers.EC_Inventory.UpdatePack(pkg, size, items);
EC_Inventory.UpdatePack(pkg, size, items);
}
}
break;
+36 -33
View File
@@ -1,47 +1,50 @@
using BrewMonster.UI;
using CSNetwork.Protocols.RPCData;
using PerfectWorld.Scripts.Managers;
using BrewMonster.Scripts.Managers;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
public class CanvasController : MonoBehaviour
namespace BrewMonster.Managers
{
[SerializeField] private ScreenLogin screenLogin;
[SerializeField] private SelecScreenCharacter screenCharacter;
[SerializeField] private GameObject bgr;
[SerializeField] private GameController gameController;
GameObject screenLoginOb;
GameObject screenCharacterOb;
private SynchronizationContext context;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
public class CanvasController : MonoBehaviour
{
bgr.gameObject.SetActive(true);
screenLogin.gameObject.SetActive(true);
screenCharacter.gameObject.SetActive(false);
context = SynchronizationContext.Current;
}
[SerializeField] private ScreenLogin screenLogin;
[SerializeField] private SelecScreenCharacter screenCharacter;
[SerializeField] private GameObject bgr;
[SerializeField] private GameController gameController;
public void ShowScreenSelectCharacter(List<RoleInfo> roleInfos)
{
context.Post(_ =>
GameObject screenLoginOb;
GameObject screenCharacterOb;
private SynchronizationContext context;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
screenLogin.gameObject.SetActive(false);
screenCharacter.gameObject.SetActive(true);
screenCharacter.InitScreen(roleInfos, OnClickSelectChacter);
}, null);
}
bgr.gameObject.SetActive(true);
screenLogin.gameObject.SetActive(true);
screenCharacter.gameObject.SetActive(false);
context = SynchronizationContext.Current;
}
private void OnClickSelectChacter(RoleInfo roleInfo)
{
}
public void ShowScreenSelectCharacter(List<RoleInfo> roleInfos)
{
context.Post(_ =>
{
screenLogin.gameObject.SetActive(false);
screenCharacter.gameObject.SetActive(true);
screenCharacter.InitScreen(roleInfos, OnClickSelectChacter);
}, null);
}
private void OnDestroy()
{
private void OnClickSelectChacter(RoleInfo roleInfo)
{
}
private void OnDestroy()
{
}
}
}
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0bc278a5921e8bc49ae3adc91a46e33c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+37 -34
View File
@@ -1,41 +1,44 @@
using UnityEngine;
public class PlayerStateMachine
namespace BrewMonster.Scripts.Player
{
PlayerState _state;
CECHostPlayer _characterCtrl;
public PlayerState State { get => _state; }
public void InitState(PlayerState state)
public class PlayerStateMachine
{
if (_state != null)
{
Debug.LogWarning("_state is already inited");
return;
}
_state = state;
_state.Enter();
}
PlayerState _state;
CECHostPlayer _characterCtrl;
public void ChangeState(PlayerState state)
{
if (_state == null )
{
Debug.LogError("you need to init state first ");
return;
}
if (_state == state)
{
Debug.LogWarning("Unchanged state");
}
_state.Exit();
_state = state;
_state.Enter();
}
public void UpdateState()
{
_state.Update();
}
public PlayerState State { get => _state; }
public void InitState(PlayerState state)
{
if (_state != null)
{
Debug.LogWarning("_state is already inited");
return;
}
_state = state;
_state.Enter();
}
public void ChangeState(PlayerState state)
{
if (_state == null)
{
Debug.LogError("you need to init state first ");
return;
}
if (_state == state)
{
Debug.LogWarning("Unchanged state");
}
_state.Exit();
_state = state;
_state.Enter();
}
public void UpdateState()
{
_state.Update();
}
}
}
+28 -25
View File
@@ -4,35 +4,38 @@ using UnityEngine.UI;
using System.Collections.Generic;
using CSNetwork.Protocols.RPCData;
public class ScreenLogin : MonoBehaviour
namespace BrewMonster.Managers
{
[SerializeField] private TMP_InputField ifUsername;
[SerializeField] private TMP_InputField ifPassword;
[SerializeField] private TMP_Dropdown ip;
[SerializeField] private Button btnLogin;
[SerializeField] private CanvasController canvasController;
private void Start()
public class ScreenLogin : MonoBehaviour
{
btnLogin.onClick.AddListener(OnClickBtnLogin);
}
[SerializeField] private TMP_InputField ifUsername;
[SerializeField] private TMP_InputField ifPassword;
[SerializeField] private TMP_Dropdown ip;
[SerializeField] private Button btnLogin;
[SerializeField] private CanvasController canvasController;
private void OnClickBtnLogin()
{
string _username = ifUsername.text;
string _password = ifPassword.text;
string _ip = ip.options[ip.value].text;
Debug.LogError("Login...");
}
private void Start()
{
btnLogin.onClick.AddListener(OnClickBtnLogin);
}
private void HandleLoginComplete(List<RoleInfo> roleInfos)
{
Debug.LogError("Success");
canvasController.ShowScreenSelectCharacter(roleInfos);
}
private void OnClickBtnLogin()
{
string _username = ifUsername.text;
string _password = ifPassword.text;
string _ip = ip.options[ip.value].text;
Debug.LogError("Login...");
}
private void HandleLoginFaile(string reslut)
{
Debug.LogError(reslut);
private void HandleLoginComplete(List<RoleInfo> roleInfos)
{
Debug.LogError("Success");
canvasController.ShowScreenSelectCharacter(roleInfos);
}
private void HandleLoginFaile(string reslut)
{
Debug.LogError(reslut);
}
}
}
@@ -1,4 +1,5 @@
using UnityEngine;
using BrewMonster.Scripts.Player;
using UnityEngine;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif