This commit is contained in:
Tran Hai Nam
2026-04-21 15:00:20 +07:00
24 changed files with 1244 additions and 302 deletions
+15 -15
View File
@@ -254,7 +254,7 @@ namespace BrewMonster
PlayAttackEffect(pCmd.idTarget, pCmd.idSkill, 0, pCmd.iDamage, (uint)pCmd.attack_flag,
pCmd.attack_speed * 50, ref refFake, pCmd.section);
}
void OnMsgHstSkillAttacked(ECMSG Msg)
void OnMsgHstSkillAttacked(ECMSG Msg)
{
cmd_host_skill_attacked pCmd = GPDataTypeHelper.FromBytes<cmd_host_skill_attacked>((byte[])Msg.dwParam1);
@@ -333,7 +333,7 @@ namespace BrewMonster
Debug.Assert(m_pCurSkill != null, "Current skill should not be null");
return;
}
// Debug.Log($"[SKILL_CAST_DEBUG] OnMsgPlayerCastSkill: OBJECT_CAST_SKILL - Skill found, skillID={m_pCurSkill.GetSkillID()}, " +
// $"IsChargeable={m_pCurSkill.IsChargeable()}");
@@ -345,8 +345,8 @@ namespace BrewMonster
iWaitTime = pCmd.time + m_pCurSkill.GetExecuteTime();
CECHPWorkSpell pWork = (CECHPWorkSpell)m_pWorkMan.CreateWork(Host_work_ID.WORK_SPELLOBJECT);
BMLogger.LogError($"[SKILL_CAST_DEBUG] OnMsgPlayerCastSkill: Created CECHPWorkSpell for skillID={m_pCurSkill.GetSkillID()}, " +
$"executeTime={m_pCurSkill.GetExecuteTime()}, waitTime={iWaitTime}");
/*BMLogger.LogError($"[SKILL_CAST_DEBUG] OnMsgPlayerCastSkill: Created CECHPWorkSpell for skillID={m_pCurSkill.GetSkillID()}, " +
$"executeTime={m_pCurSkill.GetExecuteTime()}, waitTime={iWaitTime}");*/
pWork.PrepareCast(pCmd.target, m_pCurSkill, iWaitTime);
m_pWorkMan.StartWork_p1(pWork);
// Debug.Log($"[SKILL_CAST_DEBUG] OnMsgPlayerCastSkill: OBJECT_CAST_SKILL - Created WORK_SPELLOBJECT, " +
@@ -531,7 +531,7 @@ namespace BrewMonster
cmd_object_cast_pos_skill pCmd =
GPDataTypeHelper.FromBytes<cmd_object_cast_pos_skill>((byte[])Msg.dwParam1);
Debug.Assert(pCmd.caster == m_PlayerInfo.cid);
// Log position BEFORE flashmove processing
// 记录闪移处理前的位置
A3DVECTOR3 vHostPosBefore = EC_Utility.ToA3DVECTOR3(transform.position);
@@ -553,7 +553,7 @@ namespace BrewMonster
Debug.Assert(pSkill != null, "Skill should not be null");
break;
}
// Debug.Log($"[SKILL_CAST_DEBUG] OnMsgPlayerCastSkill: OBJECT_CAST_POS_SKILL - Skill found, skillID={pSkill.GetSkillID()}, " +
// $"type={pSkill.GetType()}, rangeType={pSkill.GetRangeType()}");
@@ -661,7 +661,7 @@ namespace BrewMonster
m_pWorkMan.StartWork_p2(pWork);
iActionTime = nExecuteTime;
// Update position tracking immediately so distance checks use correct position
// The work will move the player visually over time, but we need position tracking
// updated now so normal attacks can check distance correctly
@@ -669,7 +669,7 @@ namespace BrewMonster
// 工作将在时间上移动玩家,但我们需要现在更新位置跟踪,以便普通攻击可以正确检查距离
m_MoveCtrl.SetHostLastPos(pCmd.pos);
m_MoveCtrl.SetLastSevPos(pCmd.pos);
// Log position AFTER updating position tracking
// 记录更新位置跟踪后的位置
A3DVECTOR3 vHostPosAfter = EC_Utility.ToA3DVECTOR3(transform.position);
@@ -678,7 +678,7 @@ namespace BrewMonster
$"SetHostLastPos=({pCmd.pos.x:F2}, {pCmd.pos.y:F2}, {pCmd.pos.z:F2}), " +
$"destPos=({pCmd.pos.x:F2}, {pCmd.pos.y:F2}, {pCmd.pos.z:F2}), " +
$"executeTime={nExecuteTime}, positionChange={A3d_Magnitude(pCmd.pos - vHostPosBefore):F2}");*/
// Debug.Log($"[SKILL_CAST_DEBUG] OnMsgPlayerCastSkill: OBJECT_CAST_POS_SKILL - Created WORK_FLASHMOVE, " +
// $"skillID={pSkill.GetSkillID()}, executeTime={nExecuteTime}, destPos=({pCmd.pos.x:F2}, {pCmd.pos.y:F2}, {pCmd.pos.z:F2}), " +
// $"m_pPrepSkill={(m_pPrepSkill != null ? m_pPrepSkill.GetSkillID().ToString() : "null")}");
@@ -785,22 +785,22 @@ namespace BrewMonster
// 记录来自服务器的错误消息,用于调试距离问题
//cmd_error_message pCmd = GPDataTypeHelper.FromBytes<cmd_error_message>((byte[])Msg.dwParam1);
//int errorCode = pCmd.message;
// Common error codes:
// 2 = FIXMSG_NEEDMP (Need MP)
// 20 = FIXMSG_NEEDITEM (Need item)
// 21 = FIXMSG_TARGETISFAR (Target is too far)
// 22 = FIXMSG_TARGETTOOCLOSE (Target too close)
A3DVECTOR3 vHostPos = EC_Utility.ToA3DVECTOR3(transform.position);
int idCurrentTarget = m_idSelTarget;
CECObject pTarget = idCurrentTarget > 0 ? EC_ManMessageMono.Instance.GetObject(idCurrentTarget, 1) : null;
if (pTarget != null)
{
A3DVECTOR3 vTargetPos = EC_Utility.ToA3DVECTOR3(pTarget.transform.position);
float fDistance = A3d_Magnitude(vTargetPos - vHostPos);
BMLogger.LogError($"[DISTANCE_DEBUG] ERROR_MESSAGE from server: errorCode=, " +
$"hostPos=({vHostPos.x:F2}, {vHostPos.y:F2}, {vHostPos.z:F2}), " +
$"targetPos=({vTargetPos.x:F2}, {vTargetPos.y:F2}, {vTargetPos.z:F2}), " +
@@ -817,7 +817,7 @@ namespace BrewMonster
$"m_pCurSkill={(m_pCurSkill != null ? m_pCurSkill.GetSkillID().ToString() : "null")}, " +
$"m_pPrepSkill={(m_pPrepSkill != null ? m_pPrepSkill.GetSkillID().ToString() : "null")}");
}
bDoOtherThing = true;
break;
}
@@ -903,7 +903,7 @@ namespace BrewMonster
float fDistance = A3d_Magnitude(vTargetPos - vHostPos);
float fAttackRange = m_ExtProps.ak.AttackRange;
bool bCanTouch = CanTouchTarget(vHostPos,vTargetPos, cECNPC.GetTouchRadius(), 1); // 1 = melee
BMLogger.Log($"[DISTANCE_DEBUG] NormalAttackObject: Entry, idTarget={idTarget}, " +
$"hostPos=({vHostPos.x:F2}, {vHostPos.y:F2}, {vHostPos.z:F2}), " +
$"targetPos=({vTargetPos.x:F2}, {vTargetPos.y:F2}, {vTargetPos.z:F2}), " +
+19 -19
View File
@@ -136,7 +136,7 @@ namespace BrewMonster
int offset = sizeof(uint);
int skillSize = Marshal.SizeOf<cmd_skill_data.SKILL>();
pCmd.skill_list = new cmd_skill_data.SKILL[pCmd.skill_count];
BMLogger.LogError("OnMsgHstSkillData: skill_count= " + pCmd.skill_count);
// BMLogger.LogError("OnMsgHstSkillData: skill_count= " + pCmd.skill_count);
for (int i = 0; i < pCmd.skill_count; i++)
{
pCmd.skill_list[i] = GPDataTypeHelper.FromBytes<cmd_skill_data.SKILL>((byte[])Msg.dwParam1, offset);
@@ -517,7 +517,7 @@ namespace BrewMonster
public bool ApplySkillShortcut(int idSkill, bool bCombo = false /* false */,
int idSelTarget = 0 /* 0 */, int iForceAtk = -1 /* -1 */)
{
Debug.LogError($"ApplySkillShortcut: Skill 167 detected, calling idSkill :"+ idSkill);
// Debug.LogError($"ApplySkillShortcut: Skill 167 detected, calling idSkill :"+ idSkill);
//StackChecker::ACTrace(4);
// Debug.Log($"[SKILL_CAST_DEBUG] ApplySkillShortcut: Entry, skillID={idSkill}, bCombo={bCombo}, idSelTarget={idSelTarget}, iForceAtk={iForceAtk}, " +
@@ -564,11 +564,11 @@ namespace BrewMonster
// Debug.Log($"[SKILL_CAST_DEBUG] ApplySkillShortcut: BLOCKED - Skill {idSkill} not found");
return false;
}
// Debug.Log($"[SKILL_CAST_DEBUG] ApplySkillShortcut: Skill found, skillID={pSkill.GetSkillID()}, type={pSkill.GetType()}, " +
// $"ReadyToCast={pSkill.ReadyToCast()}, IsInstant={pSkill.IsInstant()}, IsFlashMove={pSkill.GetType() == (int)Skilltype.TYPE_FLASHMOVE}");
//// If we press a chargeable skill again when it's being charged,
//// If we press a chargeable skill again when it's being charged,
//// we cast it out at once
bool allowChargeRelease = IsSpellingMagic() && m_pCurSkill != null && m_pCurSkill.IsCharging() &&
m_pCurSkill.GetSkillID() == pSkill.GetSkillID();
@@ -696,12 +696,12 @@ namespace BrewMonster
// For C#, we try to get the object and check if it's the host's active pet
CECObject pPetObject = null;
int activePetNPCID = m_pPetCorral.GetActivePetNPCID();
if (idSelTarget != 0)
{
pPetObject = CECWorld.Instance.GetObject(idSelTarget, 0);
}
// If no pet found or target is host's active pet, cast on host's active pet
if (pPetObject == null || idSelTarget == activePetNPCID)
{
@@ -878,7 +878,7 @@ namespace BrewMonster
bool isSpelling = IsSpellingMagic();
// Debug.Log($"[SKILL_CAST_DEBUG] CastSkill: Entry, prepSkillID={prepSkillID}, idTarget={idTarget}, bForceAttack={bForceAttack}, " +
// $"ReadyToCast={readyToCast}, IsSpellingMagic={isSpelling}, IsFlashMoving={IsFlashMoving()}");
// Check if prep skill is valid, ready to cast, and not currently spelling magic
if (m_pPrepSkill == null || !m_pPrepSkill.ReadyToCast() || IsSpellingMagic())
{
@@ -998,7 +998,7 @@ namespace BrewMonster
fDist = Mathf.Abs(fDist);
A3DVECTOR3 vDest = m_MoveCtrl.FlashMove(vDir, 100.0f, fDist);
UnityEngine.Vector3 vDestVec3 = EC_Utility.ToVector3(vDest);
// Log position information before sending flashmove
// 在发送闪移前记录位置信息
A3DVECTOR3 vHostPos = EC_Utility.ToA3DVECTOR3(transform.position);
@@ -1006,7 +1006,7 @@ namespace BrewMonster
$"hostPos=({vHostPos.x:F2}, {vHostPos.y:F2}, {vHostPos.z:F2}), " +
$"destPos=({vDestVec3.x:F2}, {vDestVec3.y:F2}, {vDestVec3.z:F2}), " +
$"flashDistance={fDist:F2}, byPVPMask={byPVPMask}");
// Debug.Log($"[SKILL_CAST_DEBUG] CastSkill: Sending c2s_CmdCastPosSkill (flashmove self), skillID={prepSkillID}, " +
// $"pos=({vDestVec3.x:F2}, {vDestVec3.y:F2}, {vDestVec3.z:F2}), byPVPMask={byPVPMask}");
UnityGameSession.c2s_CmdCastPosSkill(m_pPrepSkill.GetSkillID(), vDestVec3, byPVPMask, 0, 0);
@@ -1135,7 +1135,7 @@ namespace BrewMonster
// 发送协议 (Send protocol)
UnityEngine.Vector3 vMovePosVec3 = EC_Utility.ToVector3(vMovePos);
// Log position information before sending flashmove
// 在发送闪移前记录位置信息
A3DVECTOR3 vHostPos2 = EC_Utility.ToA3DVECTOR3(transform.position);
@@ -1157,7 +1157,7 @@ namespace BrewMonster
$"destPos=({vMovePosVec3.x:F2}, {vMovePosVec3.y:F2}, {vMovePosVec3.z:F2}), " +
$"target={idTarget} (target object is null), byPVPMask={byPVPMask}");
}
// Debug.Log($"[SKILL_CAST_DEBUG] CastSkill: Sending c2s_CmdCastPosSkill (flashmove target), skillID={prepSkillID}, " +
// $"pos=({vMovePosVec3.x:F2}, {vMovePosVec3.y:F2}, {vMovePosVec3.z:F2}), target={idTarget}, byPVPMask={byPVPMask}");
UnityGameSession.c2s_CmdCastPosSkill(m_pPrepSkill.GetSkillID(), vMovePosVec3, byPVPMask, 1, idTarget);
@@ -1177,7 +1177,7 @@ namespace BrewMonster
int targets = 1;
targetsCastSkill = new int[targets];
targetsCastSkill[0] = idTarget;
// Log position and distance information before sending skill cast
// Use server-tracked position instead of visual position for accurate distance checks
// 在发送技能施放前记录位置和距离信息
@@ -1191,7 +1191,7 @@ namespace BrewMonster
float fDistance = A3d_Magnitude(vTargetPos - vHostPos);
float fSkillRange = m_pPrepSkill.GetCastRange(m_ExtProps.ak.AttackRange, GetPrayDistancePlus());
bool bCanTouch = CanTouchTarget(vTargetPos, cECNPC.GetTouchRadius(), 2); // 2 = skill
/* BMLogger.Log($"[DISTANCE_DEBUG] CastSkill: Before sending c2s_CmdCastSkill (regular), skillID={prepSkillID}, " +
$"hostPos=({vHostPos.x:F2}, {vHostPos.y:F2}, {vHostPos.z:F2}), " +
$"targetPos=({vTargetPos.x:F2}, {vTargetPos.y:F2}, {vTargetPos.z:F2}), " +
@@ -1205,7 +1205,7 @@ namespace BrewMonster
$"hostPos=({vHostPos.x:F2}, {vHostPos.y:F2}, {vHostPos.z:F2}), " +
$"target={idTarget} (target object is null), byPVPMask={byPVPMask2}");
}*/
// Debug.Log($"[SKILL_CAST_DEBUG] CastSkill: Sending c2s_CmdCastSkill (regular), skillID={prepSkillID}, " +
// $"target={idTarget}, count={targets}, byPVPMask={byPVPMask2}");
UnityGameSession.c2s_CmdCastSkill(m_pPrepSkill.GetSkillID(), byPVPMask2, targets, targetsCastSkill);
@@ -1365,13 +1365,13 @@ namespace BrewMonster
// Check skill cast condition
// Returns: 0 if success, error code otherwise
// Error codes: 1=invalid weapon, 2=need mp, 3=invalid state, 6=target wrong, 7=invalid state,
// 8=need ap, 9=not enough ammo, 10=pack full, 11=invalid env, 12=hp unsatisfied,
// 8=need ap, 9=not enough ammo, 10=pack full, 11=invalid env, 12=hp unsatisfied,
// 13=combo skill not active, 20=need item
public int CheckSkillCastCondition(CECSkill pSkill)
{
int skillID = pSkill != null ? pSkill.GetSkillID() : 0;
// Debug.Log($"[SKILL_CAST_DEBUG] CheckSkillCastCondition: Entry, skillID={skillID}, SkillCore={(pSkill.SkillCore != null ? "not null" : "null")}");
// Check if skill requires an item
if (pSkill.SkillCore != null)
{
@@ -1417,11 +1417,11 @@ namespace BrewMonster
}
else if (!CanUseEquipment(pWeapon, ref iReason))
{
Info.weapon = (iReason == 5) ? (int)pWeapon.GetDBMajorType().id : 0; }
else
{
Info.weapon = (int)pWeapon.GetDBMajorType().id; }
//BMLogger.LogError(GetName() + " CheckSkillCastCondition: Weapon major type ID = " + Info.weapon);
@@ -2005,5 +2005,5 @@ namespace BrewMonster
}
#endif
}
}
+3 -3
View File
@@ -21,7 +21,7 @@ namespace BrewMonster
handle.AddrOfPinnedObject(), typeof(cmd_host_correct_pos));
handle.Free();
//cmd_host_correct_pos pCmd = GPDataTypeHelper.FromBytes<cmd_host_correct_pos>((byte[])Msg.dwParam1);
Debug.LogError("HoangDev :pCmd.pos " + pCmd.pos);
// Debug.LogError("HoangDev :pCmd.pos " + pCmd.pos);
SetPos(pCmd.pos);
m_vVelocity.Clear();
m_CDRInfo.vAbsVelocity.Clear();
@@ -91,7 +91,7 @@ namespace BrewMonster
// pScriptMan.GetContext().GetUI().SetTipDialogTitleAndContent(AC2AS_CP(CP_UTF8, pGameUI.GetStringFromTable(11350)), AC2AS_CP(CP_UTF8, (itr.second).strName));
// pScriptMan.GetContext().GetUI().ShowTip(500, 500, 5000, 300);
// }
// }
// }
// }
// else if (Msg.dwParam2 == WAYPOINT_LIST)
@@ -301,4 +301,4 @@ namespace BrewMonster
return false;
}
}
}
}
+1 -1
View File
@@ -143,7 +143,7 @@ public partial class CECGameRun : ITickable
private void LoadPrefabs()
{
BMLogger.LogError("CECGameRun::LoadPrefabs, Loading prefabs from Resources. Consider using Addressables for better performance and memory management.");
BMLogger.LogWarning("CECGameRun::LoadPrefabs, Loading prefabs from Resources. Consider using Addressables for better performance and memory management.");
_playerPrefab = Resources.Load<GameObject>(AddressResourceConfig.PlayerPrefab);
_monsterPrefab = Resources.Load<GameObject>(AddressResourceConfig.MonsterPrefab);
_npcServerPrefab = Resources.Load<GameObject>(AddressResourceConfig.NpcServerPrefab);