diff --git a/Assets/PerfectWorld/Scripts/GameData/ExpTypes.cs b/Assets/PerfectWorld/Scripts/GameData/ExpTypes.cs index 86a83d1621..0a4014bbf6 100644 --- a/Assets/PerfectWorld/Scripts/GameData/ExpTypes.cs +++ b/Assets/PerfectWorld/Scripts/GameData/ExpTypes.cs @@ -5,6 +5,10 @@ using ModelRenderer.Scripts.Common; namespace BrewMonster { + public class ExpTypesConstants + { + public const int NUM_WEAPON_TYPE = 14; + } public class ElementDataConstants { public const int ELEMENTDATA_NUM_PROFESSION = 12; // Number of professions @@ -4870,7 +4874,7 @@ namespace BrewMonster [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public ushort[] name; // name - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = ExpTypesConstants.NUM_WEAPON_TYPE)] public uint[] action_mask; // fashion weapon action masks } diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkMelee.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkMelee.cs index a9f954569f..126b9e1c93 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkMelee.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkMelee.cs @@ -148,7 +148,7 @@ class CECHPWorkMelee : CECHPWork protected virtual void OnFirstTick() { m_pHost.m_iMoveMode = (int)MoveMode.MOVE_STAND; - m_pHost.PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_ATTACK_1 + Random.Range(0, 3), true, 200, false); + m_pHost.PlayAction((int)EC_Player.PLAYER_ACTION_TYPE.ACT_ATTACK_1 + Random.Range(0, 3), true, 200, false); m_idTarget = m_pHost.m_idSelTarget; } diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs index 3ad2080f30..d4a70c39fb 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkTrace.cs @@ -139,7 +139,7 @@ public abstract class CECTracedObject } else { - CECPlayer pPlayer = pObject.GetComponent(); + EC_Player pPlayer = pObject.GetComponent(); fTouchRadius = pPlayer.GetTouchRadius(); } return m_pHost.CanTouchTarget(vHostPos, vTargetPos, fTouchRadius, iTouchReason, fMaxCut); @@ -384,7 +384,7 @@ public class CECTracedPlayer : CECTracedObject { return true; } - CECPlayer pPlayer = GetTargetObject() as CECPlayer; + EC_Player pPlayer = GetTargetObject() as EC_Player; if (pPlayer.IsElsePlayer()) { if (pPlayer.IsDead()) @@ -612,10 +612,10 @@ public class CECHPWorkTrace : CECHPWork { // Continue tracing object float fDeltaTime = dwDeltaTime /** 0.001f*/; - if (m_pHost.m_iMoveEnv == CECPlayer.Move_environment.MOVEENV_GROUND) + if (m_pHost.m_iMoveEnv == EC_Player.Move_environment.MOVEENV_GROUND) { // Play appropriate actions - if (!m_pHost.IsJumping() && !m_pHost.IsPlayingAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_TRICK_RUN) && + if (!m_pHost.IsJumping() && !m_pHost.IsPlayingAction((int)EC_Player.PLAYER_ACTION_TYPE.ACT_TRICK_RUN) && m_pHost.m_iMoveMode != (int)MoveMode.MOVE_SLIDE) { int iAction = m_pHost.GetMoveStandAction(true); @@ -807,7 +807,7 @@ public class CECHPWorkTrace : CECHPWork if (m_pHost.m_iMoveMode == (int)MoveMode.MOVE_SLIDE) { - m_pHost.PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_JUMP_LOOP, false, 200, false); + m_pHost.PlayAction((int)EC_Player.PLAYER_ACTION_TYPE.ACT_JUMP_LOOP, false, 200, false); // This will cause stop moming after we slide down. A3DVECTOR3 vDir = vTargetPos - vCurPos; diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_Object.cs b/Assets/PerfectWorld/Scripts/Managers/EC_Object.cs index 7e17d81164..f6f58bbfb4 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_Object.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_Object.cs @@ -185,7 +185,7 @@ public class CECObject : MonoBehaviour return 0; if (pObject.IsPlayer()) - return ((CECPlayer)pObject).GetCharacterID(); + return ((EC_Player)pObject).GetCharacterID(); else if (pObject.IsNPC()) return ((CECNPC)pObject).GetNPCID(); //else if (pObject.IsMatter()) diff --git a/Assets/PerfectWorld/Scripts/Move/CECHostMove.cs b/Assets/PerfectWorld/Scripts/Move/CECHostMove.cs index 5825457d0b..b38926fe57 100644 --- a/Assets/PerfectWorld/Scripts/Move/CECHostMove.cs +++ b/Assets/PerfectWorld/Scripts/Move/CECHostMove.cs @@ -85,7 +85,7 @@ public class CECHostMove float fSpeed = 0f; switch (m_pHost.GetMoveEnv()) { - case CECPlayer.Move_environment.MOVEENV_AIR: + case EC_Player.Move_environment.MOVEENV_AIR: iMoveMode |= (int)GPMoveMode.GP_MOVE_AIR; fSpeed = m_pHost.GetFlySpeed(); diff --git a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs index 7e35ab349b..2be7becb44 100644 --- a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs +++ b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs @@ -8,7 +8,7 @@ using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; -public abstract class CECPlayer : CECObject +public abstract class EC_Player : CECObject { private static PLAYER_ACTION[] _default_actions; private static PLAYER_ACTION[] _turning_actions; @@ -59,9 +59,12 @@ public abstract class CECPlayer : CECObject public bool IsDead() { return (m_dwStates & PlayerNPCState.GP_STATE_CORPSE) != 0; } public bool IsValidAction(int iIndex) { return (iIndex >= 0 && iIndex < (int)PLAYER_ACTION_TYPE.ACT_MAX) ? true : false; } +<<<<<<<< HEAD:Assets/PerfectWorld/Scripts/Move/CECPlayer.cs public int GetCharacterID() { return m_PlayerInfo.cid; } +======== +>>>>>>>> origin/develop:Assets/PerfectWorld/Scripts/Move/EC_Player.cs private static void BuildActionList() { if (_default_actions == null) @@ -681,6 +684,7 @@ public abstract class CECPlayer : CECObject public int GetWeaponID() { return m_aEquips[(int)EC_IvtrType.IndexOfIteminEquipmentInventory.EQUIPIVTR_WEAPON] & 0xffff; } public bool IsAllResReady() { return (m_dwResFlags & (uint)PlayerResourcesReadyFlag.RESFG_ALL) == (uint)PlayerResourcesReadyFlag.RESFG_ALL; } // Get character ID + public int GetCharacterID(){ return m_PlayerInfo.cid; } } public struct PlayActionEvent { diff --git a/Assets/PerfectWorld/Scripts/Move/EC_Player.cs b/Assets/PerfectWorld/Scripts/Move/EC_Player.cs new file mode 100644 index 0000000000..2be7becb44 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Move/EC_Player.cs @@ -0,0 +1,735 @@ +using BrewMonster; +using CSNetwork.GPDataType; +using ModelRenderer.Scripts.GameData; +using PerfectWorld.Scripts.Managers; +using PerfectWorld.Scripts.Player; +using System; +using System.Collections.Generic; +using Unity.VisualScripting; +using UnityEngine; + +public abstract class EC_Player : CECObject +{ + private static PLAYER_ACTION[] _default_actions; + private static PLAYER_ACTION[] _turning_actions; + PLAYER_ACTION[] m_PlayerActions; + [SerializeField] internal INFO m_PlayerInfo; + protected GameObject m_pPlayerModel; + protected float rotationSpeed = 5; + internal int m_iMoveMode; // Player's move mode + internal int m_idSelTarget; + protected int m_iShape; // Ñ¡ÖÐÄ¿±êµÄID + uint m_dwStates; // Player's basic states + protected int[] m_aEquips; + protected ROLEEXTPROP m_ExtProps; // Extend properties + protected float m_fTouchRad = 0.3f; // Touch radius + protected int m_iBattleCamp = Player_camp_in_battle.GP_BATTLE_CAMP_NONE; // Battle this player belongs to + byte m_factionPVPMask; // pvp mask + protected uint m_dwResFlags; // pvp mask + protected ROLEBASICPROP m_BasicProps; + public int m_iMoveEnv = Move_environment.MOVEENV_GROUND; // Move environment + public bool m_bWalkRun; + public A3DAABB m_aabbServer; // Óë·þÎñÆ÷±£³ÖÒ»ÖµÄaabb£¬ ²»ÊÜËõ·ÅÓ°Ïì + + + const int NUM_WEAPON_TYPE = 15; + + + + protected void Awake() + { + m_PlayerActions = _default_actions; + m_iShape = 0; + m_aEquips = new int[(int)EC_IvtrType.IndexOfIteminEquipmentInventory.SIZE_ALL_EQUIPIVTR]; + } + public void SetPlayerInfor(INFO playinfo) + { + m_PlayerInfo = playinfo; + } + public INFO GetPlayInfo() + { + return m_PlayerInfo; + } + + public static void InitStaticRes() + { + BuildActionList(); + } + + public bool IsDead() { return (m_dwStates & PlayerNPCState.GP_STATE_CORPSE) != 0; } + + public bool IsValidAction(int iIndex) { return (iIndex >= 0 && iIndex < (int)PLAYER_ACTION_TYPE.ACT_MAX) ? true : false; } +<<<<<<<< HEAD:Assets/PerfectWorld/Scripts/Move/CECPlayer.cs + public int GetCharacterID() { return m_PlayerInfo.cid; } + + +======== +>>>>>>>> origin/develop:Assets/PerfectWorld/Scripts/Move/EC_Player.cs + private static void BuildActionList() + { + if (_default_actions == null) + { + // thay cho hashtab trong C++ + Dictionary actionMap = + new Dictionary(100); + + Dictionary skillActionMap = + new Dictionary(100); + + elementdataman dataman = ElementDataManProvider.GetElementDataMan(); + PLAYER_ACTION_INFO_CONFIG data; + + int count = dataman.get_data_num(ID_SPACE.ID_SPACE_CONFIG); + + DATA_TYPE dt = default; + uint id = 0; + + for (int i = 0; i < count; ++i) + { + id = dataman.get_data_id(ID_SPACE.ID_SPACE_CONFIG, i, ref dt); + if (dt != DATA_TYPE.DT_PLAYER_ACTION_INFO_CONFIG) + continue; + + data = (PLAYER_ACTION_INFO_CONFIG)dataman.get_data_ptr(id, ID_SPACE.ID_SPACE_CONFIG, ref dt); + if (!string.IsNullOrEmpty(data.ActionName) && data.ActionName[0] != '0') + { + if (!actionMap.TryAdd(data.ActionName, data)) + { + + } + } + } + + CECStringTab actionNames = new CECStringTab(); + actionNames.Init("actions_player", false); + + _default_actions = new PLAYER_ACTION[(int)PLAYER_ACTION_TYPE.ACT_MAX]; + + for (int i = 0; i < _default_actions.Length; i++) + { + _default_actions[i].type = (PLAYER_ACTION_TYPE)i; + + string szName = actionNames.GetANSIString(i); + + if (!string.IsNullOrEmpty(szName)) + { + if (actionMap.TryGetValue(szName, out var it)) + { + _default_actions[i].data = it; + } + } + } + } + } + public bool PlayAction(int iAction, bool bRestart/* true */, int iTransTime/* 200 */, bool bQueue/* false */) + { + return PlayActionWithConfig(iAction, 0, bRestart, iTransTime, bQueue); + } + public bool PlayActionWithConfig(int iAction, int actionConfigID, bool bRestart/* =true */, int iTransTime/* =200 */, bool bQueue/* =false */) + { + if (iAction < 0 || iAction >= (int)PLAYER_ACTION_TYPE.ACT_MAX) + { + return false; + } + if (actionConfigID > 0) + { + DATA_TYPE dt = DATA_TYPE.DT_INVALID; + var p = ElementDataManProvider.GetElementDataMan().get_data_ptr((uint)actionConfigID, ID_SPACE.ID_SPACE_CONFIG, ref dt); + if (dt == DATA_TYPE.DT_PLAYER_ACTION_INFO_CONFIG) + { + PLAYER_ACTION actionConfig; + actionConfig.type = (PLAYER_ACTION_TYPE)iAction; + actionConfig.data = (PLAYER_ACTION_INFO_CONFIG)p; + return PlayActionWithConfig(iAction, actionConfig, bRestart, iTransTime, bQueue); + } + else + { + + } + } + return PlayActionWithConfig(iAction, m_PlayerActions[iAction], bRestart, iTransTime, bQueue); + } + public bool PlayActionWithConfig(int iAction, in PLAYER_ACTION actionConfig, + bool bRestart = true, int iTransTime = 200, bool bQueue = false) + { + PLAYER_ACTION action = actionConfig; + + var szAct = EC_Utility.BuildActionName(action, 0); + EventBus.PublishChannel(m_PlayerInfo.cid, new PlayActionEvent(szAct)); + return true; + } + public static void Dispose() + { + _default_actions = null; + _turning_actions = null; + } + public struct PLAYER_ACTION + { + public PLAYER_ACTION_TYPE type; + public PLAYER_ACTION_INFO_CONFIG data; + }; + public INFO GetPlayerInfo() { return m_PlayerInfo; } + public enum PLAYER_ACTION_TYPE + { + // 0 + ACT_STAND = 0, // Đứng + ACT_FIGHTSTAND, // Đứng chiến đấu + ACT_WALK, // Đi bộ + ACT_RUN, // Chạy + ACT_JUMP_START, // Bắt đầu nhảy + + // 5 + ACT_JUMP_LOOP, // Nhảy trên không lặp lại + ACT_JUMP_LAND, // Nhảy tiếp đất + ACT_SWIM, // Bơi + ACT_HANGINWATER, // Lơ lửng trong nước + ACT_TAKEOFF, // Cất cánh (should be ACT_TAKEOFF_WING) + + // 10 + ACT_HANGINAIR, // Treo trên không (should be ACT_HANGINAIR_WING) + ACT_FLY, // Bay (should be ACT_FLY_WING) + ACT_FLYDOWN, // Bay xuống cao (should be ACT_FLYDOWN_WING_HIGH) + ACT_FLYDOWN_WING_LOW, // Bay xuống thấp (should be ACT_FLYDOWN_WING_LOW) + ACT_LANDON, // Hạ cánh (should be ACT_LAND_WING) + + // 15 + ACT_TAKEOFF_SWORD, // Kiếm bay - cất cánh + ACT_HANGINAIR_SWORD, // Kiếm bay - treo không trung + ACT_FLY_SWORD, // Kiếm bay - tiến tới + ACT_FLYDOWN_SWORD_HIGH, // Kiếm bay - rơi cao + ACT_FLYDOWN_SWORD_LOW, // Kiếm bay - rơi thấp + + // 20 + ACT_LANDON_SWORD, // Kiếm bay - hạ cánh + ACT_SITDOWN, // Ngồi + ACT_SITDOWN_LOOP, // Ngồi lặp lại + ACT_STANDUP, // Đứng dậy + ACT_WOUNDED, // Bị thương + + // 25 + ACT_GROUNDDIE, // Chết trên mặt đất + ACT_GROUNDDIE_LOOP, // Chết trên đất (loop) + ACT_WATERDIE, // Chết trong nước + ACT_WATERDIE_LOOP, // Chết trong nước (loop) + ACT_AIRDIE_ST, // Chết trên không (bắt đầu) + + // 30 + ACT_AIRDIE, // Chết trên không (loop rơi) + ACT_AIRDIE_ED, // Chết trên không (chạm đất) + ACT_AIRDIE_LAND_LOOP, // Chết rơi đất (loop) + ACT_REVIVE, // Hồi sinh + ACT_CUSTOMIZE, // Động tác tùy chỉnh + + // 35 + ACT_STRIKEBACK, // Bị đánh lùi + ACT_STRIKEDOWN, // Bị đánh ngã + ACT_STRIKEDOWN_LOOP, // Bị đánh ngã (loop) + ACT_STRIKEDOWN_STANDUP, // Bị đánh ngã rồi đứng dậy + ACT_PICKUP, // Nhặt đồ + + // 40 + ACT_PICKUP_LOOP, // Nhặt đồ (loop) + ACT_PICKUP_STANDUP, // Nhặt đồ đứng dậy + ACT_PICKUP_MATTER, // Nhặt vật thể + ACT_GAPE, // Há miệng + ACT_LOOKAROUND, // Nhìn quanh + + // 45 + ACT_PLAYWEAPON, // Vung vũ khí + ACT_EXP_WAVE, // Vẫy tay + ACT_EXP_NOD, // Gật đầu + ACT_EXP_SHAKEHEAD, // Lắc đầu + ACT_EXP_SHRUG, // Nhún vai + + // 50 + ACT_EXP_LAUGH, // Cười lớn + ACT_EXP_ANGRY, // Tức giận + ACT_EXP_STUN, // Choáng + ACT_EXP_DEPRESSED, // Buồn bã + ACT_EXP_KISSHAND, // Hôn tay + + // 55 + ACT_EXP_SHY, // Ngại ngùng + ACT_EXP_SALUTE, // Chào + ACT_EXP_SITDOWN, // Ngồi xuống + ACT_EXP_SITDOWN_LOOP, // Ngồi xuống (loop) + ACT_EXP_SITDOWN_STANDUP, // Ngồi xuống rồi đứng dậy + + // 60 + ACT_EXP_ASSAULT, // Tấn công + ACT_EXP_THINK, // Suy nghĩ + ACT_EXP_DEFIANCE, // Thách thức + ACT_EXP_VICTORY, // Chiến thắng + ACT_EXP_KISS, // Hôn + + // 65 + ACT_EXP_KISS_LOOP, // Hôn (loop) + ACT_EXP_KISS_END, // Kết thúc hôn + ACT_ATTACK_1, // Tấn công 1 + ACT_ATTACK_2, // Tấn công 2 + ACT_ATTACK_3, // Tấn công 3 + + // 70 + ACT_ATTACK_4, // Tấn công 4 + ACT_ATTACK_TOSS, // Ném vũ khí + ACT_TRICK_RUN, // Chiêu khi chạy + ACT_TRICK_JUMP, // Chiêu khi nhảy + ACT_FLY_GLIDE, // Lượn + + // 75 + ACT_FLY_GLIDE_SWORD, // Kiếm bay - lượn + ACT_EXP_FIGHT, // Tư thế chiến đấu + ACT_EXP_ATTACK1, // Tấn công diễn xuất 1 + ACT_EXP_ATTACK2, // Tấn công diễn xuất 2 + ACT_EXP_ATTACK3, // Tấn công diễn xuất 3 + + // 80 + ACT_EXP_ATTACK4, // Tấn công diễn xuất 4 + ACT_EXP_DEFENCE, // Phòng thủ + ACT_EXP_FALL, // Té ngã + ACT_EXP_FALLONGROUND, // Ngã xuống đất + ACT_EXP_LOOKAROUND, // Nhìn quanh + + // 85 + ACT_EXP_DANCE, // Nhảy múa + ACT_EXP_FASHIONWEAPON, // Động tác vũ khí thời trang + ACT_USEITEM, // Dùng item + ACT_USEITMELOOP, // Dùng item (loop) + ACT_TWO_KISS, // Hôn đôi + + // 90 + ACT_USING_TARGET_ITEM, // Dùng đạo cụ + ACT_SWIM_FOR_MOVESKILL, // Bơi trong lúc dùng skill di chuyển + + ACT_MAX, + ACT_CASTSKILL // Chỉ là placeholder cho skill actions + } + /* public void PlayAttackEffect(int idTarget, int idSkill, int skillLevel, int nDamage, + uint dwModifier, int nAttackSpeed, ref int piAttackTime*//* NULL *//*, int nSection = 0) + { + if (!IsAllResReady()) + return; + + if (idSkill == 0) + { + int idWeapon = IsShapeChanged() ? 0 : GetWeaponID(); + + int nTimeFly = 10; + if (idWeapon != 0) + { + // ¿´¿´ÊDz»ÊÇÔ¶³ÌÎäÆ÷ + DATA_TYPE dt = default; + WEAPON_ESSENCE? pWeapon = (WEAPON_ESSENCE)ElementDataManProvider.GetElementDataMan().get_data_ptr((uint)idWeapon, ID_SPACE.ID_SPACE_ESSENCE, ref dt); + + if (dt == DATA_TYPE.DT_WEAPON_ESSENCE && pWeapon != null && pWeapon.Value.require_projectile != 0) + { + nTimeFly = 700; + + if (m_aEquips[(int)EC_IvtrType.IndexOfIteminEquipmentInventory.EQUIPIVTR_PROJECTILE] != 0) + idWeapon = m_aEquips[(int)EC_IvtrType.IndexOfIteminEquipmentInventory.EQUIPIVTR_PROJECTILE]; + } + } + + if (CECAttacksMan.Instance.FindAttackByAttacker(GetPlayerInfo().cid)) + { + // Unity animation làm hộ r + //ClearComActFlagAllRankNodes(true); + } + + // melee attack + CECAttackEvent pAttack = CECAttacksMan.Instance.AddMeleeAttack( + GetPlayerInfo().cid, idTarget, idWeapon, dwModifier, nDamage, nTimeFly); + + if (pAttack != null) + { + if (!IsDead() && (dwModifier & (uint)MOD.MOD_RETORT) == 0 + && (dwModifier & (uint)MOD.MOD_ATTACK_AURA) == 0 + && PlayAttackAction(nAttackSpeed, piAttackTime, pAttack.m_bSignaled) + && (dwModifier & (uint)MOD.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) + { + if (CECAttackEvent * pAttack = attackerEvents.Find(idSkill, nSection)) + { + // Ãæ¹¥»÷µÄ·ÇµÚÒ»´ÎÉ˺¦ÏûÏ¢ + 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 bool PlayAttackAction(int nAttackSpeed, out int attackTime, ref bool? pActFlag) + { + attackTime = 0; + + if (m_pPlayerModel == null) + return false; + + int nRand = UnityEngine.Random.Range(0, 4); + string szAct = string.Empty; + + int weapon_type = GetShowingWeaponType(); + + int nTime1, nTime2; + int iAction = ACT_ATTACK_1 + nRand; + PLAYER_ACTION action = m_PlayerActions[iAction]; + + if (action.data == null || string.IsNullOrEmpty(action.data.action_prefix)) + return false; + + ShowWeaponByConfig(action.data); + + var pRightHandWeapon = GetRightHandWeapon(); + bool bHideFX = !CECOptimize.Instance.GFX.CanShowAttack(GetCharacterID(), GetClassID()); + + // ============================== + // Ground Attack + // ============================== + if (GetMoveEnv() == MOVEENV_GROUND) + { + // “起” 动作(挥起) + szAct = $"{action.data.action_prefix}_{action.data.action_weapon_suffix[weapon_type].suffix}Æð"; + PlayNonSkillActionWithName(iAction, szAct, true, 200, bHideFX, ref pActFlag, COMACT_FLAG_MODE_ONCE_MULTIIGNOREGFX); + + if (pRightHandWeapon != null && IsUsingMagicWeapon()) + pRightHandWeapon.PlayActionByName(_GenWeaponActionName(szAct, m_iGender), 1.0f, true, 200, true, iAction, bHideFX); + + nTime1 = m_pPlayerModel.GetComActTimeSpanByName(szAct); + + // “收” 动作(挥下) + szAct = $"{action.data.action_prefix}_{action.data.action_weapon_suffix[weapon_type].suffix}Âä"; + QueueNonSkillActionWithName(iAction, szAct, 0, false, bHideFX); + + if (pRightHandWeapon != null && IsUsingMagicWeapon()) + pRightHandWeapon.QueueAction(_GenWeaponActionName(szAct, m_iGender), 0, iAction, false, false, bHideFX); + + nTime2 = m_pPlayerModel.GetComActTimeSpanByName(szAct); + } + // ============================== + // Air Attack + // ============================== + else + { + string szActionMiddleName; + + if ((m_wingType == WINGTYPE_WING && IsFlying()) || + GetProfession() == PROF_ANGEL || + GetProfession() == PROF_ARCHOR || + GetProfession() == PROF_MONK || + GetProfession() == PROF_GHOST) + { + szActionMiddleName = "¿ÕÖгá°ò"; // tấn công trên không + } + else + { + szActionMiddleName = "¿ÕÖзɽ£"; // rơi xuống hoặc bay + } + + szAct = $"{action.data.action_prefix}_{szActionMiddleName}_{action.data.action_weapon_suffix[weapon_type].suffix}Æð"; + PlayNonSkillActionWithName(iAction, szAct, true, 200, bHideFX, ref pActFlag, COMACT_FLAG_MODE_ONCE_MULTIIGNOREGFX); + + if (pRightHandWeapon != null && IsUsingMagicWeapon()) + pRightHandWeapon.PlayActionByName(_GenWeaponActionName(szAct, m_iGender), 1.0f, true, 200, true, iAction, bHideFX); + + nTime1 = m_pPlayerModel.GetComActTimeSpanByName(szAct); + + szAct = $"{action.data.action_prefix}_{szActionMiddleName}_{action.data.action_weapon_suffix[weapon_type].suffix}Âä"; + QueueNonSkillActionWithName(iAction, szAct, 0, false, bHideFX); + + if (pRightHandWeapon != null && IsUsingMagicWeapon()) + pRightHandWeapon.QueueAction(_GenWeaponActionName(szAct, m_iGender), 0, iAction, false, false, bHideFX); + + nTime2 = m_pPlayerModel.GetComActTimeSpanByName(szAct); + } + + // ============================== + // Kết thúc bằng FightStand + // ============================== + PLAYER_ACTION stand_action = m_PlayerActions[ACT_FIGHTSTAND]; + szAct = $"{stand_action.data.action_prefix}_{stand_action.data.action_weapon_suffix[weapon_type].suffix}"; + + QueueNonSkillActionWithName(ACT_FIGHTSTAND, szAct, 300, false, bHideFX, true); + + if (pRightHandWeapon != null && IsUsingMagicWeapon()) + pRightHandWeapon.QueueAction(_GenWeaponActionName(szAct, m_iGender), 300, iAction, false, false, bHideFX, true); + + // ============================== + // Điều chỉnh tốc độ phát animation theo tốc độ tấn công + // ============================== + if (nAttackSpeed > 0) + { + float vScale = (nTime1 + nTime2) / (float)nAttackSpeed; + if (vScale > 0f) + { + m_pPlayerModel.SetPlaySpeed(vScale); + + if (pRightHandWeapon != null && IsUsingMagicWeapon()) + pRightHandWeapon.SetPlaySpeed(vScale); + } + } + + attackTime = nTime1 + nTime2; + + // ============================== + // Cập nhật vị trí weapon hanger (vũ khí) + // ============================== + UpdateWeaponHangerPosByAction(iAction); + + return true; + } + public int GetShowingWeaponType() + { + int weapon_type = 0; + if (CanShowFashionWeapon(m_uAttackType, m_iFashionWeaponType) && m_aEquips[EQUIPIVTR_FASHION_WEAPON] != 0) + { + weapon_type = (m_iFashionWeaponType == DEFAULT_ACTION_TYPE || !IsWeaponAttached()) ? + 10 : m_iFashionWeaponType; + } + else + { + weapon_type = (m_uAttackType == DEFAULT_ACTION_TYPE || !IsWeaponAttached()) ? + 10 : m_uAttackType; + } + return weapon_type; + } + public bool CanShowFashionWeapon(int weapon_type, int fashion_weapon_type) + { + return IsFashionWeaponTypeFit(weapon_type, fashion_weapon_type) && InFashionMode(); + } + public bool IsFashionWeaponTypeFit(int weapon_type, int fashion_weapon_type) + { + if (fashion_weapon_type < 0 || fashion_weapon_type >= NUM_WEAPON_TYPE) return false; + FASHION_WEAPON_CONFIG? pConfig = GetFashionConfig(); + if (null == pConfig) + { + BMLogger.LogError("CECPlayer::GetFashionConfig, Failed to load fashion weapon config"); + return false; + } + int fashion_weapon_mask = (int)pConfig.Value.action_mask[fashion_weapon_type]; + return (fashion_weapon_mask & (1 << GetWeaponType(weapon_type))) != 0; + } + public FASHION_WEAPON_CONFIG GetFashionConfig() + { + FASHION_WEAPON_CONFIG? pFashionConfig = null; + if (null == pFashionConfig) + { + elementdataman pDataMan = ElementDataManProvider.GetElementDataMan(); + DATA_TYPE DataType; + uint tid = pDataMan.get_first_data_id(ID_SPACE_CONFIG, DataType); + + while (tid) + { + if (DataType == DT_FASHION_WEAPON_CONFIG) + { + pFashionConfig = (FASHION_WEAPON_CONFIG*)pDataMan->get_data_ptr(tid, ID_SPACE_CONFIG, DataType); + break; + } + tid = pDataMan->get_next_data_id(ID_SPACE_CONFIG, DataType); + } + } + return pFashionConfig; + }*/ + public float GetTouchRadius() { return m_fTouchRad; } + // Is player in battle + public bool IsInBattle() { return m_iBattleCamp != Player_camp_in_battle.GP_BATTLE_CAMP_NONE; } + + // Check whether specified npc in a same battle camp + public bool InSameBattleCamp(CECNPC pNPC) + { + if (!pNPC || m_iBattleCamp == Player_camp_in_battle.GP_BATTLE_CAMP_NONE || + (m_iBattleCamp == Player_camp_in_battle.GP_BATTLE_CAMP_INVADER && !pNPC.IsInBattleInvaderCamp()) || + (m_iBattleCamp == Player_camp_in_battle.GP_BATTLE_CAMP_DEFENDER && !pNPC.IsInBattleDefenderCamp())) + return false; + + return true; + } + public bool IsInFactionPVP() => (m_factionPVPMask & 0x01) != 0; + public bool CanAttackFactionPVPMineCar() => (m_factionPVPMask & 0x02) != 0; + public bool CanAttackFactionPVPMineBase() => (m_factionPVPMask & 0x04) != 0; + + // Get basic properties + public ROLEBASICPROP GetBasicProps() { return m_BasicProps; } + + public int GetMoveStandAction(bool bMove, bool bFight = false) + { + int iMoveEnv = m_iMoveEnv; + //if (m_AttachMode != enumAttachNone) + //{ + // bFight = false; + // if (m_bHangerOn) + // iMoveEnv = MOVEENV_GROUND; + //} + + int iAction = (int)PLAYER_ACTION_TYPE.ACT_STAND; + + if (bMove) + { + // Play appropriate actions + if (iMoveEnv == (int)MoveEnvironment.MOVEENV_GROUND) + { + if (m_bWalkRun) + iAction = (int)PLAYER_ACTION_TYPE.ACT_RUN; + else + iAction = (int)PLAYER_ACTION_TYPE.ACT_WALK; + } + //else if (iMoveEnv == MOVEENV_AIR) + //{ + // //if (/*UsingWing()*/ m_wingType == WINGTYPE_WING) + // // iAction = ACT_FLY; + // //else + // // iAction = ACT_FLY_SWORD; + //} + //else if (iMoveEnv == MOVEENV_WATER) + //{ + // //if (CanCombineWithMoveForSkill()) + // //{ + // // iAction = ACT_SWIM_FOR_MOVESKILL; + // //} + // //else + // //{ + // // iAction = ACT_SWIM; + // //} + //} + } + else + { + // Play appropriate actions + if (iMoveEnv == (int)MoveEnvironment.MOVEENV_GROUND) + { + if (bFight) + iAction = (int)PLAYER_ACTION_TYPE.ACT_FIGHTSTAND; + else + iAction = (int)PLAYER_ACTION_TYPE.ACT_STAND; + } + //else if (iMoveEnv == MOVEENV_AIR) + //{ + // if (/*UsingWing()*/ m_wingType == WINGTYPE_WING) + // iAction = ACT_HANGINAIR; + // else + // iAction = ACT_HANGINAIR_SWORD; + //} + //else if (iMoveEnv == MOVEENV_WATER) + // iAction = ACT_HANGINWATER; + } + + return iAction; + } + + public float GetGroundSpeed() + { + // return m_bWalkRun ? g_pGame->GetConfigs()->GetHostRunSpeed() : m_ExtProps.mv.walk_speed; + return m_bWalkRun ? m_ExtProps.mv.run_speed : m_ExtProps.mv.walk_speed; + } + + // Get move environment + public int GetMoveEnv() { return m_iMoveEnv; } + public bool IsShapeChanged() { return m_iShape != 0; } + public int GetWeaponID() { return m_aEquips[(int)EC_IvtrType.IndexOfIteminEquipmentInventory.EQUIPIVTR_WEAPON] & 0xffff; } + public bool IsAllResReady() { return (m_dwResFlags & (uint)PlayerResourcesReadyFlag.RESFG_ALL) == (uint)PlayerResourcesReadyFlag.RESFG_ALL; } + // Get character ID + public int GetCharacterID(){ return m_PlayerInfo.cid; } +} +public struct PlayActionEvent +{ + public string AnimationName; + public PlayActionEvent(string animationName) + { + this.AnimationName = animationName; + } +} +[Serializable] +public struct INFO +{ + public int cid; // Character ID + public int crc_c; // customized data crc + public int crc_e; // Equipment data crc + public INFO(int cid, int crc_c, int crc_) + { + this.cid = cid; + this.crc_c = crc_c; + this.crc_e = crc_; + } +} +public enum PlayerResourcesReadyFlag + +{ + RESFG_SKELETON = 0x01, + RESFG_SKIN = 0x02, + RESFG_CUSTOM = 0x04, + RESFG_ASSEMBLED = 0x08, + RESFG_ALL = 0x0f, +}; +public static class Duel_state // Duel state +{ + public const int DUEL_ST_NONE = 0, + DUEL_ST_PREPARE = 1, + DUEL_ST_INDUEL = 2, + DUEL_ST_STOPPING = 3; +} + +//// Move mode +//public static class Move_Mode +//{ +// public const int MOVE_STAND = 0, +// MOVE_MOVE = 1, // Normal move, walk, run, swim or fly +// MOVE_JUMP = 2, +// MOVE_FREEFALL = 3, +// MOVE_SLIDE = 4; +//} \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Move/EC_Player.cs.meta b/Assets/PerfectWorld/Scripts/Move/EC_Player.cs.meta new file mode 100644 index 0000000000..165da5cb56 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Move/EC_Player.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: be4a22babee7846459b0421234a44c99 \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Network/EC_ManMessageMono.cs b/Assets/PerfectWorld/Scripts/Network/EC_ManMessageMono.cs index 76741ba3a6..57599c37b2 100644 --- a/Assets/PerfectWorld/Scripts/Network/EC_ManMessageMono.cs +++ b/Assets/PerfectWorld/Scripts/Network/EC_ManMessageMono.cs @@ -74,8 +74,8 @@ namespace BrewMonster if (!(pObject = EC_ManPlayer.GetPlayer(idObject))) return null; - if ((iAliveFlag == 1 && (pObject as CECPlayer).IsDead()) || - (iAliveFlag == 2 && !(pObject as CECPlayer).IsDead())) + if ((iAliveFlag == 1 && (pObject as EC_Player).IsDead()) || + (iAliveFlag == 2 && !(pObject as EC_Player).IsDead())) return null; } //else if (GPDataTypeHelper.ISMATTERID(idObject)) diff --git a/Assets/PerfectWorld/Scripts/PlayerState/PlayerIdleState.cs b/Assets/PerfectWorld/Scripts/PlayerState/PlayerIdleState.cs index 00f87ae540..dab799fc4a 100644 --- a/Assets/PerfectWorld/Scripts/PlayerState/PlayerIdleState.cs +++ b/Assets/PerfectWorld/Scripts/PlayerState/PlayerIdleState.cs @@ -1,5 +1,5 @@ using UnityEngine; -using static CECPlayer; +using static EC_Player; public class PlayerIdleState : PlayerState { diff --git a/Assets/PerfectWorld/Scripts/PlayerState/PlayerMoveState.cs b/Assets/PerfectWorld/Scripts/PlayerState/PlayerMoveState.cs index b46ef1e484..e82e7f53a4 100644 --- a/Assets/PerfectWorld/Scripts/PlayerState/PlayerMoveState.cs +++ b/Assets/PerfectWorld/Scripts/PlayerState/PlayerMoveState.cs @@ -1,5 +1,5 @@ using UnityEngine; -using static CECPlayer; +using static EC_Player; public class PlayerMoveState : PlayerState { diff --git a/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs b/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs index 5d124ade08..58c64ecb0d 100644 --- a/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs +++ b/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs @@ -7,7 +7,7 @@ using UnityEngine; namespace PerfectWorld.Scripts.Player { - public class EC_ElsePlayer : CECPlayer + public class EC_ElsePlayer : EC_Player { A3DVECTOR3 m_vMoveDir; // Player's velocity A3DVECTOR3 m_vServerPos; // Player's real position on server diff --git a/Assets/Scripts/CECHostPlayer.cs b/Assets/Scripts/CECHostPlayer.cs index 97facee398..1a6d6af783 100644 --- a/Assets/Scripts/CECHostPlayer.cs +++ b/Assets/Scripts/CECHostPlayer.cs @@ -21,7 +21,7 @@ using UnityEngine.SceneManagement; using UnityEngine.UI; using Scene = UnityEngine.SceneManagement.Scene; -public class CECHostPlayer : CECPlayer +public class CECHostPlayer : EC_Player { [SerializeField] private TextMeshPro txtName; [SerializeField] private CharacterController controller; diff --git a/Assets/Scripts/EC_Utility.cs b/Assets/Scripts/EC_Utility.cs index ec337ae60d..d1ef9f4cfb 100644 --- a/Assets/Scripts/EC_Utility.cs +++ b/Assets/Scripts/EC_Utility.cs @@ -4,7 +4,7 @@ using System; using System.Collections; using System.Runtime.InteropServices; using UnityEngine; -using static CECPlayer; +using static EC_Player; public static class EC_Utility { diff --git a/Assets/Scripts/GameController.cs b/Assets/Scripts/GameController.cs index 1a1f7dcfe9..bdd3c803f6 100644 --- a/Assets/Scripts/GameController.cs +++ b/Assets/Scripts/GameController.cs @@ -54,7 +54,7 @@ public class GameController : MonoBehaviour Debug.LogError("null prefab"); return; } - CECPlayer.InitStaticRes(); + EC_Player.InitStaticRes(); hostPlayer = Instantiate(characterPrefab, transform); hostPlayer.InitCharacter(info); cinemachineCamera.Follow = hostPlayer.transform; diff --git a/Assets/Scripts/InitializePlayer.cs b/Assets/Scripts/InitializePlayer.cs index ad87a38c5f..74f9de84a2 100644 --- a/Assets/Scripts/InitializePlayer.cs +++ b/Assets/Scripts/InitializePlayer.cs @@ -5,11 +5,11 @@ public class InitializePlayer /*: IAutoInitialize*/ { public void Dispose() { - CECPlayer.Dispose(); + EC_Player.Dispose(); } public void Initialize() { - CECPlayer.InitStaticRes(); + EC_Player.InitStaticRes(); } } diff --git a/Assets/Scripts/PlayerVisual.cs b/Assets/Scripts/PlayerVisual.cs index 1046364ce4..08fab98c64 100644 --- a/Assets/Scripts/PlayerVisual.cs +++ b/Assets/Scripts/PlayerVisual.cs @@ -23,7 +23,7 @@ public class PlayerVisual : MonoBehaviour BrewMonster.BMLogger.LogError("animancer == null"); return; } - var player = GetComponentInParent(); + var player = GetComponentInParent(); if(player == null) { BrewMonster.BMLogger.LogError("player == null");