monster attack animation

This commit is contained in:
VDH
2025-10-17 17:52:36 +07:00
parent e9048c035b
commit 9b51d2aa61
12 changed files with 542 additions and 308 deletions
@@ -3,6 +3,7 @@ using CSNetwork.GPDataType;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Unity.VisualScripting;
using UnityEngine;
using static CECAttacksMan;
@@ -10,15 +11,21 @@ using static CECAttacksMan;
public class CECAttacksMan : MonoSingleton<CECAttacksMan>
{
private readonly LinkedList<CECAttackEvent> m_AttackLinkedList = new LinkedList<CECAttackEvent>();
#if UNITY_EDITOR
public List<CECAttackEvent> m_AttackList = new List<CECAttackEvent>();
#endif
private void Update()
{
#if UNITY_EDITOR
m_AttackList = m_AttackLinkedList.ToList();
#endif
var node = m_AttackLinkedList.First;
while (node != null)
{
var next = node.Next;
//BMLogger.LogError("HoangDev: Update CECAttackEvent node.Value.m_bFinished: " + node.Value.m_bFinished);
if (node.Value.m_bFinished)
m_AttackLinkedList.Remove(node);
else node.Value.Tick((uint)(Time.deltaTime * 1000));
@@ -29,7 +36,7 @@ public class CECAttacksMan : MonoSingleton<CECAttacksMan>
public CECAttackerEvents FindAttackByAttacker(int idHost)
{
CECAttackerEvents result = new CECAttackerEvents();
BMLogger.LogError("HoangDev: FindAttackByAttacker idHost: " + m_AttackLinkedList.Count);
//BMLogger.LogError("HoangDev: FindAttackByAttacker idHost: " + m_AttackLinkedList.Count);
foreach (var attack in m_AttackLinkedList)
{
if (attack.m_idHost == idHost)
@@ -41,7 +48,7 @@ public class CECAttacksMan : MonoSingleton<CECAttacksMan>
return result;
}
public CECAttackEvent AddMeleeAttack(int idHost, int idTarget, int idWeapon, uint dwModifier, int nDamage, int nTimeFly = 10)
public CECAttackEvent AddMeleeAttack(int idHost, int idTarget, int idWeapon, uint dwModifier, int nDamage, int nTimeFly = 10)
{
var newEvent = new CECAttackEvent(
this,
@@ -57,7 +64,7 @@ public class CECAttacksMan : MonoSingleton<CECAttacksMan>
nTimeFly // timeToDoDamage
);
m_AttackLinkedList.AddLast(newEvent);
BMLogger.LogError("HoangDev: FindAttackByAttacker idHost: " + m_AttackLinkedList.Count);
BMLogger.LogError("HoangDev: AddMeleeAttack CECAttackEvent: " + m_AttackLinkedList.Count);
newEvent.UpdateTargetFlag();
return m_AttackLinkedList.Last.Value;
@@ -98,6 +105,7 @@ public class CECAttacksMan : MonoSingleton<CECAttacksMan>
}
[Serializable]
public class CECAttackEvent
{
public CECAttacksMan? m_pManager;
@@ -172,7 +180,7 @@ public class CECAttackEvent
}
else if (m_timeToDoDamage != 0)
{
BMLogger.LogError("HoangDev: m_timeToDoDamage: " + m_timeToDoDamage);
BMLogger.LogError($"HoangDev: m_timeToDoDamage:{m_timeToDoDamage} , dwDeltaTime: {dwDeltaTime}");
if (m_timeToDoDamage <= dwDeltaTime)
{
m_timeToDoDamage = 0;
@@ -193,24 +201,24 @@ public class CECAttackEvent
m_bDoDamaged = true;
m_bFinished = true;
/* CECGameRun pGameRun = g_pGame-GetGameRun();
int idHostPlayer = pGameRun->GetHostPlayer()->GetCharacterID();*/
/* 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);
}*/
/* 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];
TARGET_DATA data = m_targets[i];
int idTarget = data.idTarget;
string strName;
@@ -235,28 +243,28 @@ public class CECAttackEvent
}
else if (GPDataTypeHelper.ISPLAYERID(idTarget))
{
/* CECPlayer* pPlayer = pGameRun->GetWorld()->GetPlayerMan()->GetPlayer(idTarget);
if (!pPlayer)
return true;
/* CECPlayer* pPlayer = pGameRun->GetWorld()->GetPlayerMan()->GetPlayer(idTarget);
if (!pPlayer)
return true;
strName = GetPlayerName(pPlayer);
strName = GetPlayerName(pPlayer);
pPlayer->Damaged(data.nDamage, data.dwModifier, m_idSkill);*/
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);
}
}*/
/* 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;
@@ -279,7 +287,7 @@ public class CECAttackEvent
int nNumTargets = m_targets.Count;
for (int i = 0; i < nNumTargets; i++)
{
TARGET_DATA data = m_targets[i];
TARGET_DATA data = m_targets[i];
/*
if( data.dwModifier & MOD_DEADLYSTRIKE )
{
@@ -343,7 +351,7 @@ public class CECAttackerEvents
}
enum MOD
{
{
MOD_PHYSIC_ATTACK_RUNE = 0x0001, // ÎïÀí¹¥»÷ÓÅ»¯·ûÉúЧ
MOD_MAGIC_ATTACK_RUNE = 0x0002, // ·¨Êõ¹¥»÷ÓÅ»¯·ûÉúЧ
MOD_PHYSIC_DEFENCE_RUNE = 0x0004, // ÎïÀí·ÀÓùÓÅ»¯·ûÉúЧ
@@ -25,7 +25,6 @@ public class CECNPCMan : IMsgHandler
{
if (Msg.iSubID == 0)
{
BMLogger.Log("HoangDev : CECNPCManProcessMessage " + Convert.ToInt32(Msg.dwMsg));
switch (Msg.dwMsg)
{
case long value when value == EC_MsgDef.MSG_NM_NPCINFO: OnMsgNPCInfo(Msg); break;
@@ -193,6 +192,9 @@ public class CECNPCMan : IMsgHandler
default:
return false;*/
}
CECNPC pNPC = SeekOutNPC(nid);
if (pNPC)
pNPC.ProcessMessage(Msg);
return true;
}
@@ -1,3 +1,4 @@
using BrewMonster;
using CSNetwork.GPDataType;
using CSNetwork.Protocols;
using UnityEngine;
@@ -10,6 +11,8 @@ using UnityEngine;
public class CECObject : MonoBehaviour
{
Vector3 g_vAxisY = Vector3.up;
// Class ID
public static class Class_ID
{
@@ -23,9 +26,9 @@ public class CECObject : MonoBehaviour
OCID_SERVER = 7,
OCID_MATTER = 8,
OCID_PET = 9,
OCID_CLONED_PLAYER = 10, // 复制角色模型
OCID_HOST_NAVIGATER = 11, // 纯客户端player类,用于强制移动
OCID_NPCCLONED_MASTER = 12; // NPC 复制的角色模型
OCID_CLONED_PLAYER = 10, // ¸´ÖƽÇɫģÐÍ
OCID_HOST_NAVIGATER = 11, // ´¿¿Í»§¶ËplayerÀà,ÓÃÓÚÇ¿ÖÆÒÆ¶¯
OCID_NPCCLONED_MASTER = 12; // NPC ¸´ÖƵĽÇɫģÐÍ
}
// Render flag
@@ -97,7 +100,7 @@ public class CECObject : MonoBehaviour
m_bAdjustOrient = false;
}
// Set destination orientation of model
public void SetDestDirAndUp(A3DVECTOR3 vDir, A3DVECTOR3 vUp, float dwTime)
public void SetDestDirAndUp(Vector3 vDir, Vector3 vUp, float dwTime)
{
m_bAdjustOrient = true;
m_dwOrientTime = dwTime;
@@ -145,38 +148,81 @@ public class CECObject : MonoBehaviour
}
// Turn around object and face to specified object
public virtual void TurnFaceTo(int idTarget, float dwTime = 200)
public virtual void TurnFaceTo(int idTarget, float dwTime = 5)
{
// Face to target
Vector3 vTarget = new Vector3();
CECObject pObject = EC_ManMessageMono.Instance.GetObject(idTarget, 0);
if (!pObject)
return;
if (GPDataTypeHelper.ISNPCID(idTarget))
{
CECNPC pNPC = (CECNPC)pObject;
vTarget = pNPC.transform.position;
}
else if (GPDataTypeHelper.ISPLAYERID(idTarget))
{
CECPlayer pPlayer = (CECPlayer)pObject;
vTarget = pPlayer.transform.position;
}
/* else
{
CECMatter* pMatter = g_pGame->GetGameRun()->GetWorld()->GetMatterMan()->GetMatter(idTarget);
if (pMatter && pMatter->IsMonsterSpiritMine()) vTarget = pMatter->GetPos();
else return;
}*/
// Every some time we check whether player still face to
// it's attack target.
Vector3 vDir = vTarget - transform.position;
vDir.y = 0.0f;
if (vDir.sqrMagnitude < 1e-6f)
{
vDir = transform.forward;
}
else
{
vDir.Normalize();
}
Quaternion targetRotation = Quaternion.LookRotation(vDir, Vector3.up);
// Xoay mượt từ rotation hiện tại sang rotation mục tiêu
transform.rotation = Quaternion.Slerp(
transform.rotation,
targetRotation,
Time.deltaTime * 5.0f
);
}
// Set / Get visible flag
public void SetVisible(bool bVisible)
{
m_bVisible = bVisible;
public void SetVisible(bool bVisible)
{
m_bVisible = bVisible;
}
public bool GetVisible()
{
return m_bVisible;
public bool GetVisible()
{
return m_bVisible;
}
// Get object class ID
public int GetClassID() { return m_iCID; }
public bool IsPlayer() { return m_iCID == Class_ID.OCID_HOSTPLAYER || m_iCID == Class_ID.OCID_ELSEPLAYER || m_iCID == Class_ID.OCID_LOGINPLAYER; }
public bool IsHostPlayer() { return m_iCID == Class_ID.OCID_HOSTPLAYER; }
public bool IsElsePlayer() { return m_iCID == Class_ID.OCID_ELSEPLAYER; }
public bool IsLoginPlayer(){ return m_iCID == Class_ID.OCID_LOGINPLAYER; }
public bool IsNPC() { return m_iCID == Class_ID.OCID_MONSTER || m_iCID == Class_ID.OCID_SERVER; }
public bool IsMonsterNPC() { return m_iCID == Class_ID.OCID_MONSTER; }
public bool IsServerNPC() { return m_iCID == Class_ID.OCID_SERVER; }
public bool IsMatter() { return m_iCID == Class_ID.OCID_MATTER; }
public bool IsSelectable() { return m_bSelectable; }
// Set / Get object born stamp
public uint GetBornStamp() { return m_dwBornStamp; }
public void SetBornStamp(uint dwStamp) { m_dwBornStamp = dwStamp; }
public bool IsPlayer() { return m_iCID == Class_ID.OCID_HOSTPLAYER || m_iCID == Class_ID.OCID_ELSEPLAYER || m_iCID == Class_ID.OCID_LOGINPLAYER; }
public bool IsHostPlayer() { return m_iCID == Class_ID.OCID_HOSTPLAYER; }
public bool IsElsePlayer() { return m_iCID == Class_ID.OCID_ELSEPLAYER; }
public bool IsLoginPlayer() { return m_iCID == Class_ID.OCID_LOGINPLAYER; }
public bool IsNPC() { return m_iCID == Class_ID.OCID_MONSTER || m_iCID == Class_ID.OCID_SERVER; }
public bool IsMonsterNPC() { return m_iCID == Class_ID.OCID_MONSTER; }
public bool IsServerNPC() { return m_iCID == Class_ID.OCID_SERVER; }
public bool IsMatter() { return m_iCID == Class_ID.OCID_MATTER; }
public bool IsSelectable() { return m_bSelectable; }
// Set / Get object born stamp
public uint GetBornStamp() { return m_dwBornStamp; }
public void SetBornStamp(uint dwStamp) { m_dwBornStamp = dwStamp; }
// Set / Get born in sight flag
public bool GetBornInSight() { return m_bBornInSight; }
public void SetBornInSight(bool bFlag) { m_bBornInSight = bFlag; }
public void SetBornInSight(bool bFlag) { m_bBornInSight = bFlag; }
// Get object id
public static int GetObjectID(CECObject pObject)
@@ -194,7 +240,7 @@ public class CECObject : MonoBehaviour
return 0;
}
protected int m_iCID; // Class ID
protected int m_iCID; // Class ID
protected bool m_bAdjustOrient; // Is adjusting orientation
//protected A3DQUATERNION m_quOrientStart; // Orientation start
//protected A3DQUATERNION m_quOrientEnd; // Orientation end
@@ -211,10 +257,10 @@ public class CECObject : MonoBehaviour
protected bool m_bSelectable; // whether the object can be selected
public A3DVECTOR3 GetGroundNormal(){ return m_vecGroundNormal; }
public bool GetUseGroundNormal(){ return m_bUseGroundNormal; }
public A3DVECTOR3 GetGroundNormal() { return m_vecGroundNormal; }
public bool GetUseGroundNormal() { return m_bUseGroundNormal; }
public void SetUseGroundNormal(bool bFlag)
public void SetUseGroundNormal(bool bFlag)
{
//if (m_bUseGroundNormal == bFlag)
// return;
@@ -238,7 +284,7 @@ public class CECObject : MonoBehaviour
m_vecGroundNormalSet = vecNormal;
}
protected void AdjustOrientation(float dwDeltaTime)
protected void AdjustOrientation(float dwDeltaTime)
{
}
+53 -3
View File
@@ -121,7 +121,7 @@ public abstract class CECPlayer : CECObject
m_PlayerActions = _default_actions;
m_iShape = 0;
m_aEquips = new int[(int)IndexOfIteminEquipmentInventory.SIZE_ALL_EQUIPIVTR];
queueActionEvent = new QueueActionEvent("",null,false,null);
queueActionEvent = new QueueActionEvent("", null, false, null);
}
public void SetUpPlayer()
{
@@ -644,7 +644,7 @@ public abstract class CECPlayer : CECObject
return true;
}
public void SetApplyDamage(bool isApplyDamage , CECAttackEvent cECAttackEvent)
public void SetApplyDamage(bool isApplyDamage, CECAttackEvent cECAttackEvent)
{
cECAttackEvent.m_bSignaled = isApplyDamage;
}
@@ -730,7 +730,57 @@ public abstract class CECPlayer : CECObject
// 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).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ới hướng tới target
Quaternion targetRotation = Quaternion.LookRotation(direction, Vector3.up);
// Xoay mượt từ rotation hiện tại sang rotation mục tiêu
transform.rotation = Quaternion.Slerp(
transform.rotation,
targetRotation,
Time.deltaTime * turnSpeed
);
}
}
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;
@@ -824,7 +874,7 @@ public class QueueActionEvent
public Action<bool, CECAttackEvent> SetFlag;
public CECAttackEvent AttackEvent;
public bool IsHitAnim;
public QueueActionEvent(string animationName, Action<bool,CECAttackEvent> setFlag, bool isHitAnim , CECAttackEvent attackEvent )
public QueueActionEvent(string animationName, Action<bool, CECAttackEvent> setFlag, bool isHitAnim, CECAttackEvent attackEvent)
{
this.AnimationName = animationName;
SetFlag = setFlag;
@@ -1,4 +1,4 @@
using BrewMonster;
using BrewMonster;
using CSNetwork.GPDataType;
using ModelRenderer.Scripts.GameData;
using System;
@@ -35,12 +35,12 @@ public class CECMonster : CECNPC
// If NPC doesn't have specific name, use the name in database
if ((info.state & (int)PlayerNPCState.GP_STATE_NPC_NAME) == 0)
{
m_strName = m_pDBEssence.name.ToString();
/* if (m_pPateName)
m_pPateName->SetText(m_strName, false);*/
m_strName = m_pDBEssence.name.ToString();
/* if (m_pPateName)
m_pPateName->SetText(m_strName, false);*/
}
if ((m_pDBEssence.combined_switch & (uint)MONSTER_COMBINED_SWITCH. MCS_FORBID_SELECTION) != 0)
if ((m_pDBEssence.combined_switch & (uint)MONSTER_COMBINED_SWITCH.MCS_FORBID_SELECTION) != 0)
SetSelectable(false);
transform.position = EC_Utility.ToVector3(info.pos);
@@ -48,4 +48,5 @@ public class CECMonster : CECNPC
StartWork((int)WorkType.WT_NOTHING, (int)WorkID.WORK_STAND);
return true;
}
public MONSTER_ESSENCE GetDBEssence() { return m_pDBEssence; }
}
+218 -3
View File
@@ -6,7 +6,9 @@ using System;
using System.IO;
using System.Text;
using Unity.VisualScripting;
using UnityEditor.Playables;
using UnityEngine;
using static CECPlayer;
public class CECNPC : CECObject
{
@@ -43,6 +45,7 @@ public class CECNPC : CECObject
protected CECNPCModelPolicy m_pNPCModelPolicy;
protected CECPolicyAction m_pPolicyAction;
public int m_iMMIndex;
public int m_idAttackTarget;
[SerializeField] protected float m_fMoveSpeed;
[SerializeField] protected CharacterController _characterController;
@@ -152,6 +155,210 @@ public class CECNPC : CECObject
return true;
}
public void ProcessMessage(ECMSG Msg)
{
switch (Msg.dwMsg)
{
case long value when value == EC_MsgDef.MSG_NM_NPCATKRESULT: OnMsgNPCAtkResult(Msg); break;
}
}
public void OnMsgNPCAtkResult(ECMSG msg)
{
// Giống namespace S2C trong C++
var pCmd = GPDataTypeHelper.FromBytes<cmd_object_atk_result>(msg.dwParam1 as byte[]);
if (!IsDead())
{
// Face to target
NPCTurnFaceTo(pCmd.target_id, 5);
m_idAttackTarget = pCmd.target_id;
// Start a fight work
if (IsMonsterNPC())
{
var pMonster = (CECMonster)this;
var pMonsterEssence = pMonster.GetDBEssence();
StartWork((int)WorkType.WT_NORMAL, (int)WorkID.WORK_FIGHT, (uint)(pMonsterEssence.attack_speed * 1000));
}
}
var pHost = GameController.Instance.GetHostPlayer();
int iDamage = -1;
// Attacker is host's pet
if (IsPetNPC() && GetMasterID() == pHost.GetCharacterID())
{
iDamage = pCmd.damage;
}
// Attack target is host's pet
else if (GPDataTypeHelper.ISNPCID(pCmd.target_id))
{
var pTarget = EC_ManMessageMono.Instance._CECNPCMan.GetNPC(pCmd.target_id);
if (pTarget != null && pTarget.GetMasterID() == pHost.GetCharacterID())
iDamage = pCmd.damage;
}
// Common melee attack result, idSkill = 0
PlayAttackEffect(
pCmd.target_id,
0, // idSkill
0, // dwUserData
iDamage,
(uint)pCmd.attack_flag,
pCmd.speed * 50
);
/* if (!IsDead() && IsPetNPC())
{
OnPetSays(CECPetWords.TW_FIGHT);
}*/
}
public void PlayAttackEffect(
int idTarget,
int idSkill,
int skillLevel,
int nDamage,
uint dwModifier,
int nAttackSpeed,
int nSection = 0)
{
if (m_pNPCModelPolicy == null)
return;
m_bStartFight = true;
var pAttacksMan = CECAttacksMan.Instance;
// --- Melee Attack ---
if (idSkill == 0)
{
int nTimeFly = 10;
if (IsMonsterNPC())
{
var pData = ((CECMonster)this).GetDBEssence();
if (pData.short_range_mode == 0) // cận chiến
nTimeFly = 700;
}
/* if (IsPetNPC())
{
var pData = ((CECPet)this).GetDBEssence() as PET_ESSENCE;
if (pData != null && !string.IsNullOrEmpty(pData.file_gfx_short))
nTimeFly = 700;
}*/
if (pAttacksMan.FindAttackByAttacker(m_NPCInfo.nid) != null)
{
// signal early attack event
ClearComActFlag(true);
}
// Melee attack
var pAttack = pAttacksMan.AddMeleeAttack(
m_NPCInfo.nid,
idTarget,
0,
dwModifier,
nDamage,
nTimeFly
);
if (!IsDead()
&& (dwModifier & (uint)MOD.MOD_RETORT) == 0
&& (dwModifier & (uint)MOD.MOD_ATTACK_AURA) == 0
&& PlayAttackAction(nAttackSpeed, pAttack)
&& (dwModifier & (uint)MOD.MOD_BEAT_BACK) == 0)
{
// normal flow
}
else
{
pAttack.m_bSignaled = true;
}
}
/* // --- Skill Attack ---
else
{
if (skillLevel == 0)
{
if (m_pCurSkill != null)
skillLevel = m_pCurSkill.GetSkillLevel();
else
skillLevel = 1;
}
// Try to find if there is already a skill attack event in attackman
var attackerEvents = pAttacksMan.FindAttackByAttacker(m_NPCInfo.nid);
if (attackerEvents != null)
{
var pAttack = attackerEvents.Find(idSkill, nSection);
if (pAttack != null)
{
// thêm target vào skill attack hiện có
pAttack.AddTarget(idTarget, dwModifier, nDamage);
return;
}
else
{
attackerEvents.Signal();
}
}
// Begin a new skill attack
var pNewAttack = pAttacksMan.AddSkillAttack(
m_NPCInfo.nid,
m_idCurSkillTarget,
idTarget,
0,
idSkill,
skillLevel,
dwModifier,
nDamage
);
if (pNewAttack != null)
{
pNewAttack.SetSkillSection(nSection);
if (!IsDead()
&& (dwModifier & CECAttackEvent.MOD_RETORT) == 0
&& (dwModifier & CECAttackEvent.MOD_ATTACK_AURA) == 0
&& PlaySkillAttackAction(idSkill, nAttackSpeed, nSection, ref pNewAttack.m_bSignaled)
&& (dwModifier & CECAttackEvent.MOD_BEAT_BACK) == 0)
{
// normal case
}
else
{
pNewAttack.m_bSignaled = true;
}
}
}*/
}
private bool PlayAttackAction(int nAttackSpeed, CECAttackEvent attackevent)
{
return m_pNPCModelPolicy.PlayAttackAction(nAttackSpeed, attackevent);
}
void NPCTurnFaceTo(int idTarget, uint dwTime)
{
if (IsDirFixed())
{
return;
}
// tower in war can not turn face to.
/* if (IsMonsterNPC())
{
int role_in_war = ((CECMonster)this)->GetDBEssence()->role_in_war;
if (role_in_war == 2 || role_in_war == 5)
return;
}*/
TurnFaceTo(idTarget, dwTime);
}
private void Update()
{
switch (m_iCurWork)
@@ -404,7 +611,7 @@ public class CECNPC : CECObject
}
public void ClearComActFlag(bool bSignalCurrent)
{
m_pNPCModelPolicy.ClearComActFlag(bSignalCurrent);
EventBus.PublishChannel(m_NPCInfo.nid, new ClearComActFlagEvent(true));
}
public void Damaged(int iDamage, uint dwModifier/* 0 */)
@@ -996,7 +1203,7 @@ public class CECNPC : CECObject
return (int)NPCActionIndex.ACT_NPC_WALK;
}
}
bool IsMonsterOrPet() { return IsMonsterNPC() || IsPetNPC(); }
public bool IsMonsterOrPet() { return IsMonsterNPC() || IsPetNPC(); }
bool IsMonsterNPC() { return (int)Class_ID.OCID_MONSTER == m_iCID; }
bool IsPetNPC() { return (int)Class_ID.OCID_PET == m_iCID; }
@@ -1048,7 +1255,7 @@ public class CECNPC : CECObject
}
}
}
m_pNPCModelPolicy.PlayModelAction(iAction, bRestart);
m_pNPCModelPolicy.PlayModelAction(iAction, bRestart,null);
}
bool IsDisappearing() { return m_DisappearCnt.GetCounter() != 0 ? true : false; }
@@ -1107,6 +1314,14 @@ public class CECNPC : CECObject
public float GetDistToHost() { return m_fDistToHost; }
public float GetDistToHostH() { return m_fDistToHostH; }
}
public struct ClearComActFlagEvent
{
public bool BSignalCurrent;
public ClearComActFlagEvent(bool bSignalCurrentnid)
{
BSignalCurrent = bSignalCurrentnid;
}
}
public enum WorkType
{
WT_NOTHING = 0, // Do thing
@@ -6,10 +6,10 @@ public class CECNPCModelDefaultPolicy
: CECNPCModelPolicy
{
CECModel m_pNPCModel;
CECNPC m_pNPC;
public CECNPCModelDefaultPolicy(CECNPC pNPC)
{
m_pNPCModel = new CECModel();
}
public string GetActionName(int iAct, bool bAttackStart = false)
@@ -39,7 +39,18 @@ public class CECNPCModelDefaultPolicy
m_pNPCModel.ClearComActFlag(bSignalCurrent);
}
}
public override bool PlayModelAction(int iAction, bool bRestart)
public override bool PlayAttackAction(int nAttackSpeed, CECAttackEvent attackEvent)
{
int iAction = m_pNPC.IsMonsterOrPet()
? (int)NPCActionIndex.ACT_ATTACK1 + UnityEngine.Random.Range(0, 2)
: (int)NPCActionIndex.ACT_NPC_ATTACK;
if (!PlayModelAction(iAction, true, attackEvent))
{
return false;
}
return true;
}
public override bool PlayModelAction(int iAction, bool bRestart, CECAttackEvent cECAttackEvent)
{
/* if (m_pNPCModel == null)
@@ -57,12 +68,12 @@ public class CECNPCModelDefaultPolicy
{
szAct = GetActionName((int)NPCActionIndex.ACT_WOUNDED2);
}
result = _npcVisual.TryPlayAction(szAct);
result = _npcVisual.TryPlayAction(szAct, cECAttackEvent);
}
else if (iAction == (int)NPCActionIndex.ACT_ATTACK1 || iAction == (int)NPCActionIndex.ACT_ATTACK2)
{
//bool bHideFX = !CECOptimize::Instance().GetGFX().CanShowAttack(m_pNPC->GetNPCID(), m_pNPC->GetClassID());
result = _npcVisual.TryPlayAction(GetActionName(iAction, true));
result = _npcVisual.TryPlayAction(GetActionName(iAction, true), cECAttackEvent);
if (result)
{
string szAct = GetActionName(iAction, false);
@@ -80,7 +91,7 @@ public class CECNPCModelDefaultPolicy
}
else if (iAction == (int)NPCActionIndex.ACT_IDLE)
{
result = _npcVisual.TryPlayAction(GetActionName(iAction));
result = _npcVisual.TryPlayAction(GetActionName(iAction), cECAttackEvent);
if (result)
{
string szAct2 = GetActionName((int)NPCActionIndex.ACT_STAND);
@@ -93,7 +104,7 @@ public class CECNPCModelDefaultPolicy
}
else if (iAction == (int)NPCActionIndex.ACT_NPC_IDLE1 || iAction == (int)NPCActionIndex.ACT_NPC_IDLE2)
{
result = _npcVisual.TryPlayAction(GetActionName(iAction));
result = _npcVisual.TryPlayAction(GetActionName(iAction), cECAttackEvent);
if (result)
{
string szAct2 = GetActionName((int)NPCActionIndex.ACT_NPC_STAND);
@@ -107,7 +118,7 @@ public class CECNPCModelDefaultPolicy
else if (iAction == (int)NPCActionIndex.ACT_NPC_ATTACK)
{
//bool bHideFX = !CECOptimize::Instance().GetGFX().CanShowAttack(m_pNPC->GetNPCID(), m_pNPC->GetClassID());
result = _npcVisual.TryPlayAction(GetActionName(iAction, true)); ;
result = _npcVisual.TryPlayAction(GetActionName(iAction, true), cECAttackEvent); ;
if (result)
{
string szAct = GetActionName(iAction, false);
@@ -124,7 +135,7 @@ public class CECNPCModelDefaultPolicy
}
else if (iAction == (int)NPCActionIndex.ACT_COMMON_BORN)
{
result = _npcVisual.TryPlayAction(GetActionName(iAction));
result = _npcVisual.TryPlayAction(GetActionName(iAction), cECAttackEvent);
if (result)
{
string szAct2 = GetActionName((int)NPCActionIndex.ACT_STAND);
@@ -141,7 +152,7 @@ public class CECNPCModelDefaultPolicy
{
BMLogger.LogError(GetActionName(iAction));
}
result = _npcVisual.TryPlayAction(GetActionName(iAction));
result = _npcVisual.TryPlayAction(GetActionName(iAction), cECAttackEvent);
}
return result;
}
@@ -4,10 +4,11 @@ public abstract class CECNPCModelPolicy
{
protected NPCVisual _npcVisual;
public abstract bool PlayModelAction(int iAction, bool bRestart);
public abstract bool PlayModelAction(int iAction, bool bRestart, CECAttackEvent attackevent);
public abstract bool IsPlayingAction();
public abstract bool IsPlayingAction(int iActions);
public abstract void SetNpcVisual(NPCVisual npcVisual);
public abstract bool HasAction(int iAction);
public abstract void ClearComActFlag(bool bSignalCurrent);
public abstract bool PlayAttackAction(int nAttackSpeed, CECAttackEvent attackevent);
}
+19 -3
View File
@@ -20,15 +20,24 @@ public class NPCVisual : MonoBehaviour
BMLogger.LogError(text);
}
#endif
public bool TryPlayAction(string animationName)
public bool TryPlayAction(string animationName, CECAttackEvent cECAttackEvent, bool isHit = false)
{
DEBUG("HoangDev: TryPlayAction: " + animationName);
#if UNITY_EDITOR
DEBUG("HoangDev: TryPlayAction: " + animationName);
#endif
if (namedAnimancer == null) return false;
if (namedAnimancer.IsPlaying(animationName)) return false;
_currentState = namedAnimancer.TryPlay(animationName);
if (isHit)
{
_currentState.Events.OnEnd = ()=>SetHitOnEnd(cECAttackEvent);
}
return _currentState == null;
}
private void SetHitOnEnd(CECAttackEvent cECAttackEvent)
{
cECAttackEvent.m_bSignaled = true;
}
public void InitNPCEventDoneHandler(CECNPC.INFO iNFO)
{
m_NPCInfo = iNFO;
@@ -39,7 +48,14 @@ public class NPCVisual : MonoBehaviour
return;
}
EventBus.SubscribeChannel<QueueNPCActionEvent>(m_NPCInfo.nid, OnQueueAction);
EventBus.SubscribeChannel<ClearComActFlagEvent>(m_NPCInfo.nid, OnClearComActFlagEvent);
}
private void OnClearComActFlagEvent(ClearComActFlagEvent @event)
{
_animationQueue.Clear();
}
private void Update()
{
PlayNext();
+13
View File
@@ -104301,6 +104301,7 @@ GameObject:
- component: {fileID: 1336646766}
- component: {fileID: 1336646767}
- component: {fileID: 1336646768}
- component: {fileID: 1336646769}
m_Layer: 0
m_Name: NPC Manager
m_TagString: Untagged
@@ -104354,6 +104355,18 @@ MonoBehaviour:
offset: {x: 0, y: 2, z: 0}
riseDistance: 1.5
riseDuration: 0.8
--- !u!114 &1336646769
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: 92009c5b4b0fd894790865cf674545fa, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &1338403792
GameObject:
m_ObjectHideFlags: 0
+11 -5
View File
@@ -358,9 +358,10 @@ public class CECHostPlayer : CECPlayer
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);
PlayAttackEffect(pCmd.idTarget, 0, 0, pCmd.iDamage, (uint)pCmd.attack_flag, pCmd.attack_speed * 50, ref iAttackTime);
if (iAttackTime != 0)
{
if (m_pWorkMan.GetRunningWork(CECHPWork.Host_work_ID.WORK_HACKOBJECT) is CECHPWorkMelee pCurWork)
@@ -369,6 +370,11 @@ public class CECHostPlayer : CECPlayer
}
}
}
/* public override bool IsWorkMoveRunning()
{
return m_pWorkMan.IsMovingToPosition();
}*/
private void OnMsgHstHurtResult(ECMSG Msg)
{
/* BMLogger.LogError("HoangDev : OnMsgHstHurtResult");
@@ -414,13 +420,13 @@ public class CECHostPlayer : CECPlayer
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}");
//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 = pickupItem.Instance;
if (pickupScript != null)
{
Debug.Log($"[Inventory] PICKUP_ITEM: tid={tid}, expire_date={expire_date}, iAmount={iAmount}, iSlotAmount={iSlotAmount}, byPackage={byPackage}, bySlot={bySlot}");
//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
pickupScript = UnityEngine.Object.FindFirstObjectByType<pickupItem>();
@@ -445,7 +451,7 @@ public class CECHostPlayer : CECPlayer
// 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}");
//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>();
@@ -1051,7 +1057,7 @@ public class CECHostPlayer : CECPlayer
return false;
}
public void RemoveObjectFromTabSels(CECObject pObject)
public void RemoveObjectFromTabSels(CECObject pObject)
{
for (int i = 0; i < m_aTabSels.Count; i++)
{
File diff suppressed because one or more lines are too long