Merge pull request 'feature/HostAttack_Hoang' (#26) from feature/HostAttack_Hoang into develop
Reviewed-on: https://git.brew.monster/Unity/perfect-world-unity/pulls/26
This commit is contained in:
@@ -1504,6 +1504,15 @@ namespace ModelRenderer.Scripts.GameData
|
||||
}
|
||||
break;
|
||||
// TODO: Add other id spaces here.
|
||||
case ID_SPACE.ID_SPACE_CONFIG:
|
||||
foreach (var item in config_id_data_type_map)
|
||||
{
|
||||
if (item.Value == dataType)
|
||||
{
|
||||
return item.Key;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using BrewMonster;
|
||||
using CSNetwork.GPDataType;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
public class CECGameRun
|
||||
{
|
||||
private CECWorld m_pWorld;
|
||||
public CECWorld GetWorld() { return m_pWorld; }
|
||||
public bool StartGame(int idInst, Vector3 vHostPos)
|
||||
{
|
||||
if (!JumpToInstance(idInst, vHostPos))
|
||||
{
|
||||
BMLogger.LogError ( "CECGameRun::StartGame, Failed to create game world.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool JumpToInstance(int idInst, Vector3 vHostPos, int iParallelWorldID = 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 923b4102fc6857a4e94d7a662b2e6e1a
|
||||
@@ -8,6 +8,7 @@ namespace BrewMonster.Network
|
||||
#region Fields
|
||||
private static ATaskTemplMan m_pTaskMan; // Task template manager
|
||||
private static elementdataman m_pElementDataMan; // global element templates manager
|
||||
private static CECGameRun m_pGameRun; // Game running object
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
@@ -29,8 +30,15 @@ namespace BrewMonster.Network
|
||||
Debug.LogError("[Dat]- CECGame::Init, Storage task Init Failed!");
|
||||
return false;
|
||||
}
|
||||
m_pGameRun = new CECGameRun();
|
||||
if (m_pGameRun == null)
|
||||
{
|
||||
BMLogger.LogError("CECGame::Init");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static CECGameRun GetGameRun() { return m_pGameRun; }
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
using BrewMonster;
|
||||
using CSNetwork.GPDataType;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
using static CECAttacksMan;
|
||||
|
||||
public class CECAttacksMan : MonoSingleton<CECAttacksMan>
|
||||
{
|
||||
private readonly LinkedList<CECAttackEvent> m_AttackLinkedList = new LinkedList<CECAttackEvent>();
|
||||
|
||||
|
||||
|
||||
private void Update()
|
||||
{
|
||||
var node = m_AttackLinkedList.First;
|
||||
while (node != null)
|
||||
{
|
||||
var next = node.Next;
|
||||
if (node.Value.m_bFinished)
|
||||
m_AttackLinkedList.Remove(node);
|
||||
else node.Value.Tick((uint)(Time.deltaTime * 1000));
|
||||
node = next;
|
||||
}
|
||||
}
|
||||
|
||||
public CECAttackerEvents FindAttackByAttacker(int idHost)
|
||||
{
|
||||
CECAttackerEvents result = new CECAttackerEvents();
|
||||
|
||||
foreach (var attack in m_AttackLinkedList)
|
||||
{
|
||||
if (attack.m_idHost == idHost)
|
||||
{
|
||||
result.Add(attack);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public CECAttackEvent AddMeleeAttack(int idHost, int idTarget, int idWeapon, uint dwModifier, int nDamage, int nTimeFly = 10)
|
||||
{
|
||||
var newEvent = new CECAttackEvent(
|
||||
this,
|
||||
idHost,
|
||||
0, // idCastTarget
|
||||
idTarget,
|
||||
idWeapon,
|
||||
0, // idSkill
|
||||
0, // nSkillLevel
|
||||
dwModifier,
|
||||
nDamage,
|
||||
200, // timeToBeFired
|
||||
nTimeFly // timeToDoDamage
|
||||
);
|
||||
m_AttackLinkedList.AddLast(newEvent);
|
||||
|
||||
newEvent.UpdateTargetFlag();
|
||||
return m_AttackLinkedList.Last.Value;
|
||||
}
|
||||
|
||||
public CECAttackEvent AddSkillAttack(int idHost, int idCastTarget, int idTarget, int idWeapon, int idSkill, int nSkillLevel, uint dwModifier, int nDamage)
|
||||
{
|
||||
var newEvent = new CECAttackEvent(
|
||||
this,
|
||||
idHost,
|
||||
idCastTarget,
|
||||
idTarget,
|
||||
idWeapon,
|
||||
idSkill,
|
||||
nSkillLevel,
|
||||
dwModifier,
|
||||
nDamage,
|
||||
200, // timeToBeFired
|
||||
1000 // timeToDoDamage
|
||||
);
|
||||
m_AttackLinkedList.AddLast(newEvent);
|
||||
|
||||
newEvent.UpdateTargetFlag();
|
||||
return m_AttackLinkedList.Last.Value;
|
||||
}
|
||||
|
||||
// === thêm tạm để code có thể compile ===
|
||||
public void AddAttack(CECAttackEvent evt)
|
||||
{
|
||||
m_AttackLinkedList.AddLast(evt);
|
||||
}
|
||||
public class TARGET_DATA
|
||||
{
|
||||
public int idTarget;
|
||||
public uint dwModifier;
|
||||
public int nDamage;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
public class CECAttackEvent
|
||||
{
|
||||
public CECAttacksMan? m_pManager;
|
||||
|
||||
public bool m_bSignaled;
|
||||
public bool m_bDoFired;
|
||||
public bool m_bDoDamaged;
|
||||
public bool m_bFinished;
|
||||
|
||||
public uint m_timeLived;
|
||||
public uint m_timeToBeFired;
|
||||
public uint m_timeToDoDamage;
|
||||
|
||||
public int m_idHost;
|
||||
public int m_idCastTarget;
|
||||
public List<TARGET_DATA> m_targets = new List<TARGET_DATA>();
|
||||
|
||||
public int m_idWeapon;
|
||||
public int m_idSkill;
|
||||
public int m_nSkillLevel;
|
||||
public int m_nSkillSection;
|
||||
|
||||
public CECAttackEvent() { }
|
||||
|
||||
public CECAttackEvent(CECAttacksMan? pManager, int idHost, int idCastTarget, int idTarget,
|
||||
int idWeapon, int idSkill, int nSkillLevel, uint dwModifier,
|
||||
int nDamage, int nTimeToBeFired, int nTimeToDoDamage)
|
||||
{
|
||||
m_pManager = pManager;
|
||||
m_idHost = idHost;
|
||||
m_idCastTarget = idCastTarget;
|
||||
m_idWeapon = idWeapon;
|
||||
m_idSkill = idSkill;
|
||||
m_nSkillLevel = nSkillLevel;
|
||||
m_timeToBeFired = (uint)nTimeToBeFired;
|
||||
m_timeToDoDamage = (uint)nTimeToDoDamage;
|
||||
|
||||
AddTarget(idTarget, dwModifier, nDamage);
|
||||
}
|
||||
public bool Tick(uint dwDeltaTime)
|
||||
{
|
||||
m_timeLived += dwDeltaTime;
|
||||
|
||||
if (!m_bSignaled)
|
||||
{
|
||||
if (m_timeLived > 3500)
|
||||
{
|
||||
// too long time, this event will be deleted now
|
||||
m_bFinished = true;
|
||||
//DoFire();
|
||||
DoDamage();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_timeToBeFired != 0)
|
||||
{
|
||||
if (m_timeToBeFired <= dwDeltaTime)
|
||||
{
|
||||
m_timeToBeFired = 0;
|
||||
|
||||
// Fire here
|
||||
//DoFire();
|
||||
}
|
||||
else
|
||||
m_timeToBeFired -= dwDeltaTime;
|
||||
}
|
||||
else if (m_timeToDoDamage != 0)
|
||||
{
|
||||
if (m_timeToDoDamage <= dwDeltaTime)
|
||||
{
|
||||
m_timeToDoDamage = 0;
|
||||
|
||||
// Do damage here
|
||||
DoDamage();
|
||||
}
|
||||
else
|
||||
m_timeToDoDamage -= dwDeltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool DoDamage()
|
||||
{
|
||||
m_bDoDamaged = true;
|
||||
m_bFinished = true;
|
||||
|
||||
/* CECGameRun pGameRun = g_pGame-GetGameRun();
|
||||
int idHostPlayer = pGameRun->GetHostPlayer()->GetCharacterID();*/
|
||||
|
||||
// Get host name
|
||||
/* ACString strHostName;
|
||||
CECObject* pHostObject = pGameRun->GetWorld()->GetObject(m_idHost, 0);
|
||||
if (pHostObject)
|
||||
{
|
||||
if (ISNPCID(m_idHost))
|
||||
strHostName = ((CECNPC*)pHostObject)->GetName();
|
||||
else if (ISPLAYERID(m_idHost))
|
||||
strHostName = GetPlayerName((CECPlayer*)pHostObject);
|
||||
}*/
|
||||
|
||||
int nNumTargets = m_targets.Count;
|
||||
for (int i = 0; i < nNumTargets; i++)
|
||||
{
|
||||
TARGET_DATA data = m_targets[i];
|
||||
int idTarget = data.idTarget;
|
||||
string strName;
|
||||
|
||||
if (GPDataTypeHelper.ISNPCID(idTarget))
|
||||
{
|
||||
CECNPC pNPC = null;
|
||||
if ((data.dwModifier & (uint)MOD.MOD_SUCCESS) != 0)
|
||||
pNPC = EC_ManMessageMono.Instance._CECNPCMan.GetNPCFromAll(idTarget);
|
||||
else
|
||||
{
|
||||
pNPC = EC_ManMessageMono.Instance._CECNPCMan.GetNPCFromAll(idTarget);
|
||||
if (!pNPC)
|
||||
return true;
|
||||
|
||||
//strName = pNPC->GetNameToShow();
|
||||
}
|
||||
|
||||
if (!pNPC)
|
||||
return true;
|
||||
|
||||
pNPC.Damaged(data.nDamage, data.dwModifier);
|
||||
}
|
||||
else if (GPDataTypeHelper.ISPLAYERID(idTarget))
|
||||
{
|
||||
/* CECPlayer* pPlayer = pGameRun->GetWorld()->GetPlayerMan()->GetPlayer(idTarget);
|
||||
if (!pPlayer)
|
||||
return true;
|
||||
|
||||
strName = GetPlayerName(pPlayer);
|
||||
|
||||
pPlayer->Damaged(data.nDamage, data.dwModifier, m_idSkill);*/
|
||||
}
|
||||
|
||||
/* if (data.nDamage > 0)
|
||||
{
|
||||
if (m_idHost == idHostPlayer)
|
||||
{
|
||||
if (!strName.IsEmpty())
|
||||
pGameRun->AddFixedChannelMsg(FIXMSG_DODAMAGE, GP_CHAT_DAMAGE, strName, data.nDamage);
|
||||
}
|
||||
else if (data.idTarget == idHostPlayer)
|
||||
{
|
||||
if (!strHostName.IsEmpty())
|
||||
pGameRun->AddFixedChannelMsg(FIXMSG_BEDAMAGED, GP_CHAT_DAMAGE, strHostName, data.nDamage);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool AddTarget(int idTarget, uint dwModifier, int nDamage)
|
||||
{
|
||||
m_targets.Add(new TARGET_DATA
|
||||
{
|
||||
idTarget = idTarget,
|
||||
dwModifier = dwModifier,
|
||||
nDamage = nDamage
|
||||
});
|
||||
return true;
|
||||
}
|
||||
public bool UpdateTargetFlag()
|
||||
{
|
||||
// update all targets' bAboutToDie flag
|
||||
|
||||
int nNumTargets = m_targets.Count;
|
||||
for (int i = 0; i < nNumTargets; i++)
|
||||
{
|
||||
TARGET_DATA data = m_targets[i];
|
||||
/*
|
||||
if( data.dwModifier & MOD_DEADLYSTRIKE )
|
||||
{
|
||||
int idTarget = data.idTarget;
|
||||
if (ISNPCID(idTarget))
|
||||
{
|
||||
CECNPC* pNPC = g_pGame->GetGameRun()->GetWorld()->GetNPCMan()->GetNPC(idTarget);
|
||||
if (!pNPC)
|
||||
return true;
|
||||
|
||||
pNPC->SetAboutToDie(true);
|
||||
}
|
||||
else if (ISPLAYERID(idTarget))
|
||||
{
|
||||
CECPlayer* pPlayer = g_pGame->GetGameRun()->GetWorld()->GetPlayerMan()->GetPlayer(idTarget);
|
||||
if (!pPlayer)
|
||||
return true;
|
||||
|
||||
pPlayer->SetAboutToDie(true);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public class CECAttackerEvents
|
||||
{
|
||||
private readonly List<CECAttackEvent> m_list = new List<CECAttackEvent>();
|
||||
|
||||
public void Add(CECAttackEvent? evt)
|
||||
{
|
||||
if (evt != null)
|
||||
m_list.Add(evt);
|
||||
}
|
||||
|
||||
public bool IsEmpty() => m_list.Count == 0;
|
||||
public int Count() => m_list.Count;
|
||||
|
||||
public CECAttackEvent? Find(int idSkill = 0, int nSkillSection = 0)
|
||||
{
|
||||
foreach (var evt in m_list)
|
||||
{
|
||||
if (evt.m_idSkill == idSkill && evt.m_nSkillSection == nSkillSection)
|
||||
return evt;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Signal()
|
||||
{
|
||||
foreach (var evt in m_list)
|
||||
evt.m_bSignaled = true;
|
||||
m_list.Clear();
|
||||
}
|
||||
|
||||
public static implicit operator bool(CECAttackerEvents events)
|
||||
{
|
||||
return !events.IsEmpty();
|
||||
}
|
||||
}
|
||||
enum MOD
|
||||
|
||||
{
|
||||
MOD_PHYSIC_ATTACK_RUNE = 0x0001, // ÎïÀí¹¥»÷ÓÅ»¯·ûÉúЧ
|
||||
MOD_MAGIC_ATTACK_RUNE = 0x0002, // ·¨Êõ¹¥»÷ÓÅ»¯·ûÉúЧ
|
||||
MOD_PHYSIC_DEFENCE_RUNE = 0x0004, // ÎïÀí·ÀÓùÓÅ»¯·ûÉúЧ
|
||||
MOD_MAGIC_DEFENCE_RUNE = 0x0008, // ·¨Êõ·ÀÓùÓÅ»¯·ûÉúЧ
|
||||
MOD_CRITICAL_STRIKE = 0x0010, // ±¬»÷
|
||||
MOD_RETORT = 0x0020, // ·´Õð
|
||||
MOD_NULLITY = 0x0040, // ÎÞЧ¹¥»÷
|
||||
MOD_IMMUNE = 0x0080, // ÃâÒßÁ˴˴ι¥»÷£¬ÓÅÏȼ¶¸ßÓÚÎÞЧ
|
||||
MOD_ENCHANT_FAILED = 0x0100, // enchant ʧ°Ü
|
||||
MOD_SUCCESS = 0x0200, // ³É¹¦
|
||||
MOD_DODGE_DAMAGE = 0x0400, // É˺¦¶ãÉÁ
|
||||
MOD_DODGE_DEBUFF = 0x0800, // ״̬¶ãÉÁ
|
||||
MOD_ATTACK_AURA = 0x1000, // ¹â»·¹¥»÷
|
||||
MOD_REBOUND = 0x2000, // ·´µ¯
|
||||
MOD_BEAT_BACK = 0x4000, // ·´»÷
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 92009c5b4b0fd894790865cf674545fa
|
||||
@@ -6,6 +6,7 @@ using System;
|
||||
using System.Buffers.Binary;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
|
||||
public class CECNPCMan : CECObject, IMsgHandler
|
||||
@@ -203,6 +204,22 @@ public class CECNPCMan : CECObject, IMsgHandler
|
||||
|
||||
return npc;
|
||||
}
|
||||
public CECNPC GetNPCFromAll(int nid)
|
||||
{
|
||||
CECNPC pNPC = GetNPC(nid);
|
||||
if (pNPC)
|
||||
return pNPC;
|
||||
|
||||
// Search from disappear array ?
|
||||
/*for (int i = 0; i < m_aDisappearNPCs.GetSize(); i++)
|
||||
{
|
||||
CECNPC* pNPC = m_aDisappearNPCs[i];
|
||||
if (pNPC->GetNPCID() == nid)
|
||||
return pNPC;
|
||||
}*/
|
||||
|
||||
return null;
|
||||
}
|
||||
public CECNPC CreateNPC(info_npc Info, bool bBornInSight, ReadOnlySpan<byte> packet, int infoOffset)
|
||||
{
|
||||
CECNPC pNPC = null;
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using DG.Tweening; // cần DOTween
|
||||
|
||||
public class DamageTextManager : MonoBehaviour
|
||||
{
|
||||
public static DamageTextManager Instance { get; private set; }
|
||||
|
||||
[Header("Prefab")]
|
||||
[SerializeField] private TextMeshPro damageTextPrefab;
|
||||
|
||||
[Header("Settings")]
|
||||
[SerializeField] private int poolSize = 20;
|
||||
[SerializeField] private Vector3 offset = new Vector3(0, 2f, 0);
|
||||
[SerializeField] private float riseDistance = 1.5f;
|
||||
[SerializeField] private float riseDuration = 0.8f;
|
||||
|
||||
private readonly Queue<TextMeshPro> pool = new();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// Singleton
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
Instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
|
||||
// Tạo sẵn pool
|
||||
for (int i = 0; i < poolSize; i++)
|
||||
{
|
||||
var textObj = Instantiate(damageTextPrefab, transform);
|
||||
textObj.gameObject.SetActive(false);
|
||||
pool.Enqueue(textObj);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gọi để spawn text damage
|
||||
/// </summary>
|
||||
public void SpawnDamage(Vector3 worldPos, int damage, Color color, float scale = 1f)
|
||||
{
|
||||
var text = GetFromPool();
|
||||
text.text = damage.ToString();
|
||||
text.color = color;
|
||||
text.fontSize = 6;
|
||||
text.transform.localScale = Vector3.one * scale;
|
||||
|
||||
Vector3 startPos = worldPos + offset;
|
||||
text.transform.position = startPos;
|
||||
text.gameObject.SetActive(true);
|
||||
|
||||
// Hiệu ứng bay lên + mờ dần
|
||||
text.transform.DOMoveY(startPos.y + riseDistance, riseDuration).SetEase(Ease.OutQuad);
|
||||
text.DOFade(0f, riseDuration)
|
||||
.SetEase(Ease.InQuad)
|
||||
.OnComplete(() =>
|
||||
{
|
||||
text.alpha = 1f;
|
||||
text.gameObject.SetActive(false);
|
||||
ReturnToPool(text);
|
||||
});
|
||||
}
|
||||
|
||||
private TextMeshPro GetFromPool()
|
||||
{
|
||||
if (pool.Count > 0)
|
||||
{
|
||||
return pool.Dequeue();
|
||||
}
|
||||
|
||||
// Nếu hết pool, tạo thêm
|
||||
var text = Instantiate(damageTextPrefab, transform);
|
||||
text.gameObject.SetActive(false);
|
||||
return text;
|
||||
}
|
||||
|
||||
private void ReturnToPool(TextMeshPro text)
|
||||
{
|
||||
pool.Enqueue(text);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e7981b037b60f4a4989ff59265a308ad
|
||||
@@ -148,7 +148,7 @@ class CECHPWorkMelee : CECHPWork
|
||||
protected virtual void OnFirstTick()
|
||||
{
|
||||
m_pHost.m_iMoveMode = (int)MoveMode.MOVE_STAND;
|
||||
m_pHost.PlayAction((int)EC_Player.PLAYER_ACTION_TYPE.ACT_ATTACK_1 + Random.Range(0, 3), true, 200, false);
|
||||
m_pHost.PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_ATTACK_1 + Random.Range(0, 3), true, 200, false);
|
||||
|
||||
m_idTarget = m_pHost.m_idSelTarget;
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ public abstract class CECTracedObject
|
||||
}
|
||||
else
|
||||
{
|
||||
EC_Player pPlayer = pObject.GetComponent<CECHostPlayer>();
|
||||
CECPlayer pPlayer = pObject.GetComponent<CECHostPlayer>();
|
||||
fTouchRadius = pPlayer.GetTouchRadius();
|
||||
}
|
||||
return m_pHost.CanTouchTarget(vHostPos, vTargetPos, fTouchRadius, iTouchReason, fMaxCut);
|
||||
@@ -384,7 +384,7 @@ public class CECTracedPlayer : CECTracedObject
|
||||
{
|
||||
return true;
|
||||
}
|
||||
EC_Player pPlayer = GetTargetObject() as EC_Player;
|
||||
CECPlayer pPlayer = GetTargetObject() as CECPlayer;
|
||||
if (pPlayer.IsElsePlayer())
|
||||
{
|
||||
if (pPlayer.IsDead())
|
||||
@@ -615,10 +615,10 @@ public class CECHPWorkTrace : CECHPWork
|
||||
{
|
||||
// Continue tracing object
|
||||
float fDeltaTime = dwDeltaTime /** 0.001f*/;
|
||||
if (m_pHost.m_iMoveEnv == EC_Player.Move_environment.MOVEENV_GROUND)
|
||||
if (m_pHost.m_iMoveEnv == CECPlayer.Move_environment.MOVEENV_GROUND)
|
||||
{
|
||||
// Play appropriate actions
|
||||
if (!m_pHost.IsJumping() && !m_pHost.IsPlayingAction((int)EC_Player.PLAYER_ACTION_TYPE.ACT_TRICK_RUN) &&
|
||||
if (!m_pHost.IsJumping() && !m_pHost.IsPlayingAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_TRICK_RUN) &&
|
||||
m_pHost.m_iMoveMode != (int)MoveMode.MOVE_SLIDE)
|
||||
{
|
||||
int iAction = m_pHost.GetMoveStandAction(true);
|
||||
@@ -810,7 +810,7 @@ public class CECHPWorkTrace : CECHPWork
|
||||
|
||||
if (m_pHost.m_iMoveMode == (int)MoveMode.MOVE_SLIDE)
|
||||
{
|
||||
m_pHost.PlayAction((int)EC_Player.PLAYER_ACTION_TYPE.ACT_JUMP_LOOP, false, 200, false);
|
||||
m_pHost.PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_JUMP_LOOP, false, 200, false);
|
||||
|
||||
// This will cause stop moming after we slide down.
|
||||
A3DVECTOR3 vDir = vTargetPos - vCurPos;
|
||||
|
||||
@@ -183,7 +183,7 @@ namespace PerfectWorld.Scripts.Managers
|
||||
// For equipping, we need to find an empty equipment slot
|
||||
// Use the new method that checks for available slots (especially for finger items)
|
||||
byte equipLocation = EC_IvtrType.GetAvailableEquipLocationForItem(currentSelectedItem.TemplateId);
|
||||
if (equipLocation >= (byte)EC_IvtrType.IndexOfIteminEquipmentInventory.SIZE_EQUIPIVTR)
|
||||
if (equipLocation >= (byte)IndexOfIteminEquipmentInventory.SIZE_EQUIPIVTR)
|
||||
{
|
||||
Debug.LogWarning($"[InventoryUI] Could not determine equip location for item {currentSelectedItem.TemplateId}");
|
||||
return;
|
||||
|
||||
@@ -5,43 +5,54 @@ using BrewMonster;
|
||||
|
||||
namespace PerfectWorld.Scripts.Managers
|
||||
{
|
||||
public enum IndexOfIteminEquipmentInventory : byte
|
||||
{
|
||||
EQUIPIVTR_WEAPON = 0,
|
||||
EQUIPIVTR_HEAD = 1,
|
||||
EQUIPIVTR_NECK = 2,
|
||||
EQUIPIVTR_SHOULDER = 3,
|
||||
EQUIPIVTR_BODY = 4,
|
||||
EQUIPIVTR_WAIST = 5,
|
||||
EQUIPIVTR_LEG = 6,
|
||||
EQUIPIVTR_FOOT = 7,
|
||||
EQUIPIVTR_WRIST = 8,
|
||||
EQUIPIVTR_FINGER1 = 9,
|
||||
EQUIPIVTR_FINGER2 = 10,
|
||||
EQUIPIVTR_PROJECTILE = 11,
|
||||
EQUIPIVTR_FLYSWORD = 12,
|
||||
EQUIPIVTR_FASHION_BODY = 13,
|
||||
EQUIPIVTR_FASHION_LEG = 14,
|
||||
EQUIPIVTR_FASHION_FOOT = 15,
|
||||
EQUIPIVTR_FASHION_WRIST = 16,
|
||||
EQUIPIVTR_RUNE = 17,
|
||||
EQUIPIVTR_BIBLE = 18,
|
||||
EQUIPIVTR_SPEAKER = 19,
|
||||
EQUIPIVTR_AUTOHP = 20,
|
||||
EQUIPIVTR_AUTOMP = 21,
|
||||
EQUIPIVTR_POCKET = 22,
|
||||
EQUIPIVTR_GOBLIN = 23,
|
||||
EQUIPIVTR_CERTIFICATE = 24,
|
||||
EQUIPIVTR_FASHION_HEAD = 25,
|
||||
EQUIPIVTR_FORCE_TOKEN = 26,
|
||||
EQUIPIVTR_DYNSKILLEQUIP1 = 27,
|
||||
EQUIPIVTR_DYNSKILLEQUIP2 = 28,
|
||||
EQUIPIVTR_FASHION_WEAPON = 29,
|
||||
SIZE_EQUIPIVTR = 30,
|
||||
EQUIPIVTR_UNUSED1 = SIZE_EQUIPIVTR,
|
||||
EQUIPIVTR_UNUSED2 = 31,
|
||||
EQUIPIVTR_GENERALCARD1,
|
||||
EQUIPIVTR_GENERALCARD2,
|
||||
EQUIPIVTR_GENERALCARD3,
|
||||
EQUIPIVTR_GENERALCARD4 = 35,
|
||||
EQUIPIVTR_GENERALCARD5,
|
||||
EQUIPIVTR_GENERALCARD6,
|
||||
SIZE_ALL_EQUIPIVTR,
|
||||
SIZE_GENERALCARD_EQUIPIVTR = SIZE_ALL_EQUIPIVTR - EQUIPIVTR_GENERALCARD1,
|
||||
}
|
||||
|
||||
public static class EC_IvtrType
|
||||
{
|
||||
public enum IndexOfIteminEquipmentInventory : byte
|
||||
{
|
||||
EQUIPIVTR_WEAPON = 0,
|
||||
EQUIPIVTR_HEAD = 1,
|
||||
EQUIPIVTR_NECK = 2,
|
||||
EQUIPIVTR_SHOULDER = 3,
|
||||
EQUIPIVTR_BODY = 4,
|
||||
EQUIPIVTR_WAIST = 5,
|
||||
EQUIPIVTR_LEG = 6,
|
||||
EQUIPIVTR_FOOT = 7,
|
||||
EQUIPIVTR_WRIST = 8,
|
||||
EQUIPIVTR_FINGER1 = 9,
|
||||
EQUIPIVTR_FINGER2 = 10,
|
||||
EQUIPIVTR_PROJECTILE = 11,
|
||||
EQUIPIVTR_FLYSWORD = 12,
|
||||
EQUIPIVTR_FASHION_BODY = 13,
|
||||
EQUIPIVTR_FASHION_LEG = 14,
|
||||
EQUIPIVTR_FASHION_FOOT = 15,
|
||||
EQUIPIVTR_FASHION_WRIST = 16,
|
||||
EQUIPIVTR_RUNE = 17,
|
||||
EQUIPIVTR_BIBLE = 18,
|
||||
EQUIPIVTR_SPEAKER = 19,
|
||||
EQUIPIVTR_AUTOHP = 20,
|
||||
EQUIPIVTR_AUTOMP = 21,
|
||||
EQUIPIVTR_POCKET = 22,
|
||||
EQUIPIVTR_GOBLIN = 23,
|
||||
EQUIPIVTR_CERTIFICATE = 24,
|
||||
EQUIPIVTR_FASHION_HEAD = 25,
|
||||
EQUIPIVTR_FORCE_TOKEN = 26,
|
||||
EQUIPIVTR_DYNSKILLEQUIP1 = 27,
|
||||
EQUIPIVTR_DYNSKILLEQUIP2 = 28,
|
||||
EQUIPIVTR_FASHION_WEAPON = 29,
|
||||
SIZE_EQUIPIVTR = 30,
|
||||
}
|
||||
|
||||
|
||||
public static byte GetEquipLocationForItem(int templateId)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -470,7 +470,7 @@ namespace PerfectWorld.Scripts.Managers
|
||||
}
|
||||
|
||||
// Get a player (may be host or else player) by id
|
||||
public EC_Player GetPlayer(int cid, uint dwBornStamp = 0)
|
||||
public CECPlayer GetPlayer(int cid, uint dwBornStamp = 0)
|
||||
{
|
||||
CECHostPlayer pHost = GetHostPlayer();
|
||||
if (pHost && pHost.GetCharacterID() == cid)
|
||||
|
||||
@@ -185,7 +185,7 @@ public class CECObject : MonoBehaviour
|
||||
return 0;
|
||||
|
||||
if (pObject.IsPlayer())
|
||||
return ((EC_Player)pObject).GetCharacterID();
|
||||
return ((CECPlayer)pObject).GetCharacterID();
|
||||
else if (pObject.IsNPC())
|
||||
return ((CECNPC)pObject).GetNPCID();
|
||||
//else if (pObject.IsMatter())
|
||||
|
||||
+1
-1
@@ -85,7 +85,7 @@ public class CECHostMove
|
||||
float fSpeed = 0f;
|
||||
switch (m_pHost.GetMoveEnv())
|
||||
{
|
||||
case EC_Player.Move_environment.MOVEENV_AIR:
|
||||
case CECPlayer.Move_environment.MOVEENV_AIR:
|
||||
|
||||
iMoveMode |= (int)GPMoveMode.GP_MOVE_AIR;
|
||||
fSpeed = m_pHost.GetFlySpeed();
|
||||
@@ -1,26 +1,34 @@
|
||||
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
|
||||
public abstract class CECPlayer : 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 GameObject _pPlayerModel;
|
||||
protected float rotationSpeed = 5;
|
||||
internal int m_iMoveMode; // Player's move mode
|
||||
internal int m_idSelTarget; // Ñ¡ÖÐÄ¿±êµÄID
|
||||
uint m_dwStates; // Player's basic states
|
||||
internal int m_idSelTarget;
|
||||
protected int m_iShape; // Ñ¡ÖÐÄ¿±êµÄID
|
||||
protected uint m_dwStates; // Player's basic states
|
||||
protected uint m_uAttackType;
|
||||
protected int[] m_aEquips;
|
||||
protected ROLEEXTPROP m_ExtProps; // Extend properties
|
||||
protected float m_fTouchRad = 0.3f; // Touch radius
|
||||
protected int m_iFashionWeaponType;
|
||||
protected float m_fTouchRad = 0.3f; // Touch radius
|
||||
protected bool m_bWeaponAttached;
|
||||
protected int m_iBattleCamp = Player_camp_in_battle.GP_BATTLE_CAMP_NONE; // Battle this player belongs to
|
||||
byte m_factionPVPMask; // pvp mask
|
||||
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;
|
||||
@@ -28,7 +36,12 @@ public abstract class EC_Player : CECObject
|
||||
public A3DAABB m_aabb = new A3DAABB(); // Player's aabb£¬ÓÃÓÚÏÔʾµÄaabb£¬ÊÜËõ·ÅÓ°Ïì
|
||||
public int m_iProfession; // Profession
|
||||
public float m_fScaleBySkill;
|
||||
public int m_iGender; // Gender
|
||||
public int m_iGender; // Gender
|
||||
protected bool m_bFashionMode;
|
||||
|
||||
protected int NUM_WEAPON_TYPE = 15;
|
||||
|
||||
|
||||
public MOVECONST m_MoveConst; // Const used when moving control
|
||||
|
||||
public MOVECONST[] aMoveConsts = new MOVECONST[PROFESSION.NUM_PROFESSION * GENDER.NUM_GENDER]
|
||||
@@ -103,6 +116,12 @@ public abstract class EC_Player : CECObject
|
||||
protected void Awake()
|
||||
{
|
||||
m_PlayerActions = _default_actions;
|
||||
m_iShape = 0;
|
||||
m_aEquips = new int[(int)IndexOfIteminEquipmentInventory.SIZE_ALL_EQUIPIVTR];
|
||||
}
|
||||
public void SetUpPlayer()
|
||||
{
|
||||
m_dwResFlags = 0;
|
||||
}
|
||||
public void SetPlayerInfor(INFO playinfo)
|
||||
{
|
||||
@@ -127,9 +146,12 @@ public abstract class EC_Player : CECObject
|
||||
BuildActionList();
|
||||
}
|
||||
|
||||
public bool IsDead(){ return (m_dwStates & PlayerNPCState.GP_STATE_CORPSE) != 0; }
|
||||
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)
|
||||
@@ -233,6 +255,7 @@ public abstract class EC_Player : CECObject
|
||||
public PLAYER_ACTION_TYPE type;
|
||||
public PLAYER_ACTION_INFO_CONFIG data;
|
||||
};
|
||||
public INFO GetPlayerInfo() { return m_PlayerInfo; }
|
||||
public enum PLAYER_ACTION_TYPE
|
||||
{
|
||||
// 0
|
||||
@@ -368,8 +391,301 @@ public abstract class EC_Player : CECObject
|
||||
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;*/
|
||||
|
||||
public float GetTouchRadius(){ return m_fTouchRad; }
|
||||
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)IndexOfIteminEquipmentInventory.EQUIPIVTR_PROJECTILE] != 0)
|
||||
idWeapon = m_aEquips[(int)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, out piAttackTime, ref 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 (_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, 0, "Æð");
|
||||
EventBus.PublishChannel(m_PlayerInfo.cid, new PlayActionEvent(szAct));
|
||||
szAct = EC_Utility.BuildActionName(action, 0, "Âä");
|
||||
EventBus.PublishChannel(m_PlayerInfo.cid, new QueueActionEvent(szAct));
|
||||
//PlayNonSkillActionWithName(iAction, szAct, true, 200, true, 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 = _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ố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[(int)PLAYER_ACTION_TYPE.ACT_FIGHTSTAND];
|
||||
szAct = EC_Utility.BuildActionName(stand_action, 0);
|
||||
EventBus.PublishChannel(m_PlayerInfo.cid, new QueueActionEvent(szAct));
|
||||
|
||||
/* 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 bool m_bShowWeapon;
|
||||
public void ShowWeaponByConfig(PLAYER_ACTION_INFO_CONFIG p)
|
||||
{
|
||||
m_bShowWeapon = p.hide_weapon != 0 ? false : true;
|
||||
//ShowWeapon(m_bShowWeapon);
|
||||
}
|
||||
public int GetShowingWeaponType()
|
||||
{
|
||||
int weapon_type = 0;
|
||||
if (CanShowFashionWeapon((int)m_uAttackType, m_iFashionWeaponType) && m_aEquips[(int)IndexOfIteminEquipmentInventory.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 : (int)m_uAttackType;
|
||||
}
|
||||
return weapon_type;
|
||||
}
|
||||
|
||||
public bool IsWeaponAttached()
|
||||
{
|
||||
return m_bWeaponAttached;
|
||||
}
|
||||
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.Value;
|
||||
}
|
||||
public float GetTouchRadius() { return m_fTouchRad; }
|
||||
// Is player in battle
|
||||
public bool IsInBattle() { return m_iBattleCamp != Player_camp_in_battle.GP_BATTLE_CAMP_NONE; }
|
||||
|
||||
@@ -383,6 +699,8 @@ public abstract class EC_Player : CECObject
|
||||
|
||||
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;
|
||||
@@ -462,9 +780,11 @@ public abstract class EC_Player : CECObject
|
||||
}
|
||||
|
||||
// Get move environment
|
||||
public int GetMoveEnv(){ return m_iMoveEnv; }
|
||||
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
|
||||
public int GetCharacterID(){ return m_PlayerInfo.cid; }
|
||||
}
|
||||
public struct PlayActionEvent
|
||||
{
|
||||
@@ -474,6 +794,15 @@ public struct PlayActionEvent
|
||||
this.AnimationName = animationName;
|
||||
}
|
||||
}
|
||||
|
||||
public struct QueueActionEvent
|
||||
{
|
||||
public string AnimationName;
|
||||
public QueueActionEvent(string animationName)
|
||||
{
|
||||
this.AnimationName = animationName;
|
||||
}
|
||||
}
|
||||
[Serializable]
|
||||
public struct INFO
|
||||
{
|
||||
@@ -487,7 +816,15 @@ public struct INFO
|
||||
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,
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 041192bec8f11c747a80df312c2df184
|
||||
@@ -264,6 +264,63 @@ public class CECNPC : CECObject
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Damaged(int iDamage, uint dwModifier/* 0 */)
|
||||
{
|
||||
if (iDamage == -1 || iDamage == -2)
|
||||
{
|
||||
// when else player hit this npc iDamage is -1,
|
||||
// so if iDamage is -1 we will shoud the wounded animation
|
||||
if (iDamage == -1)
|
||||
PlayModelAction((int)NPCActionIndex. ACT_WOUNDED);
|
||||
DamageTextManager.Instance.SpawnDamage(transform.position, iDamage, Color.red, 1.0f);
|
||||
|
||||
/*if ((dwModifier & (uint)MOD.MOD_IMMUNE) != 0 *//* && !IsImmuneDisable()*//*)
|
||||
textma
|
||||
else if (dwModifier & CECAttackEvent::MOD_NULLITY)
|
||||
BubbleText(BUBBLE_INVALIDHIT, 0);
|
||||
else if (dwModifier & CECAttackEvent::MOD_ENCHANT_FAILED)
|
||||
BubbleText(BUBBLE_LOSE, 0);
|
||||
else if (dwModifier & CECAttackEvent::MOD_SUCCESS)
|
||||
BubbleText(BUBBLE_SUCCESS, 0);
|
||||
else if (dwModifier & CECAttackEvent::MOD_DODGE_DEBUFF)
|
||||
BubbleText(BUBBLE_DODGE_DEBUFF, 0);*/
|
||||
}
|
||||
else
|
||||
{
|
||||
// this message is related to the host, so we should show a pop up message
|
||||
// Popup a damage decal
|
||||
/* bool bDeadlyStrike = (dwModifier & CECAttackEvent::MOD_CRITICAL_STRIKE) ? true : false;
|
||||
bool bRetort = (dwModifier & CECAttackEvent::MOD_RETORT) ? true : false;*/
|
||||
|
||||
if (iDamage > 0)
|
||||
{
|
||||
PlayModelAction((int)NPCActionIndex.ACT_WOUNDED);
|
||||
DamageTextManager.Instance.SpawnDamage(transform.position, iDamage, Color.red, 1.0f);
|
||||
/* int p1 = 0;
|
||||
if (bDeadlyStrike)
|
||||
p1 |= 0x0001;
|
||||
else if (bRetort)
|
||||
p1 |= 0x0002;*/
|
||||
|
||||
/* if (dwModifier & CECAttackEvent::MOD_REBOUND)
|
||||
BubbleText(BUBBLE_REBOUND, (DWORD)iDamage);
|
||||
else if (dwModifier & CECAttackEvent::MOD_BEAT_BACK)
|
||||
BubbleText(BUBBLE_BEAT_BACK, (DWORD)iDamage);
|
||||
else
|
||||
BubbleText(BUBBLE_DAMAGE, (DWORD)iDamage, p1);*/
|
||||
}
|
||||
/* else if ((dwModifier & CECAttackEvent::MOD_IMMUNE) && !IsImmuneDisable())
|
||||
BubbleText(BUBBLE_IMMUNE, 0);
|
||||
else if (dwModifier & CECAttackEvent::MOD_NULLITY)
|
||||
BubbleText(BUBBLE_INVALIDHIT, 0);
|
||||
else if (dwModifier & CECAttackEvent::MOD_ENCHANT_FAILED)
|
||||
BubbleText(BUBBLE_LOSE, 0);
|
||||
else if (dwModifier & CECAttackEvent::MOD_SUCCESS)
|
||||
BubbleText(BUBBLE_SUCCESS, 0);
|
||||
else
|
||||
BubbleText(BUBBLE_HITMISSED, 0);*/
|
||||
}
|
||||
}
|
||||
|
||||
public void WorkFinished(int iWorkID)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Animancer;
|
||||
using BrewMonster;
|
||||
using UnityEngine;
|
||||
|
||||
public class NPCVisual : MonoBehaviour
|
||||
@@ -6,10 +7,11 @@ public class NPCVisual : MonoBehaviour
|
||||
[SerializeField] NamedAnimancerComponent namedAnimancer;
|
||||
public bool TryPlayAction(string animationName)
|
||||
{
|
||||
BMLogger.LogError("HoangDev: TryPlayAction: " + animationName);
|
||||
if (namedAnimancer == null) return false;
|
||||
if (namedAnimancer.IsPlaying(animationName)) return false;
|
||||
|
||||
return namedAnimancer.TryPlay("慢速移动") == null;
|
||||
return namedAnimancer.TryPlay(animationName) == null;
|
||||
}
|
||||
public void InitNPCEventDoneHandler()
|
||||
{
|
||||
|
||||
@@ -846,6 +846,15 @@ namespace CSNetwork.GPDataType
|
||||
public byte[] content;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_host_attack_result
|
||||
{
|
||||
public int idTarget;
|
||||
public int iDamage; // Èç¹ûÊÇ0±íʾûÓл÷ÖÐ
|
||||
public int attack_flag; // ±ê¼Ç¸Ã¹¥»÷ÊÇ·ñÓй¥»÷ÓÅ»¯·ûºÍ·ÀÓùÓÅ»¯·ûºÍÖØ»÷·¢Éú
|
||||
public byte attack_speed;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_own_ivtr_detail_info
|
||||
{
|
||||
|
||||
@@ -319,7 +319,7 @@ namespace CSNetwork
|
||||
}
|
||||
var pCmdHeader = BitConverter.ToUInt16(byteArrHeader);
|
||||
//sss
|
||||
_logger.Info($"### GameDataSend: CMDID {pCmdHeader}");
|
||||
BMLogger.LogError($"### GameDataSend: CMDID {pCmdHeader}");
|
||||
int iHostID = _selectedRole.roleid;
|
||||
switch (pCmdHeader)
|
||||
{
|
||||
@@ -339,7 +339,6 @@ namespace CSNetwork
|
||||
case CommandID.PLAYER_INFO_00:
|
||||
case CommandID.SELF_INFO_1:
|
||||
// OnMsgPlayerInfo(-1, pDataBuf, pCmdHeader);
|
||||
_logger.Info($"HoangDev : EC_MsgDef.MSG_PM_PLAYERINFO");
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_PLAYERINFO, (int)MANAGER_INDEX.MAN_PLAYER, -1, pDataBuf, pCmdHeader, iHostID, _selectedRole);
|
||||
break;
|
||||
case CommandID.OBJECT_MOVE:
|
||||
@@ -352,7 +351,6 @@ namespace CSNetwork
|
||||
}
|
||||
else if (ISNPCID(idObjMove))
|
||||
{
|
||||
_logger.Info("HoangDev : NPC OBJECT_MOVE");
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_NM_NPCMOVE, (int)MANAGER_INDEX.MAN_NPC, 0, pDataBuf, pCmdHeader);
|
||||
}
|
||||
break;
|
||||
@@ -365,7 +363,6 @@ namespace CSNetwork
|
||||
}
|
||||
else if (ISNPCID(id1))
|
||||
{
|
||||
_logger.Info("HoangDev : NPC OBJECT_MOVE");
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_NM_NPCSTOPMOVE, (int)MANAGER_INDEX.MAN_NPC, 0, pDataBuf, pCmdHeader);
|
||||
}
|
||||
break;
|
||||
@@ -374,7 +371,6 @@ namespace CSNetwork
|
||||
case CommandID.OWN_IVTR_DETAIL_DATA:
|
||||
case CommandID.GET_OWN_MONEY:
|
||||
case CommandID.CHANGE_IVTR_SIZE:
|
||||
_logger.Info($"HUNG INVENTORY2");
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_IVTRINFO, (int)MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader, iHostID);
|
||||
break;
|
||||
case CommandID.EXG_IVTR_ITEM:
|
||||
@@ -385,7 +381,6 @@ namespace CSNetwork
|
||||
case CommandID.MOVE_EQUIP_ITEM:
|
||||
case CommandID.UNFREEZE_IVTR_SLOT:
|
||||
case CommandID.PLAYER_EQUIP_TRASHBOX_ITEM:
|
||||
_logger.Info($"HUNG EQUIP ITEM: " + pCmdHeader);
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_ITEMOPERATION, (int)MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
|
||||
break;
|
||||
case CommandID.MATTER_INFO_LIST:
|
||||
@@ -398,7 +393,6 @@ namespace CSNetwork
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_PICKUPITEM, (int)MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
|
||||
break;
|
||||
case CommandID.HOST_CORRECT_POS:
|
||||
_logger.Info($"HoangDev HOST_CORRECT_POSHOST_CORRECT_POSHOST_CORRECT_POS");
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_CORRECTPOS, (int)MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader, iHostID);
|
||||
break;
|
||||
case CommandID.OWN_ITEM_INFO:
|
||||
@@ -409,7 +403,6 @@ namespace CSNetwork
|
||||
case CommandID.NPC_INFO_00:
|
||||
case CommandID.NPC_ENTER_WORLD:
|
||||
case CommandID.NPC_VISIBLE_TID_NOTIFY:
|
||||
_logger.Info($"HoangDev :NPC_VISIBLE_TID_NOTIFY");
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_NM_NPCINFO, (int)MANAGER_INDEX.MAN_NPC, 0, pDataBuf, pCmdHeader, dwDataSize);
|
||||
break;
|
||||
case CommandID.TASK_DATA:
|
||||
@@ -429,12 +422,10 @@ namespace CSNetwork
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_NM_NPCATKRESULT, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
|
||||
break;
|
||||
case CommandID.HOST_ATTACKRESULT:
|
||||
BMLogger.LogError("HoangDev : HOST_ATTACKRESULT");
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_ATKRESULT, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
|
||||
break;
|
||||
case CommandID.HOST_ATTACKED:
|
||||
BMLogger.LogError("HoangDev : HOST_ATTACKED");
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_ATKRESULT, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_ATTACKED, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
|
||||
break;
|
||||
|
||||
case CommandID.ERROR_MESSAGE:
|
||||
|
||||
@@ -74,8 +74,8 @@ namespace BrewMonster
|
||||
if (!(pObject = EC_ManPlayer.GetPlayer(idObject)))
|
||||
return null;
|
||||
|
||||
if ((iAliveFlag == 1 && (pObject as EC_Player).IsDead()) ||
|
||||
(iAliveFlag == 2 && !(pObject as EC_Player).IsDead()))
|
||||
if ((iAliveFlag == 1 && (pObject as CECPlayer).IsDead()) ||
|
||||
(iAliveFlag == 2 && !(pObject as CECPlayer).IsDead()))
|
||||
return null;
|
||||
}
|
||||
//else if (GPDataTypeHelper.ISMATTERID(idObject))
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
using UnityEngine;
|
||||
using static EC_Player;
|
||||
using static CECPlayer;
|
||||
|
||||
public class PlayerIdleState : PlayerState
|
||||
{
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
using UnityEngine;
|
||||
using static EC_Player;
|
||||
using static CECPlayer;
|
||||
|
||||
public class PlayerMoveState : PlayerState
|
||||
{
|
||||
@@ -7,7 +7,7 @@ using UnityEngine;
|
||||
|
||||
namespace PerfectWorld.Scripts.Player
|
||||
{
|
||||
public class EC_ElsePlayer : EC_Player
|
||||
public class EC_ElsePlayer : CECPlayer
|
||||
{
|
||||
A3DVECTOR3 m_vMoveDir; // Player's velocity
|
||||
A3DVECTOR3 m_vServerPos; // Player's real position on server
|
||||
|
||||
@@ -52,6 +52,12 @@ namespace BrewMonster.UI
|
||||
_usernameInputField.text = "test004";
|
||||
_passwordInputField.text = "123456";
|
||||
}
|
||||
if (Input.GetKeyUp(KeyCode.Tab))
|
||||
{
|
||||
_usernameInputField.text = "test005";
|
||||
_passwordInputField.text = "123456";
|
||||
OnLoginButtonClicked();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -812,6 +812,11 @@ MonoBehaviour:
|
||||
- {fileID: 7400000, guid: 29895f3687b86a24ba1bff2318b1d817, type: 2}
|
||||
- {fileID: 7400000, guid: 9b5c3773d9888954c95132e25788ae54, type: 2}
|
||||
- {fileID: 7400000, guid: 5f21aa4feb9cf1e49b63d5e7b7d9ad58, type: 2}
|
||||
- {fileID: 7400000, guid: 4c93f18fe5082524d8ccda024f7988ad, type: 2}
|
||||
- {fileID: 7400000, guid: bc909de03ae7dcc4d824253bf652de1d, type: 2}
|
||||
- {fileID: 7400000, guid: 211cf985d64485e4ca42f7d8d6509e87, type: 2}
|
||||
- {fileID: 7400000, guid: caa9485da71a78b4da087ae69bf7120d, type: 2}
|
||||
- {fileID: 7400000, guid: 233ca05b3510f614e8b2ea31731dc298, type: 2}
|
||||
--- !u!21 &19752687
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
@@ -75381,6 +75386,182 @@ Mesh:
|
||||
offset: 0
|
||||
size: 0
|
||||
path:
|
||||
--- !u!1 &927529342
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 927529343}
|
||||
- component: {fileID: 927529345}
|
||||
- component: {fileID: 927529344}
|
||||
m_Layer: 0
|
||||
m_Name: DamageText
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &927529343
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 927529342}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1336646766}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 9000}
|
||||
m_SizeDelta: {x: 20, y: 5}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &927529344
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 927529342}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 9541d86e2fd84c1d9990edf0852d74ab, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_text:
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||
m_fontSharedMaterials: []
|
||||
m_fontMaterial: {fileID: 0}
|
||||
m_fontMaterials: []
|
||||
m_fontColor32:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_enableVertexGradient: 0
|
||||
m_colorMode: 3
|
||||
m_fontColorGradient:
|
||||
topLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
topRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_fontColorGradientPreset: {fileID: 0}
|
||||
m_spriteAsset: {fileID: 0}
|
||||
m_tintAllSprites: 0
|
||||
m_StyleSheet: {fileID: 0}
|
||||
m_TextStyleHashCode: -1183493901
|
||||
m_overrideHtmlColors: 0
|
||||
m_faceColor:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontSize: 2
|
||||
m_fontSizeBase: 2
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 0
|
||||
m_fontSizeMin: 18
|
||||
m_fontSizeMax: 72
|
||||
m_fontStyle: 0
|
||||
m_HorizontalAlignment: 2
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_TextWrappingMode: 0
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 0
|
||||
m_ActiveFontFeatures: 6e72656b
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 0
|
||||
m_isCullingEnabled: 0
|
||||
m_horizontalMapping: 0
|
||||
m_verticalMapping: 0
|
||||
m_uvLineOffset: 0
|
||||
m_geometrySortingOrder: 0
|
||||
m_IsTextObjectScaleStatic: 0
|
||||
m_VertexBufferAutoSizeReduction: 0
|
||||
m_useMaxVisibleDescender: 1
|
||||
m_pageToDisplay: 1
|
||||
m_margin: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_isUsingLegacyAnimationComponent: 0
|
||||
m_isVolumetricText: 0
|
||||
_SortingLayer: 0
|
||||
_SortingLayerID: 0
|
||||
_SortingOrder: 0
|
||||
m_hasFontAssetChanged: 0
|
||||
m_renderer: {fileID: 927529345}
|
||||
m_maskType: 0
|
||||
--- !u!23 &927529345
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 927529342}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 0
|
||||
m_ReceiveShadows: 0
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 2
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_AdditionalVertexStreams: {fileID: 0}
|
||||
--- !u!1 &928368405
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -104206,6 +104387,7 @@ GameObject:
|
||||
m_Component:
|
||||
- component: {fileID: 1336646766}
|
||||
- component: {fileID: 1336646767}
|
||||
- component: {fileID: 1336646768}
|
||||
m_Layer: 0
|
||||
m_Name: NPC Manager
|
||||
m_TagString: Untagged
|
||||
@@ -104225,7 +104407,8 @@ Transform:
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Children:
|
||||
- {fileID: 927529343}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &1336646767
|
||||
@@ -104241,6 +104424,23 @@ MonoBehaviour:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
modelPlayerCharacter: {fileID: 960760103}
|
||||
--- !u!114 &1336646768
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1336646764}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: e7981b037b60f4a4989ff59265a308ad, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
damageTextPrefab: {fileID: 927529344}
|
||||
poolSize: 20
|
||||
offset: {x: 0, y: 2, z: 0}
|
||||
riseDistance: 1.5
|
||||
riseDuration: 0.8
|
||||
--- !u!1 &1338403792
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
+151
-96
@@ -1,6 +1,7 @@
|
||||
using BrewMonster;
|
||||
using BrewMonster.Network;
|
||||
using CSNetwork;
|
||||
using CSNetwork.Common;
|
||||
using CSNetwork.GPDataType;
|
||||
using CSNetwork.Protocols;
|
||||
using CSNetwork.Protocols.RPCData;
|
||||
@@ -12,13 +13,14 @@ using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using TMPro;
|
||||
using UnityEditor.Experimental.GraphView;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UI;
|
||||
using Scene = UnityEngine.SceneManagement.Scene;
|
||||
|
||||
public class CECHostPlayer : EC_Player
|
||||
public class CECHostPlayer : CECPlayer
|
||||
{
|
||||
[SerializeField] private TextMeshPro txtName;
|
||||
[SerializeField] private CharacterController controller;
|
||||
@@ -92,12 +94,12 @@ public class CECHostPlayer : EC_Player
|
||||
|
||||
public void SetModelHostPlayer()
|
||||
{
|
||||
m_pPlayerModel = NPCManager.Instance.GetModelPlayer();
|
||||
_pPlayerModel = NPCManager.Instance.GetModelPlayer();
|
||||
Scene scene = SceneManager.GetSceneByName("WorldRender");
|
||||
SceneManager.MoveGameObjectToScene(m_pPlayerModel, scene);
|
||||
m_pPlayerModel.transform.SetParent(parentModel);
|
||||
m_pPlayerModel.transform.localPosition = Vector3.zero;
|
||||
m_pPlayerModel.SetActive(true);
|
||||
SceneManager.MoveGameObjectToScene(_pPlayerModel, scene);
|
||||
_pPlayerModel.transform.SetParent(parentModel);
|
||||
_pPlayerModel.transform.localPosition = Vector3.zero;
|
||||
_pPlayerModel.SetActive(true);
|
||||
}
|
||||
private void Start()
|
||||
{
|
||||
@@ -133,20 +135,20 @@ public class CECHostPlayer : EC_Player
|
||||
{
|
||||
CECObject clickedObject = hit.collider.gameObject.GetComponent<CECObject>();
|
||||
|
||||
if(clickedObject != null)
|
||||
if (clickedObject != null)
|
||||
{
|
||||
int idObject = CECObject.GetObjectID(clickedObject);
|
||||
if (idObject != 0)
|
||||
{
|
||||
CECNPC pNPC = EC_ManMessageMono.Instance._CECNPCMan.GetNPC(idObject);
|
||||
if(pNPC != null)
|
||||
if (pNPC != null)
|
||||
{
|
||||
if (!pNPC.IsDead()/* && m_idSelTarget == idObject*/)
|
||||
{
|
||||
idTraceTarget = idObject;
|
||||
idSelTarget = idObject;
|
||||
}
|
||||
if (idTraceTarget != 0)
|
||||
if (idTraceTarget != 0)
|
||||
{
|
||||
if (AttackableJudge(idObject, bForceAttack) == 1)
|
||||
iTraceReason = CECHPWorkTrace.Trace_reason.TRACE_ATTACK;
|
||||
@@ -339,11 +341,61 @@ public class CECHostPlayer : EC_Player
|
||||
case int value when value == EC_MsgDef.MSG_HST_PICKUPITEM:
|
||||
OnMsgHstPickupItem(Msg);
|
||||
break;
|
||||
case int value when value == EC_MsgDef.MSG_HST_SELTARGET:
|
||||
case int value when value == EC_MsgDef.MSG_HST_SELTARGET:
|
||||
OnMsgHstSelTarget(Msg); break;
|
||||
case int value when value == EC_MsgDef.MSG_HST_ATKRESULT: OnMsgHstAttackResult(Msg); break;
|
||||
//case int value when value == EC_MsgDef.MSG_HST_ATTACKED: OnMsgHstAttacked(Msg); break;
|
||||
case int value when value == EC_MsgDef.MSG_HST_HURTRESULT: OnMsgHstHurtResult(Msg); break;
|
||||
}
|
||||
}
|
||||
public void OnMsgHstAttackResult(ECMSG Msg)
|
||||
{
|
||||
BMLogger.LogError($"dwParam1 type = {Msg.dwParam1?.GetType()}");
|
||||
byte[] data = Msg.dwParam1 as byte[];
|
||||
cmd_host_attack_result pCmd = EC_Utility.ByteArrayToStructure<cmd_host_attack_result>(data);
|
||||
|
||||
int iAttackTime = 0;
|
||||
PlayAttackEffect(pCmd.idTarget, 0, 0, pCmd.iDamage, (uint)pCmd.attack_flag, pCmd.attack_speed * 50, ref iAttackTime);
|
||||
TurnFaceTo(pCmd.idTarget);
|
||||
|
||||
if (iAttackTime != 0)
|
||||
{
|
||||
if (m_pWorkMan.GetRunningWork(CECHPWork.Host_work_ID.WORK_HACKOBJECT) is CECHPWorkMelee pCurWork)
|
||||
{
|
||||
pCurWork.SetIdleTime(iAttackTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void OnMsgHstHurtResult(ECMSG Msg)
|
||||
{
|
||||
/* BMLogger.LogError("HoangDev : OnMsgHstHurtResult");
|
||||
int cmd = Convert.ToInt32(Msg.dwParam2);
|
||||
if (cmd == CommandID.BE_HURT)
|
||||
{
|
||||
cmd_be_hurt pCmd = (cmd_be_hurt)Msg.dwParam1;
|
||||
if (pCmd.damage != 0)
|
||||
Damaged(pCmd->damage);
|
||||
}
|
||||
else if (cmd == CommandID.HURT_RESULT)
|
||||
{
|
||||
cmd_hurt_result pCmd = (cmd_hurt_result)Msg.dwParam1;
|
||||
if (pCmd.target_id == m_PlayerInfo.cid)
|
||||
return; // Host himself will receive BE_HURT, so ignore this.
|
||||
|
||||
if (UnityGameSession.Instance.GameSession.ISPLAYERID(pCmd.target_id))
|
||||
{
|
||||
CECElsePlayer pTarget = m_pPlayerMan.GetElsePlayer(pCmd.target_id);
|
||||
if (pTarget)
|
||||
pTarget->Damaged(pCmd->damage);
|
||||
}
|
||||
else if (UnityGameSession.Instance.GameSession.ISNPCID(pCmd.target_id))
|
||||
{
|
||||
CECNPC pTarget = EC_ManMessageMono.Instance._CECNPCMan.GetNPC(pCmd.target_id);
|
||||
if (pTarget)
|
||||
pTarget.Damaged(pCmd.damage);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
public void OnMsgHstPickupItem(in ECMSG Msg)
|
||||
{
|
||||
var data = Msg.dwParam1 as byte[];
|
||||
@@ -351,85 +403,44 @@ public class CECHostPlayer : EC_Player
|
||||
switch (cmd)
|
||||
{
|
||||
case CommandID.PICKUP_ITEM:
|
||||
{
|
||||
// Parse the pickup item data from the server response
|
||||
if (data != null && data.Length >= 16)
|
||||
{
|
||||
int tid = BitConverter.ToInt32(data, 0);
|
||||
int expire_date = BitConverter.ToInt32(data, 4);
|
||||
uint iAmount = BitConverter.ToUInt32(data, 8);
|
||||
uint iSlotAmount = BitConverter.ToUInt32(data, 12);
|
||||
byte byPackage = data[16];
|
||||
byte bySlot = data[17];
|
||||
|
||||
Debug.Log($"[Inventory] PICKUP_ITEM: tid={tid}, expire_date={expire_date}, iAmount={iAmount}, iSlotAmount={iSlotAmount}, byPackage={byPackage}, bySlot={bySlot}");
|
||||
|
||||
// Notify pickupItem script about successful pickup
|
||||
pickupItem pickupScript = UnityEngine.Object.FindFirstObjectByType<pickupItem>();
|
||||
if (pickupScript != null)
|
||||
// Parse the pickup item data from the server response
|
||||
if (data != null && data.Length >= 16)
|
||||
{
|
||||
pickupScript.OnPickupSuccess(tid);
|
||||
}
|
||||
|
||||
// Create new inventory item data
|
||||
var newItem = new InventoryItemData
|
||||
{
|
||||
Package = byPackage,
|
||||
Slot = bySlot,
|
||||
TemplateId = tid,
|
||||
ExpireDate = expire_date,
|
||||
State = 0,
|
||||
Count = (int)iAmount,
|
||||
Crc = 0,
|
||||
Content = null
|
||||
};
|
||||
|
||||
// Add item to inventory
|
||||
EC_Inventory.SetItem(byPackage, bySlot, newItem);
|
||||
|
||||
Debug.Log($"[Inventory] Successfully added item {tid} to package {byPackage}, slot {bySlot} with count {iAmount}");
|
||||
|
||||
// Trigger UI refresh if an EC_InventoryUI is present in scene
|
||||
var ui = GameObject.FindFirstObjectByType<EC_InventoryUI>();
|
||||
if (ui != null)
|
||||
{
|
||||
ui.RefreshAll();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[Inventory] PICKUP_ITEM: Invalid data length");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public void OnMsgHstItemOperation(ECMSG Msg)
|
||||
{
|
||||
var data = Msg.dwParam1 as byte[];
|
||||
int cmd = Convert.ToInt32(Msg.dwParam2);
|
||||
switch (cmd)
|
||||
{
|
||||
case CommandID.PLAYER_DROP_ITEM:
|
||||
{
|
||||
// Parse the drop item data from the server response
|
||||
if (data != null && data.Length >= 6)
|
||||
{
|
||||
byte byPackage = data[0];
|
||||
byte bySlot = data[1];
|
||||
int count = BitConverter.ToInt32(data, 2);
|
||||
int tid = BitConverter.ToInt32(data, 6);
|
||||
byte reason = data[10];
|
||||
|
||||
Debug.Log($"[Inventory] PLAYER_DROP_ITEM: package={byPackage}, slot={bySlot}, count={count}, tid={tid}, reason={reason}");
|
||||
|
||||
// Update the inventory by removing the item
|
||||
bool success = EC_Inventory.RemoveItem(byPackage, bySlot, count);
|
||||
|
||||
if (success)
|
||||
{
|
||||
Debug.Log($"[Inventory] Successfully removed {count} items from package {byPackage}, slot {bySlot}");
|
||||
|
||||
int tid = BitConverter.ToInt32(data, 0);
|
||||
int expire_date = BitConverter.ToInt32(data, 4);
|
||||
uint iAmount = BitConverter.ToUInt32(data, 8);
|
||||
uint iSlotAmount = BitConverter.ToUInt32(data, 12);
|
||||
byte byPackage = data[16];
|
||||
byte bySlot = data[17];
|
||||
|
||||
Debug.Log($"[Inventory] PICKUP_ITEM: tid={tid}, expire_date={expire_date}, iAmount={iAmount}, iSlotAmount={iSlotAmount}, byPackage={byPackage}, bySlot={bySlot}");
|
||||
|
||||
// Notify pickupItem script about successful pickup
|
||||
pickupItem pickupScript = UnityEngine.Object.FindFirstObjectByType<pickupItem>();
|
||||
if (pickupScript != null)
|
||||
{
|
||||
pickupScript.OnPickupSuccess(tid);
|
||||
}
|
||||
|
||||
// Create new inventory item data
|
||||
var newItem = new InventoryItemData
|
||||
{
|
||||
Package = byPackage,
|
||||
Slot = bySlot,
|
||||
TemplateId = tid,
|
||||
ExpireDate = expire_date,
|
||||
State = 0,
|
||||
Count = (int)iAmount,
|
||||
Crc = 0,
|
||||
Content = null
|
||||
};
|
||||
|
||||
// Add item to inventory
|
||||
EC_Inventory.SetItem(byPackage, bySlot, newItem);
|
||||
|
||||
Debug.Log($"[Inventory] Successfully added item {tid} to package {byPackage}, slot {bySlot} with count {iAmount}");
|
||||
|
||||
// Trigger UI refresh if an EC_InventoryUI is present in scene
|
||||
var ui = GameObject.FindFirstObjectByType<EC_InventoryUI>();
|
||||
if (ui != null)
|
||||
@@ -439,15 +450,56 @@ public class CECHostPlayer : EC_Player
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[Inventory] Failed to remove items from package {byPackage}, slot {bySlot}");
|
||||
Debug.LogWarning("[Inventory] PICKUP_ITEM: Invalid data length");
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
}
|
||||
}
|
||||
public void OnMsgHstItemOperation(ECMSG Msg)
|
||||
{
|
||||
var data = Msg.dwParam1 as byte[];
|
||||
int cmd = Convert.ToInt32(Msg.dwParam2);
|
||||
switch (cmd)
|
||||
{
|
||||
case CommandID.PLAYER_DROP_ITEM:
|
||||
{
|
||||
Debug.LogWarning("[Inventory] PLAYER_DROP_ITEM: Invalid data length");
|
||||
// Parse the drop item data from the server response
|
||||
if (data != null && data.Length >= 6)
|
||||
{
|
||||
byte byPackage = data[0];
|
||||
byte bySlot = data[1];
|
||||
int count = BitConverter.ToInt32(data, 2);
|
||||
int tid = BitConverter.ToInt32(data, 6);
|
||||
byte reason = data[10];
|
||||
|
||||
Debug.Log($"[Inventory] PLAYER_DROP_ITEM: package={byPackage}, slot={bySlot}, count={count}, tid={tid}, reason={reason}");
|
||||
|
||||
// Update the inventory by removing the item
|
||||
bool success = EC_Inventory.RemoveItem(byPackage, bySlot, count);
|
||||
|
||||
if (success)
|
||||
{
|
||||
Debug.Log($"[Inventory] Successfully removed {count} items from package {byPackage}, slot {bySlot}");
|
||||
|
||||
// Trigger UI refresh if an EC_InventoryUI is present in scene
|
||||
var ui = GameObject.FindFirstObjectByType<EC_InventoryUI>();
|
||||
if (ui != null)
|
||||
{
|
||||
ui.RefreshAll();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[Inventory] Failed to remove items from package {byPackage}, slot {bySlot}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[Inventory] PLAYER_DROP_ITEM: Invalid data length");
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CommandID.EQUIP_ITEM:
|
||||
{
|
||||
byte index_inv = data[0];
|
||||
@@ -592,6 +644,7 @@ public class CECHostPlayer : EC_Player
|
||||
if (txtName != null) txtName.text = roleName;
|
||||
transform.position = pos;
|
||||
SetModelHostPlayer();
|
||||
m_dwResFlags = (uint)PlayerResourcesReadyFlag.RESFG_ALL;
|
||||
Debug.LogError("Pos Character = " + pos);
|
||||
joystick = FindAnyObjectByType<Joystick>();
|
||||
EventBus.Subscribe<JoystickRealeaseEvent>(JoystickRelease);
|
||||
@@ -932,7 +985,7 @@ public class CECHostPlayer : EC_Player
|
||||
return Mathf.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
|
||||
}
|
||||
|
||||
public int GetCharacterID(){ return m_PlayerInfo.cid; }
|
||||
public int GetCharacterID() { return m_PlayerInfo.cid; }
|
||||
|
||||
public bool CannotAttack() { return (m_dwLIES & (uint)Logic_Influence_Extned_states.LIES_DISABLEFIGHT) != 0; }
|
||||
|
||||
@@ -1001,17 +1054,19 @@ public class CECHostPlayer : EC_Player
|
||||
A3DVECTOR3 vector = new A3DVECTOR3(gameObject.transform.position.x, gameObject.transform.position.y, gameObject.transform.position.z);
|
||||
return CanTouchTarget(vector, vTargetPos, fTargetRad, iReason, fMaxCut);
|
||||
}
|
||||
public bool IsRooting() {
|
||||
public bool IsRooting()
|
||||
{
|
||||
var mask = (uint)(Logic_Influence_Extned_states.LIES_ROOT
|
||||
| Logic_Influence_Extned_states.LIES_SLEEP
|
||||
| Logic_Influence_Extned_states.LIES_STUN);
|
||||
return (m_dwLIES & mask) != 0; }
|
||||
return (m_dwLIES & mask) != 0;
|
||||
}
|
||||
|
||||
bool IsInFortress() { return m_fortressEnter.role_in_war != 0; }
|
||||
|
||||
bool IsPVPOpen() { return m_pvp.bEnable; }
|
||||
// Get faction ID
|
||||
int GetFactionID(){ return m_idFaction; }
|
||||
int GetFactionID() { return m_idFaction; }
|
||||
|
||||
public bool IsJumping() { return m_iJumpCount > 0; }
|
||||
|
||||
|
||||
@@ -3,8 +3,9 @@ using CSNetwork.GPDataType;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using static EC_Player;
|
||||
using static CECPlayer;
|
||||
|
||||
public static class EC_Utility
|
||||
{
|
||||
@@ -32,16 +33,21 @@ public static class EC_Utility
|
||||
}
|
||||
}
|
||||
public static float FIX8TOFLOAT(int x) => x / 256.0f;
|
||||
public static T ByteArrayToStructure<T>(byte[] bytes) where T : struct
|
||||
public static T ByteArrayToStructure<T>(byte[] data) where T : struct
|
||||
{
|
||||
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||
int size = Marshal.SizeOf(typeof(T));
|
||||
if (data.Length < size)
|
||||
throw new ArgumentException($"Data length {data.Length} < struct size {size}");
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(size);
|
||||
try
|
||||
{
|
||||
return Marshal.PtrToStructure<T>(handle.AddrOfPinnedObject());
|
||||
Marshal.Copy(data, 0, ptr, size);
|
||||
return Marshal.PtrToStructure<T>(ptr);
|
||||
}
|
||||
finally
|
||||
{
|
||||
handle.Free();
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
}
|
||||
}
|
||||
public static Vector3 glb_DecompressDirH(byte byDir)
|
||||
@@ -72,7 +78,18 @@ public static class EC_Utility
|
||||
{
|
||||
return Mathf.Sqrt(v.x * v.x + v.z * v.z);
|
||||
}
|
||||
public static string BuildActionName(PLAYER_ACTION action, int weaponType)
|
||||
public static string FixGBKString(string input)
|
||||
{
|
||||
// Giả sử input hiện đang là "Æð"
|
||||
// B1: lấy bytes theo "Latin1" (mỗi ký tự 1 byte giữ nguyên giá trị gốc)
|
||||
byte[] bytes = Encoding.GetEncoding("ISO-8859-1").GetBytes(input);
|
||||
|
||||
// B2: giải mã lại bằng GBK (Code page 936)
|
||||
string decoded = Encoding.GetEncoding(936).GetString(bytes);
|
||||
|
||||
return decoded;
|
||||
}
|
||||
public static string BuildActionName(PLAYER_ACTION action, int weaponType, string tail = "")
|
||||
{
|
||||
string prefix = action.data.ActionPrefix ?? string.Empty;
|
||||
string suffix = string.Empty;
|
||||
@@ -83,8 +100,8 @@ public static class EC_Utility
|
||||
{
|
||||
suffix = action.data.action_weapon_suffix[weaponType].Suffix ?? string.Empty;
|
||||
}
|
||||
|
||||
return $"{prefix}_{suffix}";
|
||||
var tailFixed = FixGBKString(tail);
|
||||
return $"{prefix}_{suffix}{tailFixed}";
|
||||
}
|
||||
|
||||
// Build pvp mask
|
||||
|
||||
@@ -54,7 +54,7 @@ public class GameController : MonoBehaviour
|
||||
Debug.LogError("null prefab");
|
||||
return;
|
||||
}
|
||||
EC_Player.InitStaticRes();
|
||||
CECPlayer.InitStaticRes();
|
||||
hostPlayer = Instantiate(characterPrefab, transform);
|
||||
hostPlayer.InitCharacter(info);
|
||||
cinemachineCamera.Follow = hostPlayer.transform;
|
||||
|
||||
@@ -5,11 +5,11 @@ public class InitializePlayer /*: IAutoInitialize*/
|
||||
{
|
||||
public void Dispose()
|
||||
{
|
||||
EC_Player.Dispose();
|
||||
CECPlayer.Dispose();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
EC_Player.InitStaticRes();
|
||||
CECPlayer.InitStaticRes();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be4a22babee7846459b0421234a44c99
|
||||
@@ -1,5 +1,7 @@
|
||||
using Animancer;
|
||||
using Animancer;
|
||||
using BrewMonster;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class PlayerVisual : MonoBehaviour
|
||||
@@ -9,10 +11,16 @@ public class PlayerVisual : MonoBehaviour
|
||||
[SerializeField] private INFO _playerInfo;
|
||||
|
||||
|
||||
[SerializeField] private AnimancerState _currentState;
|
||||
private readonly Queue<string> _animationQueue = new Queue<string>();
|
||||
|
||||
private void PlayActionEventHandler(PlayActionEvent @event)
|
||||
{
|
||||
BrewMonster.BMLogger.Log("PlayActionEventHandler : "+@event.AnimationName);
|
||||
namedAnimancer.TryPlay(@event.AnimationName);
|
||||
_currentState = namedAnimancer.TryPlay(@event.AnimationName);
|
||||
if(_currentState == null)
|
||||
{
|
||||
BMLogger.LogError("HoangDev: PlayActionEventHandler Failed ");
|
||||
}
|
||||
}
|
||||
|
||||
public void InitHostPlayerEventDoneHandler()
|
||||
@@ -23,7 +31,7 @@ public class PlayerVisual : MonoBehaviour
|
||||
BrewMonster.BMLogger.LogError("animancer == null");
|
||||
return;
|
||||
}
|
||||
var player = GetComponentInParent<EC_Player>();
|
||||
var player = GetComponentInParent<CECPlayer>();
|
||||
if(player == null)
|
||||
{
|
||||
BrewMonster.BMLogger.LogError("player == null");
|
||||
@@ -31,7 +39,44 @@ public class PlayerVisual : MonoBehaviour
|
||||
}
|
||||
_playerInfo = player.GetPlayInfo();
|
||||
EventBus.SubscribeChannel<PlayActionEvent>(_playerInfo.cid, PlayActionEventHandler);
|
||||
EventBus.SubscribeChannel<QueueActionEvent>(_playerInfo.cid, QueueActionEventHandler);
|
||||
}
|
||||
|
||||
private void QueueActionEventHandler(QueueActionEvent @event)
|
||||
{
|
||||
if(!EnqueueAnimation(@event.AnimationName))
|
||||
{
|
||||
BMLogger.LogError("HoangDev : EnqueueAnimation Failed");
|
||||
}
|
||||
}
|
||||
public bool EnqueueAnimation(string animName)
|
||||
{
|
||||
if (namedAnimancer == null) return false;
|
||||
_animationQueue.Enqueue(animName);
|
||||
if (!namedAnimancer.IsPlaying())
|
||||
PlayNext();
|
||||
else
|
||||
{
|
||||
if (_currentState == null) return false;
|
||||
_currentState.Events.OnEnd = PlayNext;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void PlayNext()
|
||||
{
|
||||
if (_animationQueue.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string animName = _animationQueue.Dequeue();
|
||||
var state = namedAnimancer.TryPlay(animName);
|
||||
|
||||
// Khi clip kết thúc thì gọi tiếp cái kế tiếp
|
||||
state.Events.OnEnd = PlayNext;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
EventBus.UnsubscribeAllInChannel(_playerInfo.cid);
|
||||
|
||||
Reference in New Issue
Block a user