657 lines
25 KiB
C#
657 lines
25 KiB
C#
using BrewMonster;
|
|
using BrewMonster.Managers;
|
|
using BrewMonster.Network;
|
|
using BrewMonster.Scripts;
|
|
using CSNetwork;
|
|
using CSNetwork.GPDataType;
|
|
using CSNetwork.Protocols;
|
|
using CSNetwork.Protocols.rpcdata;
|
|
using CSNetwork.Protocols.RPCData;
|
|
using ModelRenderer.Scripts.Common;
|
|
using System;
|
|
using System.Data;
|
|
using System.Text;
|
|
using BrewMonster.PerfectWorld.Scripts.Vfx;
|
|
using UnityEngine;
|
|
|
|
namespace BrewMonster
|
|
{
|
|
public class EC_ElsePlayer : CECPlayer
|
|
{
|
|
|
|
public int m_iAppearFlag; // Player's appearing flag
|
|
public bool m_bBaseInfoReady; // true, Basic info is ready
|
|
public bool m_bCustomReady; // true, Customized data is ready
|
|
public bool m_bEquipReady; // true, Equipment data is ready
|
|
|
|
A3DVECTOR3 m_vMoveDir; // Player's velocity
|
|
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;
|
|
// 依附者或被依附者id = The ID of the attacher (dependent) or the attached target.
|
|
int m_iBuddyId;
|
|
bool m_bStopMove; // Stop move flag
|
|
public const float MAX_LAGDIST = 10.0f; // Maximum lag distance
|
|
A3DVECTOR3 g_vAxisY = new A3DVECTOR3(0.0f, 1.0f, 0.0f);
|
|
long m_dwLastMoveTime = 0; // Last move command arrived time
|
|
float m_fMoveSpeed; // Move speed
|
|
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
|
|
private BaseVfxObject m_pAppearGFX; // Appear GFX
|
|
public CECCounter m_FightCnt;
|
|
CECEPWorkMan m_pEPWorkMan;
|
|
CECHostPlayer pHost => EC_ManMessageMono.Instance?.GetECManPlayer?.GetHostPlayer();
|
|
|
|
public void Init(info_player_1 Info, int iAppearFlag)
|
|
{
|
|
SetUpPlayer();
|
|
m_dwResFlags = (uint)PlayerResourcesReadyFlag.RESFG_ALL;
|
|
m_pEPWorkMan = new CECEPWorkMan(this);
|
|
|
|
CalcPlayerAABB();
|
|
SetPlayerInfor(new INFO(Info.cid, Info.crc_e, Info.crc_c));
|
|
SetServerPos(Info.pos);
|
|
SetPos(Info.pos);
|
|
|
|
m_cdr.fStepHeight = m_MoveConst.fStepHei;
|
|
m_cdr.vExts = m_aabbServer.Extents;
|
|
m_cdr.vVelocity.Clear();
|
|
|
|
m_FightCnt = new CECCounter();
|
|
m_FightCnt.SetPeriod(15000);
|
|
m_FightCnt.Reset(true);
|
|
|
|
A3DVECTOR3 vPos = GetPos();
|
|
m_aabb.Center = vPos + new A3DVECTOR3(0.0f, m_aabb.Extents.y, 0.0f);
|
|
m_aabb.CompleteMinsMaxs();
|
|
m_aabbServer.Center = vPos + new A3DVECTOR3(0.0f, m_aabbServer.Extents.y, 0.0f);
|
|
m_aabbServer.CompleteMinsMaxs();
|
|
|
|
LoadAppearGfx();
|
|
}
|
|
public void MoveTo(cmd_object_move Cmd)
|
|
{
|
|
BrewMonster.BMLogger.Log("HoangDev : MoveToMoveTo");
|
|
|
|
if (Cmd.use_time == 0)
|
|
return;
|
|
SetServerPos(Cmd.dest);
|
|
m_vMoveDir = Cmd.dest - GetPos();
|
|
float fDist = m_vMoveDir.Normalize();
|
|
m_bStopMove = false;
|
|
|
|
// If destination position is too far to us, forcely pull player
|
|
// to that position.
|
|
if (fDist >= MAX_LAGDIST)
|
|
{
|
|
BrewMonster.BMLogger.Log("HoangDev : fDist >= MAX_LAGDIST");
|
|
SetPos(Cmd.dest);
|
|
//m_pEPWorkMan.FinishWork(CECEPWork::WORK_MOVE);
|
|
return;
|
|
}
|
|
|
|
int iMoveMode = Cmd.move_mode;
|
|
m_cdr.bTraceGround = true;
|
|
|
|
if (((GPMoveMode)iMoveMode & GPMoveMode.GP_MOVE_AIR) != 0)
|
|
{
|
|
m_iMoveEnv = (int)MoveEnvironment.MOVEENV_AIR;
|
|
m_cdr.bTraceGround = false;
|
|
}
|
|
else if (((GPMoveMode)iMoveMode & GPMoveMode.GP_MOVE_WATER) != 0)
|
|
{
|
|
m_iMoveEnv = (int)MoveEnvironment.MOVEENV_WATER;
|
|
m_cdr.bTraceGround = false;
|
|
//ShowWing(false);
|
|
}
|
|
else
|
|
{
|
|
m_iMoveEnv = (int)MoveEnvironment.MOVEENV_GROUND;
|
|
|
|
//if (!IsFlying())
|
|
// ShowWing(false);
|
|
}
|
|
|
|
switch ((GPMoveMode)iMoveMode & GPMoveMode.GP_MOVE_MASK)
|
|
{
|
|
case GPMoveMode.GP_MOVE_WALK: m_iMoveMode = (int)MoveMode.MOVE_MOVE; m_bWalkRun = false; break;
|
|
case GPMoveMode.GP_MOVE_RUN: m_iMoveMode = (int)MoveMode.MOVE_MOVE; m_bWalkRun = true; break;
|
|
case GPMoveMode.GP_MOVE_SLIDE: m_iMoveMode = (int)MoveMode.MOVE_SLIDE; break;
|
|
case GPMoveMode.GP_MOVE_FALL: m_iMoveMode = (int)MoveMode.MOVE_FREEFALL; m_cdr.bTraceGround = false; break;
|
|
case GPMoveMode.GP_MOVE_FLYFALL: m_cdr.bTraceGround = false; break;
|
|
case GPMoveMode.GP_MOVE_JUMP: m_iMoveMode = (int)MoveMode.MOVE_JUMP; m_cdr.bTraceGround = false; break;
|
|
}
|
|
|
|
long dwTimeNow = Environment.TickCount;
|
|
long dwDeltaTime = (dwTimeNow > m_dwLastMoveTime) ? (dwTimeNow - m_dwLastMoveTime) : 0;
|
|
m_dwLastMoveTime = dwTimeNow;
|
|
if (dwDeltaTime < 500)
|
|
dwDeltaTime = 500;
|
|
if (dwDeltaTime > 1000)
|
|
dwDeltaTime = 1000;
|
|
|
|
float fSpeed = (Cmd.sSpeed) / 256f; // short / 256 <=> FIX8TOFLOAT(short)
|
|
m_fMoveSpeed = fDist / (dwDeltaTime * 0.001f);
|
|
Mathf.Clamp(m_fMoveSpeed, 0.0f, fSpeed * 1.2f);
|
|
|
|
//if (!m_pPlayerModel) return;
|
|
//if (!IsValidAction(iCurAction)) return;
|
|
// PlayAction(GetMoveStandAction(true), true, 1, false);
|
|
|
|
// Play action
|
|
if (IsValidAction(m_iCurAction))
|
|
{
|
|
if (!IsPlayingAction((int)PLAYER_ACTION_TYPE.ACT_TRICK_JUMP) && !IsPlayingAction((int)PLAYER_ACTION_TYPE.ACT_TRICK_RUN))
|
|
{
|
|
if (m_iMoveMode == Move_Mode.MOVE_JUMP || m_iMoveMode == Move_Mode.MOVE_SLIDE)
|
|
PlayAction((int)PLAYER_ACTION_TYPE.ACT_JUMP_LOOP, false);
|
|
else
|
|
PlayAction(GetMoveStandAction(true), false);
|
|
}
|
|
}
|
|
else
|
|
PlayAction(GetMoveStandAction(true), true, 1, false);
|
|
}
|
|
|
|
public bool MovingTo(float dwDeltaTime)
|
|
{
|
|
bool bRet = false;
|
|
|
|
A3DVECTOR3 vPos, vCurPos = GetPos();
|
|
float fDeltaTime = dwDeltaTime;
|
|
|
|
if (m_bStopMove)
|
|
{
|
|
A3DVECTOR3 vDir = m_vServerPos - vCurPos;
|
|
float fDist = vDir.Normalize();
|
|
if (vDir.IsZero()) return false;
|
|
|
|
Vector3 flatDir = EC_Utility.ToVector3(vDir);
|
|
flatDir.y = 0;
|
|
if (flatDir.sqrMagnitude > 0.001f)
|
|
{
|
|
Quaternion targetRotation = Quaternion.LookRotation(flatDir);
|
|
if (Quaternion.Angle(transform.rotation, targetRotation) < 0.5f)
|
|
transform.rotation = targetRotation;
|
|
else
|
|
transform.rotation = Quaternion.Slerp(
|
|
transform.rotation,
|
|
targetRotation,
|
|
rotationSpeed * Time.deltaTime
|
|
);
|
|
}
|
|
|
|
vPos = MoveStep(vDir, m_fMoveSpeed, fDeltaTime);
|
|
|
|
float fMoveDelta = A3d_Magnitude(vPos - vCurPos);
|
|
if (Math.Abs(fMoveDelta - 0f) <= float.Epsilon || fMoveDelta >= fDist) //!fMoveDelta <=> (Math.Abs(fMoveDelta - 0f) <= float.Epsilon) Compare with 0
|
|
{
|
|
SetPos(m_vServerPos);
|
|
PlayAction(GetMoveStandAction(false), true, 1, false);
|
|
bRet = true;
|
|
}
|
|
else
|
|
{
|
|
SetPos(vPos);
|
|
}
|
|
}
|
|
else // Just move on
|
|
{
|
|
// If we have move so far from destination and still don't
|
|
// receive new 'move' or 'stop move' command, it's better to
|
|
// stop moving and goto last destination at once
|
|
if (m_vMoveDir.IsZero()) return false;
|
|
A3DVECTOR3 vDir = m_vMoveDir;
|
|
vDir.Normalize();
|
|
|
|
Vector3 flatDir = EC_Utility.ToVector3(vDir);
|
|
flatDir.y = 0;
|
|
if (flatDir.sqrMagnitude > 0.001f)
|
|
{
|
|
Quaternion targetRotation = Quaternion.LookRotation(flatDir);
|
|
if (Quaternion.Angle(transform.rotation, targetRotation) < 0.5f)
|
|
transform.rotation = targetRotation;
|
|
else
|
|
transform.rotation = Quaternion.Slerp(
|
|
transform.rotation,
|
|
targetRotation,
|
|
rotationSpeed * Time.deltaTime
|
|
);
|
|
}
|
|
vPos = MoveStep(vDir, m_fMoveSpeed, fDeltaTime);
|
|
SetPos(vPos);
|
|
float fDist = A3d_Magnitude(m_vServerPos - vCurPos);
|
|
if (fDist >= MAX_LAGDIST)
|
|
{
|
|
SetPos(m_vServerPos);
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
public void StopMoveTo(cmd_object_stop_move Cmd)
|
|
{
|
|
m_vMoveDir = Cmd.dest - GetPos();
|
|
m_bStopMove = true;
|
|
m_fMoveSpeed = (Cmd.sSpeed) / 256f;
|
|
m_vStopDir = glb_DecompressDirH(Cmd.dir);
|
|
|
|
SetServerPos(Cmd.dest);
|
|
|
|
float fDist = m_vMoveDir.Normalize();
|
|
BrewMonster.BMLogger.Log($"HoangDev : {fDist} : {MAX_LAGDIST} || {m_fMoveSpeed}");
|
|
|
|
if (fDist >= MAX_LAGDIST || m_fMoveSpeed < 0.01f)
|
|
{
|
|
m_bStopMove = false;
|
|
SetPos(Cmd.dest);
|
|
PlayAction(GetMoveStandAction(true), true, 1, false);
|
|
return;
|
|
}
|
|
int iMoveMode = Cmd.move_mode;
|
|
m_cdr.bTraceGround = true;
|
|
|
|
if (((GPMoveMode)iMoveMode & GPMoveMode.GP_MOVE_AIR) != 0)
|
|
{
|
|
m_iMoveEnv = (int)MoveEnvironment.MOVEENV_AIR;
|
|
m_cdr.bTraceGround = false;
|
|
}
|
|
else if (((GPMoveMode)iMoveMode & GPMoveMode.GP_MOVE_WATER) != 0)
|
|
{
|
|
m_iMoveEnv = (int)MoveEnvironment.MOVEENV_WATER;
|
|
m_cdr.bTraceGround = false;
|
|
}
|
|
else
|
|
m_iMoveEnv = (int)MoveEnvironment.MOVEENV_GROUND;
|
|
|
|
switch ((GPMoveMode)iMoveMode & GPMoveMode.GP_MOVE_MASK)
|
|
{
|
|
case GPMoveMode.GP_MOVE_WALK: m_iMoveMode = (int)MoveMode.MOVE_MOVE; m_bWalkRun = false; break;
|
|
case GPMoveMode.GP_MOVE_RUN: m_iMoveMode = (int)MoveMode.MOVE_MOVE; m_bWalkRun = true; break;
|
|
case GPMoveMode.GP_MOVE_SLIDE: m_iMoveMode = (int)MoveMode.MOVE_SLIDE; break;
|
|
case GPMoveMode.GP_MOVE_FALL: m_iMoveMode = (int)MoveMode.MOVE_FREEFALL; m_cdr.bTraceGround = false; break;
|
|
case GPMoveMode.GP_MOVE_FLYFALL: m_cdr.bTraceGround = false; break;
|
|
case GPMoveMode.GP_MOVE_JUMP: m_iMoveMode = (int)MoveMode.MOVE_JUMP; m_cdr.bTraceGround = false; break;
|
|
}
|
|
|
|
PlayAction(GetMoveStandAction(true), true, 1, false);
|
|
}
|
|
|
|
public float GetDistToHost() { return m_fDistToHost; }
|
|
|
|
// Decompress horizontal direction
|
|
A3DVECTOR3 glb_DecompressDirH(byte byDir)
|
|
{
|
|
float fInter = 360.0f / 256.0f;
|
|
|
|
float fRad = Mathf.Deg2Rad * (byDir * fInter);
|
|
A3DVECTOR3 v;
|
|
v.x = (float)Math.Cos(fRad);
|
|
v.z = (float)Math.Sin(fRad);
|
|
v.y = 0.0f;
|
|
|
|
return v;
|
|
}
|
|
public void EnterFightState()
|
|
{
|
|
m_FightCnt.Reset(false);
|
|
}
|
|
private A3DVECTOR3 MoveStep(A3DVECTOR3 vDir, float fSpeed, float fTime)
|
|
{
|
|
A3DVECTOR3 vRealDir = vDir;
|
|
// OnAirMove only accept positive speed value
|
|
if (fSpeed < 0.0f)
|
|
{
|
|
vRealDir = -vDir;
|
|
fSpeed = -fSpeed;
|
|
}
|
|
m_cdr.vCenter = m_aabbServer.Center;
|
|
m_cdr.vVelocity = vRealDir * fSpeed;
|
|
m_cdr.t = fTime;
|
|
m_cdr.bTestTrnOnly = false;
|
|
//OtherPlayerMove(m_cdr);
|
|
A3DVECTOR3 vDelta = m_cdr.t * m_cdr.vVelocity;
|
|
m_cdr.vCenter += vDelta;
|
|
|
|
m_cdr.vecGroundNormal = g_vAxisY;
|
|
if (m_cdr.bTraceGround)
|
|
SetGroundNormal(m_cdr.vecGroundNormal);
|
|
else
|
|
SetGroundNormal(g_vAxisY);
|
|
|
|
return m_cdr.vCenter - g_vAxisY * m_cdr.vExts.y;
|
|
}
|
|
|
|
void OtherPlayerMove(OtherPlayer_Move_Info OPMoveInfo)
|
|
{
|
|
A3DVECTOR3 vDelta = OPMoveInfo.t * OPMoveInfo.vVelocity;
|
|
OPMoveInfo.vCenter += vDelta;
|
|
|
|
OPMoveInfo.vecGroundNormal = g_vAxisY;
|
|
A3DVECTOR3 vGroundPos, vNormal;
|
|
|
|
// Now, we directly interpolate the pos, and we don't use bTraceGround
|
|
//if (OPMoveInfo.bTestTrnOnly)
|
|
//{
|
|
// GetTerrainInfo(OPMoveInfo.vCenter, vGroundPos, vNormal);
|
|
// vGroundPos.y += OPMoveInfo.vExts.y;
|
|
|
|
// if (OPMoveInfo.vCenter.y < vGroundPos.y + 0.1f)
|
|
// OPMoveInfo.vecGroundNormal = vNormal;
|
|
|
|
// // verify not below the terrain
|
|
// if (OPMoveInfo.vCenter.y < vGroundPos.y)
|
|
// OPMoveInfo.vCenter.y = vGroundPos.y;
|
|
//}
|
|
//else
|
|
//{
|
|
// if (VertRayTrace(OPMoveInfo.vCenter, vGroundPos, vNormal, 3.0f))
|
|
// {
|
|
// OPMoveInfo.vecGroundNormal = vNormal;
|
|
|
|
// vGroundPos.y += OPMoveInfo.vExts.y;
|
|
|
|
// // verify not below the ground
|
|
// if (OPMoveInfo.vCenter.y < vGroundPos.y)
|
|
// OPMoveInfo.vCenter.y = vGroundPos.y;
|
|
// }
|
|
//}
|
|
}
|
|
|
|
private float A3d_Magnitude(A3DVECTOR3 v)
|
|
{
|
|
return Mathf.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
|
|
}
|
|
|
|
// Set server position
|
|
public void SetServerPos(A3DVECTOR3 vPos)
|
|
{
|
|
m_vServerPos = vPos;
|
|
// If this player is a mule, change it's rider's server pos too.
|
|
if (m_iBuddyId != 0 && !m_bHangerOn)
|
|
{
|
|
var pPlayer = EC_ManMessageMono.Instance.GetECManPlayer.GetElsePlayer(m_iBuddyId);
|
|
if (pPlayer)
|
|
pPlayer.SetServerPos(vPos);
|
|
}
|
|
}
|
|
|
|
protected override void Update()
|
|
{
|
|
base.Update();
|
|
MovingTo(Time.deltaTime);
|
|
|
|
if (pHost != null /*&& pHost.IsSkeletonReady()*/)
|
|
{
|
|
m_fDistToHost = CalcDist(pHost.GetPos(), true);
|
|
m_fDistToHostH = CalcDist(pHost.GetPos(), false);
|
|
}
|
|
m_pEPWorkMan?.Tick(Time.deltaTime);
|
|
}
|
|
|
|
public void SetPos(A3DVECTOR3 vPos)
|
|
{
|
|
Vector3 vector = new Vector3();
|
|
vector.x = vPos.x;
|
|
vector.y = vPos.y;
|
|
vector.z = vPos.z;
|
|
transform.position = vector;
|
|
|
|
m_aabb.Center = vPos + new A3DVECTOR3(0.0f, m_aabb.Extents.y, 0.0f);
|
|
m_aabb.CompleteMinsMaxs();
|
|
m_aabbServer.Center = vPos + new A3DVECTOR3(0.0f, m_aabbServer.Extents.y, 0.0f);
|
|
m_aabbServer.CompleteMinsMaxs();
|
|
}
|
|
|
|
public A3DVECTOR3 GetPos()
|
|
{
|
|
A3DVECTOR3 result = new A3DVECTOR3();
|
|
result.x = transform.position.x;
|
|
result.y = transform.position.y;
|
|
result.z = transform.position.z;
|
|
return result;
|
|
}
|
|
|
|
// 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_PLAYERBASEINFO:
|
|
OnMsgPlayerBaseInfo(Msg);
|
|
break;
|
|
case long value when value == EC_MsgDef.MSG_PM_PLAYERATKRESULT:
|
|
OnMsgPlayerAtkResult(Msg);
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public void HandleRevive(short sReviveType, A3DVECTOR3 pos)
|
|
{
|
|
SetServerPos(pos);
|
|
SetPos(pos);
|
|
m_pEPWorkMan?.FinishWork(CECEPWork.EP_work_ID.WORK_DEAD);
|
|
m_pEPWorkMan?.StartNormalWork(new CECEPWorkIdle(m_pEPWorkMan, CECEPWork.Idle_work_type.IDLE_REVIVE, 0, 0));
|
|
}
|
|
|
|
async void OnMsgPlayerBaseInfo(ECMSG Msg)
|
|
{
|
|
playerbaseinfo_re p = (playerbaseinfo_re)Msg.dwParam1;
|
|
GRoleBase roleBase = p.Player;
|
|
// if (p.Roleid != m_PlayerInfo.cid)
|
|
// {
|
|
// BMLogger.LogError($"OnMsgPlayerBaseInfo:: Expected {m_PlayerInfo.cid}, but got {p.Roleid}");
|
|
// return;
|
|
// }
|
|
|
|
if (roleBase.name.Length <= 0)
|
|
return;
|
|
|
|
string strName = Encoding.Unicode.GetString(roleBase.name.ByteArray);
|
|
SetPlayerBriefInfo(roleBase.cls, roleBase.gender, strName);
|
|
|
|
EventBus.Publish(new NPCINFO(strName, 100,100, p.Roleid));
|
|
|
|
BMLogger.Log($"SetPlayerModel: {roleBase.cls} {roleBase.gender}");
|
|
await SetPlayerModel((byte)roleBase.cls, (byte)roleBase.gender);
|
|
|
|
if (TryGetComponent<PlayerVisual>(out var visual))
|
|
{
|
|
visual.InitPlayerEventDoneHandler();
|
|
}
|
|
}
|
|
|
|
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
|
|
int attackTime = int.MinValue;
|
|
PlayAttackEffect(pCmd.target_id, 0, 0, -1, (uint)pCmd.attack_flag, pCmd.speed* 50, ref attackTime);
|
|
|
|
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();
|
|
}
|
|
|
|
private async void LoadAppearGfx()
|
|
{
|
|
if (!m_pAppearGFX && m_iAppearFlag == (int)PlayerAppearFlag.APPEAR_ENTERWORLD)
|
|
{
|
|
CECGFXCaster pGfxCaster = EC_Game.GetGFXCaster();
|
|
|
|
m_pAppearGFX = await pGfxCaster.LoadGFXEx(EC_Resource.res_GFXFile((int)GfxResourceType.RES_GFX_PLAYERAPPEAR));
|
|
var pos = GetPos();
|
|
m_pAppearGFX.transform.position = new Vector3(pos.x, pos.y, pos.z);
|
|
m_pAppearGFX.transform.parent = transform;
|
|
m_pAppearGFX.Play();
|
|
}
|
|
}
|
|
// 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);
|
|
//}
|
|
|
|
private void SetPlayerBriefInfo(int iProf, int iGender, string szName)
|
|
{
|
|
m_iProfession = iProf;
|
|
m_iGender = iGender;
|
|
m_bBaseInfoReady = true;
|
|
}
|
|
// Level up
|
|
public void LevelUp()
|
|
{
|
|
// if (m_pLevelUpGFX)
|
|
// m_pLevelUpGFX->Start(true);
|
|
//
|
|
PlayGfx(EC_Resource.res_GFXFile((int)GfxResourceType.RES_GFX_LEVELUP), null, 1f,1);//PLAYERMODEL_TYPEALL
|
|
}
|
|
|
|
bool IsPlayingAction(int iAction)
|
|
{
|
|
return m_iCurAction == iAction;
|
|
}
|
|
}
|
|
|
|
// Player appear flag
|
|
public enum PlayerAppearFlag
|
|
{
|
|
APPEAR_DISAPPEAR = -1, // Player disappear
|
|
APPEAR_ENTERWORLD = 0, // Player join world
|
|
APPEAR_RUNINTOVIEW, // Player run into view
|
|
APPEAR_GHOST, // Player is in ghost state, in player list but not active
|
|
};
|
|
|
|
}
|