1366 lines
47 KiB
C#
1366 lines
47 KiB
C#
using Animancer;
|
|
using BrewMonster;
|
|
using BrewMonster.Managers;
|
|
using BrewMonster.Scripts;
|
|
using BrewMonster.Scripts.Managers;
|
|
using CSNetwork.GPDataType;
|
|
using ModelRenderer.Scripts.GameData;
|
|
using PerfectWorld.Scripts.Managers;
|
|
using PerfectWorld.Scripts.Player;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using System.Xml.Linq;
|
|
using BrewMonster.PerfectWorld.Scripts.Vfx;
|
|
using BrewMonster.Scripts;
|
|
using TMPro;
|
|
using Unity.VisualScripting;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
using BrewMonster.Network;
|
|
|
|
public abstract partial class CECPlayer : CECObject
|
|
{
|
|
[SerializeField] protected Transform parentModel;
|
|
[SerializeField] protected TextMeshProUGUI txtName;
|
|
|
|
private static PLAYER_ACTION[] _default_actions;
|
|
private static PLAYER_ACTION[] _turning_actions;
|
|
PLAYER_ACTION[] m_PlayerActions;
|
|
[SerializeField] internal INFO m_PlayerInfo;
|
|
protected GameObject _pPlayerModel;
|
|
protected float rotationSpeed = 5;
|
|
internal int m_iMoveMode; // Player's move mode
|
|
[SerializeField] internal int m_idSelTarget;
|
|
[SerializeField] internal int m_idCurHover; // ID of object under cursor
|
|
protected int m_iShape; // �癒���聶簣礙繕�ID
|
|
protected uint m_dwStates; // Player's basic states
|
|
|
|
// 敶枏��餃稬�孵� // Action type for attack animation
|
|
protected uint m_uAttackType;
|
|
protected int[] m_aEquips;
|
|
protected ROLEEXTPROP m_ExtProps; // Extend properties
|
|
protected int m_iFashionWeaponType;
|
|
protected float m_fTouchRad = 0.3f; // Touch radius
|
|
protected bool m_bWeaponAttached;
|
|
protected bool m_bFight;
|
|
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 = new A3DAABB(); // �禱繚臘�簽�繩簣瞿糧��罈��繕�aabb瞿竅 簡罈���繭繚��簞�穫
|
|
public A3DAABB m_aabb = new A3DAABB(); // Player's aabb瞿竅�������職繕�aabb瞿竅���繭繚��簞�穫
|
|
public int m_iProfession; // Profession
|
|
public float m_fScaleBySkill;
|
|
public int m_iGender; // Gender
|
|
protected bool m_bFashionMode;
|
|
public bool m_bShowWeapon;
|
|
private QueueActionEvent queueActionEvent;
|
|
protected static PLAYER_LEVELEXP_CONFIG _player_levelup_exp;
|
|
|
|
protected int NUM_WEAPON_TYPE = 15;
|
|
public static readonly int[] m_sciStateIDForStateAction = { 117 };
|
|
|
|
protected int m_iBoothState = 0; // Booth state. 0, none; 1, prepare; 2, open booth; 3, visite other's booth
|
|
public int m_idFRole = GNETRoles._R_UNMEMBER; // ID of player's faction role
|
|
protected int m_idCountry = 0; // 繒繳�翻�籀�穠 id
|
|
public static int MAX_REINCARNATION = 2;
|
|
protected List<int> m_aCurEffects = new List<int>(); // Current effects
|
|
byte m_ReincarnationCount = 0;
|
|
string m_strName; // Player name
|
|
|
|
public MOVECONST m_MoveConst; // Const used when moving control
|
|
public Move_Mode m_MoveMode;
|
|
public MOVECONST[] aMoveConsts = new MOVECONST[PROFESSION.NUM_PROFESSION * GENDER.NUM_GENDER]
|
|
{
|
|
// �瓣��
|
|
// fStepHei fMinAirHei fMinWaterHei fShoreDepth fWaterSurf
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
|
|
// 繚穡�礎
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
|
|
// ���礎
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
|
|
// �羸職竄
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
|
|
// �羸��
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.8f, 0.7f),
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
|
|
// 織�聶�
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
|
|
// �簸�瞽
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
|
|
// �簸�矇
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
|
|
// 翻瞿�矇
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
|
|
// 繩��矇
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
|
|
// �繒�簞
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
|
|
// ����
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
|
|
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
|
|
};
|
|
|
|
public A3DVECTOR3[] aExts = new A3DVECTOR3[PROFESSION.NUM_PROFESSION * GENDER.NUM_GENDER]
|
|
{
|
|
new A3DVECTOR3(0.4f, 0.9f, 0.4f), // �瓣��
|
|
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
|
|
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // 繚穡�礎
|
|
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
|
|
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // ���礎
|
|
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
|
|
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // �羸職竄
|
|
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
|
|
new A3DVECTOR3(0.5f, 1.05f, 0.5f), // �羸��
|
|
new A3DVECTOR3(0.3f, 0.9f, 0.3f),
|
|
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // 織�聶�
|
|
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
|
|
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // �簸�瞽
|
|
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
|
|
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // �簸�矇
|
|
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
|
|
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // 翻瞿�矇
|
|
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
|
|
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // 繩��矇
|
|
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
|
|
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // �繒�簞
|
|
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
|
|
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // ����
|
|
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
|
|
};
|
|
|
|
public static class Effect_type
|
|
{
|
|
public const int EFF_FACEPILL = 1;
|
|
}
|
|
private BaseVfxObject _levelUpVfx;
|
|
|
|
protected void Awake()
|
|
{
|
|
m_PlayerActions = _default_actions;
|
|
m_iShape = 0;
|
|
m_aEquips = new int[(int)IndexOfIteminEquipmentInventory.SIZE_ALL_EQUIPIVTR];
|
|
queueActionEvent = new QueueActionEvent("", null, false, null);
|
|
}
|
|
|
|
/// <summary>This function will get the coressponding model player for the player based on the profession and gender </summary>
|
|
public async Task SetPlayerModel(byte profession, byte gender)
|
|
{
|
|
parentModel = transform.GetChild(0);
|
|
txtName = GetComponentInChildren<TextMeshProUGUI>();
|
|
|
|
_pPlayerModel = await NPCManager.Instance.GetModelPlayer(profession, gender);
|
|
Scene scene = SceneManager.GetActiveScene();
|
|
SceneManager.MoveGameObjectToScene(_pPlayerModel, scene);
|
|
_pPlayerModel.transform.SetParent(parentModel);
|
|
_pPlayerModel.transform.localPosition = Vector3.zero;
|
|
_pPlayerModel.SetActive(true);
|
|
}
|
|
public virtual void SetUpPlayer()
|
|
{
|
|
m_dwResFlags = 0;
|
|
m_iFashionWeaponType = -1;
|
|
m_uAttackType = DEFAULT_ACTION_TYPE;
|
|
|
|
AttachWeapon();
|
|
}
|
|
|
|
public void SetPlayerInfor(INFO playinfo)
|
|
{
|
|
m_PlayerInfo = playinfo;
|
|
}
|
|
|
|
public INFO GetPlayInfo()
|
|
{
|
|
return m_PlayerInfo;
|
|
}
|
|
|
|
public void CalcPlayerAABB()
|
|
{
|
|
int iIndex = m_iProfession * GENDER.NUM_GENDER + m_iGender;
|
|
|
|
m_aabb.Extents = aExts[iIndex] * m_fScaleBySkill;
|
|
m_aabbServer.Extents = aExts[iIndex];
|
|
m_MoveConst = aMoveConsts[iIndex];
|
|
}
|
|
|
|
|
|
public static async Task<bool> LoadPlayerSkin(GameObject aSkins, int index, string szFile)
|
|
{
|
|
// these are LOD suffix
|
|
string[] suffix1 = {"銝�蝥?", "鈭𣬚漣", "銝厩漣"};
|
|
string[] suffix2 = {"", "鈭𣬚漣", "銝厩漣"};
|
|
|
|
string szSkinFile = "";
|
|
|
|
if( index == EC_Player_Skin_Const.SKIN_BODY_INDEX || index == EC_Player_Skin_Const.SKIN_HEAD_INDEX )
|
|
szSkinFile = $"{szFile}{suffix2[0]}";
|
|
else
|
|
szSkinFile = $"{szFile}{suffix1[0]}";
|
|
|
|
aSkins = await AddressableManager.Instance.LoadPrefabAsync(szSkinFile);
|
|
|
|
if (aSkins == null)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
public static void InitStaticRes()
|
|
{
|
|
BuildActionList();
|
|
DATA_TYPE dt = default;
|
|
_player_levelup_exp = (PLAYER_LEVELEXP_CONFIG)ElementDataManProvider.GetElementDataMan()
|
|
.get_data_ptr(202, ID_SPACE.ID_SPACE_CONFIG, ref dt);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
public int GetCharacterID()
|
|
{
|
|
return m_PlayerInfo.cid;
|
|
}
|
|
|
|
|
|
private static void BuildActionList()
|
|
{
|
|
if (_default_actions == null)
|
|
{
|
|
// thay cho hashtab trong C++
|
|
Dictionary<string, PLAYER_ACTION_INFO_CONFIG> actionMap =
|
|
new Dictionary<string, PLAYER_ACTION_INFO_CONFIG>(100);
|
|
|
|
Dictionary<string, PLAYER_ACTION_INFO_CONFIG> skillActionMap =
|
|
new Dictionary<string, PLAYER_ACTION_INFO_CONFIG>(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;
|
|
}
|
|
|
|
protected override void Update()
|
|
{
|
|
base.Update();
|
|
}
|
|
|
|
public enum PLAYER_ACTION_TYPE
|
|
{
|
|
// 0
|
|
ACT_STAND = 0, // �廙姊g
|
|
ACT_FIGHTSTAND, // �廙姊g chi廕積 �廕?u
|
|
ACT_WALK, // �i b廙?
|
|
ACT_RUN, // Ch廕?y
|
|
ACT_JUMP_START, // B廕眩 �廕?u nh廕?y
|
|
|
|
// 5
|
|
ACT_JUMP_LOOP, // Nh廕?y tr礙n kh繫ng l廕搆 l廕?i
|
|
ACT_JUMP_LAND, // Nh廕?y ti廕穆 �廕?t
|
|
ACT_SWIM, // B①i
|
|
ACT_HANGINWATER, // L① l廙要g trong n⑹廙𢲷
|
|
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廙𤉋g cao (should be ACT_FLYDOWN_WING_HIGH)
|
|
ACT_FLYDOWN_WING_LOW, // Bay xu廙𤉋g th廕?p (should be ACT_FLYDOWN_WING_LOW)
|
|
ACT_LANDON, // H廕? c獺nh (should be ACT_LAND_WING)
|
|
|
|
// 15
|
|
ACT_TAKEOFF_SWORD, // Ki廕禦 bay - c廕?t c獺nh
|
|
ACT_HANGINAIR_SWORD, // Ki廕禦 bay - treo kh繫ng trung
|
|
ACT_FLY_SWORD, // Ki廕禦 bay - ti廕積 t廙𢹂
|
|
ACT_FLYDOWN_SWORD_HIGH, // Ki廕禦 bay - r①i cao
|
|
ACT_FLYDOWN_SWORD_LOW, // Ki廕禦 bay - r①i th廕?p
|
|
|
|
// 20
|
|
ACT_LANDON_SWORD, // Ki廕禦 bay - h廕? c獺nh
|
|
ACT_SITDOWN, // Ng廙𧗽
|
|
ACT_SITDOWN_LOOP, // Ng廙𧗽 l廕搆 l廕?i
|
|
ACT_STANDUP, // �廙姊g d廕軌
|
|
ACT_WOUNDED, // B廙? th⑹①ng
|
|
|
|
// 25
|
|
ACT_GROUNDDIE, // Ch廕篙 tr礙n m廕暗 �廕?t
|
|
ACT_GROUNDDIE_LOOP, // Ch廕篙 tr礙n �廕?t (loop)
|
|
ACT_WATERDIE, // Ch廕篙 trong n⑹廙𢲷
|
|
ACT_WATERDIE_LOOP, // Ch廕篙 trong n⑹廙𢲷 (loop)
|
|
ACT_AIRDIE_ST, // Ch廕篙 tr礙n kh繫ng (b廕眩 �廕?u)
|
|
|
|
// 30
|
|
ACT_AIRDIE, // Ch廕篙 tr礙n kh繫ng (loop r①i)
|
|
ACT_AIRDIE_ED, // Ch廕篙 tr礙n kh繫ng (ch廕?m �廕?t)
|
|
ACT_AIRDIE_LAND_LOOP, // Ch廕篙 r①i �廕?t (loop)
|
|
ACT_REVIVE, // H廙𧗽 sinh
|
|
ACT_CUSTOMIZE, // �廙㷌g t獺c t羅y ch廙纤h
|
|
|
|
// 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廙𧗽 �廙姊g d廕軌
|
|
ACT_PICKUP, // Nh廕暗 �廙?
|
|
|
|
// 40
|
|
ACT_PICKUP_LOOP, // Nh廕暗 �廙? (loop)
|
|
ACT_PICKUP_STANDUP, // Nh廕暗 �廙? �廙姊g d廕軌
|
|
ACT_PICKUP_MATTER, // Nh廕暗 v廕負 th廙?
|
|
ACT_GAPE, // H獺 mi廙𡵞g
|
|
ACT_LOOKAROUND, // Nh穫n quanh
|
|
|
|
// 45
|
|
ACT_PLAYWEAPON, // Vung v觼 kh穩
|
|
ACT_EXP_WAVE, // V廕咳 tay
|
|
ACT_EXP_NOD, // G廕負 �廕?u
|
|
ACT_EXP_SHAKEHEAD, // L廕畚 �廕?u
|
|
ACT_EXP_SHRUG, // Nh繳n vai
|
|
|
|
// 50
|
|
ACT_EXP_LAUGH, // C⑹廙𩥉 l廙𣌟
|
|
ACT_EXP_ANGRY, // T廙妾 gi廕要
|
|
ACT_EXP_STUN, // Cho獺ng
|
|
ACT_EXP_DEPRESSED, // Bu廙忛 b瓊
|
|
ACT_EXP_KISSHAND, // H繫n tay
|
|
|
|
// 55
|
|
ACT_EXP_SHY, // Ng廕?i ng羅ng
|
|
ACT_EXP_SALUTE, // Ch�o
|
|
ACT_EXP_SITDOWN, // Ng廙𧗽 xu廙𤉋g
|
|
ACT_EXP_SITDOWN_LOOP, // Ng廙𧗽 xu廙𤉋g (loop)
|
|
ACT_EXP_SITDOWN_STANDUP, // Ng廙𧗽 xu廙𤉋g r廙𧗽 �廙姊g d廕軌
|
|
|
|
// 60
|
|
ACT_EXP_ASSAULT, // T廕?n c繫ng
|
|
ACT_EXP_THINK, // Suy ngh藺
|
|
ACT_EXP_DEFIANCE, // Th獺ch th廙妾
|
|
ACT_EXP_VICTORY, // Chi廕積 th廕疸g
|
|
ACT_EXP_KISS, // H繫n
|
|
|
|
// 65
|
|
ACT_EXP_KISS_LOOP, // H繫n (loop)
|
|
ACT_EXP_KISS_END, // K廕篙 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廕禦 bay - l⑹廙?n
|
|
ACT_EXP_FIGHT, // T⑹ th廕? chi廕積 �廕?u
|
|
ACT_EXP_ATTACK1, // T廕?n c繫ng di廙� xu廕?t 1
|
|
ACT_EXP_ATTACK2, // T廕?n c繫ng di廙� xu廕?t 2
|
|
ACT_EXP_ATTACK3, // T廕?n c繫ng di廙� xu廕?t 3
|
|
|
|
// 80
|
|
ACT_EXP_ATTACK4, // T廕?n c繫ng di廙� xu廕?t 4
|
|
ACT_EXP_DEFENCE, // Ph簷ng th廙?
|
|
ACT_EXP_FALL, // T矇 ng瓊
|
|
ACT_EXP_FALLONGROUND, // Ng瓊 xu廙𤉋g �廕?t
|
|
ACT_EXP_LOOKAROUND, // Nh穫n quanh
|
|
|
|
// 85
|
|
ACT_EXP_DANCE, // Nh廕?y m繳a
|
|
ACT_EXP_FASHIONWEAPON, // �廙㷌g t獺c v觼 kh穩 th廙𩥉 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廙�
|
|
|
|
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, int nSection = 0)
|
|
{
|
|
if (!IsAllResReady())
|
|
return;
|
|
|
|
if (idSkill == 0)
|
|
{
|
|
int idWeapon = IsShapeChanged() ? 0 : GetWeaponID();
|
|
|
|
int nTimeFly = 10;
|
|
if (idWeapon != 0)
|
|
{
|
|
// 聶織聶織��簡罈���繞糧��瓣�繩
|
|
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)IndexOfIteminEquipmentInventory.EQUIPIVTR_PROJECTILE] != 0)
|
|
idWeapon = m_aEquips[(int)IndexOfIteminEquipmentInventory.EQUIPIVTR_PROJECTILE];
|
|
}
|
|
}
|
|
|
|
if (CECAttacksMan.Instance.FindAttackByAttacker(GetPlayerInfo().cid))
|
|
{
|
|
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, ref piAttackTime, pAttack)
|
|
&& (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 pAttack1 = 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 pAttack1 = attackerEvents.Find(idSkill, nSection);
|
|
// if (pAttack1 != null)
|
|
// {
|
|
// // �疆繒瞼罈繩繕�繚�繕��罈織���繙礎�羶�瞽
|
|
// pAttack1.AddTarget(idTarget, dwModifier, nDamage);
|
|
// goto EXIT;
|
|
// }
|
|
// else
|
|
// {
|
|
// attackerEvents.Signal();
|
|
// }
|
|
// }
|
|
// if (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;
|
|
//}
|
|
}
|
|
|
|
protected void ClearComActFlagAllRankNodes(bool v)
|
|
{
|
|
EventBus.PublishChannel(m_PlayerInfo.cid, new ClearComActFlagAllRankNodesEvent(v));
|
|
}
|
|
|
|
public struct ClearComActFlagAllRankNodesEvent
|
|
{
|
|
public bool v;
|
|
|
|
public ClearComActFlagAllRankNodesEvent(bool value)
|
|
{
|
|
v = value;
|
|
}
|
|
}
|
|
|
|
public bool PlayAttackAction(int nAttackSpeed, ref int attackTime, CECAttackEvent attackEvent)
|
|
{
|
|
//attackTime = 0;
|
|
|
|
//if (_pPlayerModel == null)
|
|
// return false;
|
|
|
|
int nRand = UnityEngine.Random.Range(0, 4);
|
|
string szAct = string.Empty;
|
|
|
|
int weapon_type = GetShowingWeaponType();
|
|
|
|
int nTime1 = 0, nTime2 = 0;
|
|
int iAction = (int)PLAYER_ACTION_TYPE.ACT_ATTACK_1 + nRand;
|
|
PLAYER_ACTION action = m_PlayerActions[iAction];
|
|
|
|
if (string.IsNullOrEmpty(action.data.ActionPrefix))
|
|
return false;
|
|
|
|
ShowWeaponByConfig(action.data);
|
|
|
|
/* var pRightHandWeapon = GetRightHandWeapon();
|
|
bool bHideFX = !CECOptimize.Instance.GFX.CanShowAttack(GetCharacterID(), GetClassID());*/
|
|
// ==============================
|
|
// Ground Attack
|
|
// ==============================
|
|
if (GetMoveEnv() == (int)MoveEnvironment.MOVEENV_GROUND)
|
|
{
|
|
|
|
// �𡏭絲�? �其�嚗�泿韏瘀�
|
|
szAct = EC_Utility.BuildActionName(action, weapon_type, "�簸");
|
|
EventBus.PublishChannel(m_PlayerInfo.cid, new PlayActionEvent(szAct));
|
|
szAct = EC_Utility.BuildActionName(action, weapon_type, "�瓣");
|
|
queueActionEvent.SetData(szAct, SetApplyDamage, true, attackEvent);
|
|
EventBus.PublishChannelClass(m_PlayerInfo.cid, queueActionEvent);
|
|
//PlayNonSkillActionWithName(iAction, szAct, true, 200, true, ref pActFlag, COMACT_FLAG_MODE_ONCE_MULTIIGNOREGFX);gag獺ga
|
|
/*
|
|
if (pRightHandWeapon != null && IsUsingMagicWeapon())
|
|
pRightHandWeapon.PlayActionByName(_GenWeaponActionName(szAct, m_iGender), 1.0f, true, 200, true, iAction, bHideFX);
|
|
|
|
nTime1 = _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 = _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廙𤉋g ho廕搾 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廕篙 th繳c b廕彫g FightStand
|
|
// ==============================
|
|
PLAYER_ACTION stand_action = m_PlayerActions[(int)PLAYER_ACTION_TYPE.ACT_FIGHTSTAND];
|
|
szAct = EC_Utility.BuildActionName(stand_action, 0);
|
|
queueActionEvent.SetData(szAct, SetApplyDamage, false, attackEvent);
|
|
EventBus.PublishChannelClass(m_PlayerInfo.cid, queueActionEvent);
|
|
|
|
/* 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廙� ch廙纤h t廙倴 �廙? ph獺t animation theo t廙倴 �廙? 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廕計 nh廕負 v廙? tr穩 weapon hanger (v觼 kh穩)
|
|
// ==============================
|
|
//UpdateWeaponHangerPosByAction(iAction);
|
|
|
|
return true;
|
|
}
|
|
|
|
public void SetApplyDamage(bool isApplyDamage, CECAttackEvent cECAttackEvent)
|
|
{
|
|
cECAttackEvent.m_bSignaled = isApplyDamage;
|
|
}
|
|
|
|
public void ShowWeaponByConfig(PLAYER_ACTION_INFO_CONFIG p)
|
|
{
|
|
m_bShowWeapon = p.hide_weapon != 0 ? false : true;
|
|
//ShowWeapon(m_bShowWeapon);
|
|
}
|
|
|
|
public int GetShowingWeaponType()
|
|
{
|
|
//todo: mr Hoang should double check it
|
|
return 10;
|
|
|
|
int weapon_type = 0;
|
|
if (CanShowFashionWeapon((int)m_uAttackType, m_iFashionWeaponType) &&
|
|
m_aEquips[(int)IndexOfIteminEquipmentInventory.EQUIPIVTR_FASHION_WEAPON] != 0)
|
|
{
|
|
weapon_type = (EC_Utility.BinaryEquals(m_iFashionWeaponType, DEFAULT_ACTION_TYPE) || !IsWeaponAttached())
|
|
? 10
|
|
: m_iFashionWeaponType;
|
|
}
|
|
else
|
|
{
|
|
weapon_type = (EC_Utility.BinaryEquals(m_uAttackType, DEFAULT_ACTION_TYPE) || !IsWeaponAttached()) ? 10 : (int)m_uAttackType;
|
|
}
|
|
|
|
return weapon_type;
|
|
}
|
|
|
|
public bool IsWeaponAttached()
|
|
{
|
|
return m_bWeaponAttached;
|
|
}
|
|
bool AttachWeapon(){
|
|
bool result = (false);
|
|
|
|
/*while (GetPlayerModel() && (GetLeftHandWeapon() || GetRightHandWeapon())){
|
|
A3DSkinModel *pSkinModel = GetPlayerModel()->GetA3DSkinModel();
|
|
if (!pSkinModel ||
|
|
!pSkinModel->GetSkeleton()){
|
|
break;
|
|
}
|
|
if (!pSkinModel->GetSkeletonHook(GetLeftWeaponHookPos(m_weaponHangerPos),true) ||
|
|
!pSkinModel->GetSkeletonHook(GetRightWeaponHookPos(m_weaponHangerPos),true)){
|
|
break;
|
|
}
|
|
if (GetLeftHandWeapon()){
|
|
GetPlayerModel()->AddChildModel(
|
|
_left_hand_weapon,
|
|
false,
|
|
GetLeftWeaponHookPos(m_weaponHangerPos),
|
|
GetLeftHandWeapon(),
|
|
GetLeftWeaponOwnHookPos(GetLeftHandWeapon()));
|
|
}
|
|
if (GetRightHandWeapon()){
|
|
GetPlayerModel()->AddChildModel(
|
|
_right_hand_weapon,
|
|
false,
|
|
GetRightWeaponHookPos(m_weaponHangerPos),
|
|
GetRightHandWeapon(),
|
|
GetRightWeaponOwnHookPos(GetRightHandWeapon()));
|
|
}
|
|
ALog log;
|
|
log.Init("EC.log", "My Application Log");
|
|
|
|
// Anywhere in your code where you want to see the call flow:
|
|
log.Log("[HoangDev]Checking execution flow at this point:");
|
|
log.LogStackTrace();
|
|
|
|
log.Release();
|
|
m_bWeaponAttached = true;
|
|
result = true;
|
|
break;
|
|
}*/
|
|
m_bWeaponAttached = true;
|
|
result = true;
|
|
return result;
|
|
}
|
|
public bool InFashionMode()
|
|
{
|
|
return m_bFashionMode;
|
|
}
|
|
|
|
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 = DATA_TYPE.DT_FASHION_WEAPON_CONFIG;
|
|
uint tid = pDataMan.get_id_with_data_type(ID_SPACE.ID_SPACE_CONFIG, DataType);
|
|
|
|
if (tid != 0)
|
|
{
|
|
pFashionConfig =
|
|
(FASHION_WEAPON_CONFIG)pDataMan.get_data_ptr(tid, ID_SPACE.ID_SPACE_CONFIG, ref DataType);
|
|
BMLogger.LogError($"HoangDev : get_data_ptr {pFashionConfig.GetType()}");
|
|
}
|
|
}
|
|
|
|
return pFashionConfig == null ? default : pFashionConfig.Value;
|
|
}
|
|
|
|
public int GetSelectedTarget()
|
|
{
|
|
return m_idSelTarget;
|
|
}
|
|
|
|
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 const uint DEFAULT_ACTION_TYPE = 0xFFFFFFFF;
|
|
|
|
public static int GetWeaponType(int iWeaponType)
|
|
{
|
|
return iWeaponType == DEFAULT_ACTION_TYPE ? 10 : iWeaponType;
|
|
}
|
|
|
|
public bool IsInFactionPVP() => (m_factionPVPMask & 0x01) != 0;
|
|
public bool CanAttackFactionPVPMineCar() => (m_factionPVPMask & 0x02) != 0;
|
|
public bool CanAttackFactionPVPMineBase() => (m_factionPVPMask & 0x04) != 0;
|
|
|
|
public int GetLevelUpExp(int iLevel)
|
|
{
|
|
return _player_levelup_exp.exp[iLevel - 1];
|
|
//return iLevel * iLevel * 500;
|
|
}
|
|
|
|
// Get basic properties
|
|
public ROLEBASICPROP GetBasicProps()
|
|
{
|
|
return m_BasicProps;
|
|
}
|
|
|
|
public override void TurnFaceTo(int idTarget, float dwTime = 200)
|
|
{
|
|
if (idTarget != 0)
|
|
{
|
|
if (idTarget == GetCharacterID())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (IsWorkMoveRunning() /*&& !IsPlayingCastingSkillAndMoveActions()*/)
|
|
{
|
|
// ��繞簪�簣�罈簞瓊�礎�疆�簷��繞簪繚翻�簷癒瞽�罈����繞簪�穢繚穡��簡��穠�簷
|
|
return;
|
|
}
|
|
}
|
|
|
|
var target = EC_ManMessageMono.Instance?.GetObject(idTarget, 0)?.gameObject.transform;
|
|
if (target == null)
|
|
{
|
|
BMLogger.LogError("HoangDev: ko c籀 transform ");
|
|
return;
|
|
}
|
|
|
|
Vector3 direction = (target.position - transform.position).normalized;
|
|
direction.y = 0f;
|
|
int turnSpeed = 5;
|
|
if (direction.sqrMagnitude > 0.001f)
|
|
{
|
|
// T廕?o rotation m廙𢹂 h⑹廙𣌟g t廙𢹂 target
|
|
Quaternion targetRotation = Quaternion.LookRotation(direction, Vector3.up);
|
|
|
|
// Xoay m⑹廙?t t廙? rotation hi廙𡵞 t廕?i sang rotation m廙?c ti礙u
|
|
//transform.rotation = Quaternion.Slerp(
|
|
// transform.rotation,
|
|
// targetRotation,
|
|
// Time.deltaTime * turnSpeed
|
|
//);
|
|
transform.rotation = targetRotation;
|
|
}
|
|
}
|
|
|
|
public virtual bool IsWorkMoveRunning()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/* public bool IsPlayingCastingSkillAndMoveActions()
|
|
{
|
|
return IsPlayingCastingSkillAction() && IsPlayingMoveAction();
|
|
}
|
|
public bool IsPlayingCastingSkillAction()
|
|
{
|
|
return m_pActionController ? m_pActionController.IsPlayingCastingSkillAction() : false;
|
|
}
|
|
bool IsPlayingMoveAction()
|
|
{
|
|
return m_pActionController ? m_pActionController.IsPlayingMoveAction() : false;
|
|
}*/
|
|
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 void Damaged(int nDamage, uint dwModifier = 0, int skill = 0)
|
|
{
|
|
if (nDamage == -2)
|
|
{
|
|
// this message is caused by a help skill, so don't use a wounded action here
|
|
/* if (dwModifier & CECAttackEvent::MOD_IMMUNE)
|
|
BubbleText(BUBBLE_IMMUNE, 0);
|
|
else if (dwModifier & CECAttackEvent::MOD_NULLITY)
|
|
BubbleText(BUBBLE_INVALIDHIT, 0);
|
|
else if (dwModifier & CECAttackEvent::MOD_DODGE_DEBUFF)
|
|
BubbleText(BUBBLE_DODGE_DEBUFF, 0);*/
|
|
}
|
|
else if (nDamage == -1)
|
|
{
|
|
// when else player hit this player iDamage is -1,
|
|
// Just play a wounded action
|
|
if (!OnDamaged(skill))
|
|
{
|
|
// PlayAction((int)PLAYER_ACTION_TYPE.ACT_WOUNDED);
|
|
}
|
|
/*if (dwModifier & CECAttackEvent::MOD_IMMUNE)
|
|
BubbleText(BUBBLE_IMMUNE, 0);
|
|
else if (dwModifier & CECAttackEvent::MOD_NULLITY)
|
|
BubbleText(BUBBLE_INVALIDHIT, 0);
|
|
else if (dwModifier & CECAttackEvent::MOD_DODGE_DEBUFF)
|
|
BubbleText(BUBBLE_DODGE_DEBUFF, 0);*/
|
|
}
|
|
else
|
|
{
|
|
// Popup a damage decal
|
|
if (nDamage > 0)
|
|
{
|
|
int p1 = 0;
|
|
/*if (dwModifier & CECAttackEvent::MOD_CRITICAL_STRIKE)
|
|
p1 |= 0x0001;
|
|
|
|
if (dwModifier & CECAttackEvent::MOD_RETORT)
|
|
p1 |= 0x0002;*/
|
|
|
|
if (!OnDamaged(skill))
|
|
// PlayAction((int)PLAYER_ACTION_TYPE.ACT_WOUNDED);
|
|
|
|
DamageTextManager.Instance.ShowDamageText(
|
|
transform.position, nDamage, Color.yellow, 1.0f);
|
|
/* if (dwModifier & CECAttackEvent::MOD_IMMUNE)
|
|
BubbleText(BUBBLE_IMMUNE, 0);
|
|
else if (dwModifier & CECAttackEvent::MOD_REBOUND)
|
|
BubbleText(BUBBLE_REBOUND, nDamage);
|
|
else if (dwModifier & CECAttackEvent::MOD_BEAT_BACK)
|
|
BubbleText(BUBBLE_BEAT_BACK, nDamage);
|
|
else
|
|
BubbleText(BUBBLE_DAMAGE, nDamage, p1);*/
|
|
}
|
|
/* else if (dwModifier & CECAttackEvent::MOD_IMMUNE)
|
|
BubbleText(BUBBLE_IMMUNE, 0);
|
|
else if (dwModifier & CECAttackEvent::MOD_NULLITY)
|
|
BubbleText(BUBBLE_INVALIDHIT, 0);
|
|
else
|
|
BubbleText(BUBBLE_HITMISSED, 0);*/
|
|
}
|
|
}
|
|
|
|
public bool OnDamaged(int skill)
|
|
{
|
|
var atkMan = CECAttacksMan.Instance;
|
|
if (atkMan == null)
|
|
return false;
|
|
|
|
string name1, name2;
|
|
|
|
for (int i = 0; i < m_sciStateIDForStateAction.Length; i++)
|
|
{
|
|
/* if (atkMan.GetSkillStateActionName(skill, m_sciStateIDForStateAction[i], out name1, out name2))
|
|
{
|
|
m_SkillIDForStateAction = skill;
|
|
return true;
|
|
}*/
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool GetSkillStateActionName(int skill, int state, string name1, string name2)
|
|
{
|
|
/* for (int i = 0; i < (int)m_SkillStateActionVec.size(); i++)
|
|
{
|
|
if (m_SkillStateActionVec[i].skill == skill && m_SkillStateActionVec[i].state == state)
|
|
{
|
|
name1 = m_SkillStateActionVec[i].beHitAction;
|
|
name2 = m_SkillStateActionVec[i].stayDownAction;
|
|
return true;
|
|
}
|
|
}*/
|
|
return false;
|
|
}
|
|
|
|
public float GetGroundSpeed()
|
|
{
|
|
// return m_bWalkRun ? g_pGame.GetConfigs().GetHostRunSpeed() : m_ExtProps.mv.walk_speed;
|
|
return 5f;
|
|
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)IndexOfIteminEquipmentInventory.EQUIPIVTR_WEAPON] & 0xffff;
|
|
}
|
|
|
|
public bool IsAllResReady()
|
|
{
|
|
return (m_dwResFlags & (uint)PlayerResourcesReadyFlag.RESFG_ALL) == (uint)PlayerResourcesReadyFlag.RESFG_ALL;
|
|
}
|
|
// Get character ID
|
|
|
|
// Play Gfx on Models
|
|
protected bool PlayGfx(string szPath, string szHook, float fScale /*1.0f*/, uint iShapeTypeMask /*(1<<PLAYERMODEL_MAJOR)*/, bool bForceNoRecord =false)
|
|
{
|
|
// bool bPlayed(false);
|
|
// bool bSkipRecord = (iShapeTypeMask != PLAYERMODEL_TYPEALL) || bForceNoRecord;
|
|
// for(int i=0;i<PLAYERMODEL_MAX;i++)
|
|
// {
|
|
// if (m_pModels[i] && (iShapeTypeMask & (1<<i)))
|
|
// {
|
|
// if (IsCurrentModel(m_pModels[i])){
|
|
// m_pModels[i]->PlayGfx(szPath, szHook, fScale);
|
|
// bPlayed = true;
|
|
// }
|
|
// if(bSkipRecord) continue;
|
|
// A3DGFXEx* pGfx = m_pModels[i]->GetGfx(szPath, szHook);
|
|
// if (pGfx && pGfx->IsInfinite()){
|
|
// GFXRECORD rec;
|
|
// rec.strPath = szPath;
|
|
// rec.strHook = szHook;
|
|
// rec.fScale = fScale;
|
|
// AString key = rec.strPath + rec.strHook;
|
|
// m_GfxRecords[key] = rec;
|
|
// bSkipRecord = true;
|
|
// }
|
|
// }
|
|
// }
|
|
PlayLevelUpGfx(szPath);
|
|
return false;
|
|
}
|
|
|
|
private async void PlayLevelUpGfx(string path)
|
|
{
|
|
// Usage: Load the prefab asynchronously using AddressableManager
|
|
GameObject prefab = await AddressableManager.Instance.LoadPrefabAsync(path);
|
|
if(prefab != null)
|
|
{
|
|
if (_levelUpVfx != null)
|
|
{
|
|
if(_levelUpVfx.IsPlaying())
|
|
return;
|
|
_levelUpVfx.Play();
|
|
return;
|
|
}
|
|
|
|
// Instantiate at player's current position and rotation
|
|
_levelUpVfx = Instantiate(prefab, transform).GetComponent<BaseVfxObject>();
|
|
_levelUpVfx.Play();
|
|
// vfx.transform.SetParent(transform); transform.position, prefab.transform.rotation
|
|
_levelUpVfx.transform.localPosition = Vector3.zero;
|
|
}
|
|
else
|
|
{
|
|
BMLogger.LogError($"Failed to load level up effect prefab at: {path}");
|
|
}
|
|
}
|
|
|
|
// Get booth state
|
|
public int GetBoothState() { return m_iBoothState; }
|
|
|
|
// Check whether player has effect of specified type
|
|
public bool HasEffectType(int iEffType)
|
|
{
|
|
int i;
|
|
|
|
switch (iEffType)
|
|
{
|
|
case Effect_type.EFF_FACEPILL:
|
|
{
|
|
elementdataman pDataMan = EC_Game.GetElementDataMan();
|
|
|
|
// Get item data type
|
|
for (i = 0; i < m_aCurEffects.Count; i++)
|
|
{
|
|
DATA_TYPE DataType = pDataMan.get_data_type((uint)m_aCurEffects[i], ID_SPACE.ID_SPACE_ESSENCE);
|
|
if (DataType == DATA_TYPE.DT_FACEPILL_ESSENCE)
|
|
return true;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public byte GetReincarnationCount() { return m_ReincarnationCount; }
|
|
|
|
public string GetName()
|
|
{
|
|
return m_strName;
|
|
}
|
|
}
|
|
|
|
public struct PlayActionEvent
|
|
{
|
|
public string AnimationName;
|
|
|
|
public PlayActionEvent(string animationName)
|
|
{
|
|
this.AnimationName = animationName;
|
|
}
|
|
}
|
|
|
|
public class QueueActionEvent
|
|
{
|
|
public string AnimationName;
|
|
public Action<bool, CECAttackEvent> SetFlag;
|
|
public CECAttackEvent AttackEvent;
|
|
public bool IsHitAnim;
|
|
|
|
public QueueActionEvent(string animationName, Action<bool, CECAttackEvent> setFlag, bool isHitAnim,
|
|
CECAttackEvent attackEvent)
|
|
{
|
|
this.AnimationName = animationName;
|
|
SetFlag = setFlag;
|
|
IsHitAnim = isHitAnim;
|
|
AttackEvent = attackEvent;
|
|
}
|
|
|
|
public void SetData(string animationName, Action<bool, CECAttackEvent> setFlag, bool isHitAnim,
|
|
CECAttackEvent attackEvent)
|
|
{
|
|
this.AnimationName = animationName;
|
|
SetFlag = setFlag;
|
|
IsHitAnim = isHitAnim;
|
|
AttackEvent = attackEvent;
|
|
}
|
|
}
|
|
|
|
[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 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;
|
|
}
|
|
|
|
public class EC_Player_Skin_Const
|
|
{
|
|
// Skin index
|
|
public static byte SKIN_BODY_INDEX = 0;
|
|
public static byte SKIN_UPPER_BODY_INDEX = 1;
|
|
public static byte SKIN_WRIST_INDEX = 2;
|
|
public static byte SKIN_LOWER_INDEX = 3;
|
|
public static byte SKIN_FOOT_INDEX = 4;
|
|
public static byte SKIN_HEAD_INDEX = 5;
|
|
public static byte SKIN_FASHION_UPPER_BODY_INDEX = 6;
|
|
public static byte SKIN_FASHION_WRIST_INDEX = 7;
|
|
public static byte SKIN_FASHION_LOWER_INDEX = 8;
|
|
public static byte SKIN_FASHION_FOOT_INDEX = 9;
|
|
public static byte NUM_SKIN_INDEX = 10;
|
|
} |