Merge branch 'develop' into feature/embed-stone
# Conflicts: # Assets/Scripts/CECHostPlayer.cs
This commit is contained in:
+183
-24
@@ -61,6 +61,7 @@ namespace BrewMonster
|
||||
private int m_iRoleLastLoginTime; // Role last login time
|
||||
private int m_iAccountTotalCash;
|
||||
|
||||
private EC_PetCorral m_pPetCorral;
|
||||
private List<CECObject> m_aTabSels = new List<CECObject>();
|
||||
private List<CECSkill> m_aPtSkills = new List<CECSkill>();
|
||||
private List<CECSkill> m_aPsSkills = new List<CECSkill>();
|
||||
@@ -773,7 +774,7 @@ namespace BrewMonster
|
||||
// Is skill cool time
|
||||
int idSkill = item.idx - (int)CoolTimeIndex.GP_CT_SKILL_START;
|
||||
|
||||
COOLTIME ct = m_skillCoolTime[idSkill];
|
||||
COOLTIME ct = default;
|
||||
ct.iCurTime = item.cooldown;
|
||||
ct.iMaxTime = item.max_cooltime;
|
||||
Mathf.Clamp(ct.iCurTime, 0, ct.iMaxTime);
|
||||
@@ -936,6 +937,13 @@ namespace BrewMonster
|
||||
bActionStartSkill = true;
|
||||
iActionTime = iWaitTime;
|
||||
Debug.Log($"Cast skill({m_pCurSkill.GetSkillID()})");
|
||||
|
||||
// Special logging for return-to-town skill (167)
|
||||
// 回城技能(167)的特殊日志
|
||||
if (m_pCurSkill.GetSkillID() == ID_RETURNTOWN_SKILL)
|
||||
{
|
||||
Debug.Log($"Return-to-town skill (167) cast - State2 should trigger SetReturntown(1) on server");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case int value2 when value2 == CommandID.SKILL_PERFORM:
|
||||
@@ -947,6 +955,15 @@ namespace BrewMonster
|
||||
if (m_pCurSkill != null && m_pCurSkill.IsDurative())
|
||||
m_bSpellDSkill = true;
|
||||
|
||||
// Special handling for return-to-town skill (167)
|
||||
// 回城技能(167)的特殊处理
|
||||
// When skill 167 reaches State2, server calls SetReturntown(1) which should trigger MSG_HST_GOTO
|
||||
// 当技能167到达State2时,服务器调用SetReturntown(1),这应该触发MSG_HST_GOTO
|
||||
if (m_pCurSkill != null && m_pCurSkill.GetSkillID() == ID_RETURNTOWN_SKILL)
|
||||
{
|
||||
Debug.Log($"Skill 167 (Return to Town) performed - waiting for MSG_HST_GOTO from server");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case int value2 when value2 == CommandID.HOST_STOP_SKILL:
|
||||
@@ -1388,27 +1405,27 @@ namespace BrewMonster
|
||||
}
|
||||
}
|
||||
// Restore and convert shortcuts after loading new skills
|
||||
/* if (hostPlayer.HostIsReady())
|
||||
{
|
||||
hostPlayer.ConvertSkillShortcut(skillSCConfigArray1);
|
||||
hostPlayer.AssignSkillShortcut(skillSCConfigArray1, hostPlayer.m_aSCSets1);
|
||||
hostPlayer.ConvertSkillShortcut(skillSCConfigArray2);
|
||||
hostPlayer.AssignSkillShortcut(skillSCConfigArray2, hostPlayer.m_aSCSets2);
|
||||
hostPlayer.ConvertComboSkill();
|
||||
hostPlayer.ValidateSkillGrpShortcut(skillGrpSCConfigArray1);
|
||||
hostPlayer.AssignSkillGrpShortcut(skillGrpSCConfigArray1, hostPlayer.m_aSCSets1);
|
||||
hostPlayer.ValidateSkillGrpShortcut(skillGrpSCConfigArray2);
|
||||
hostPlayer.AssignSkillGrpShortcut(skillGrpSCConfigArray2, hostPlayer.m_aSCSets2);
|
||||
}
|
||||
if (HostIsReady())
|
||||
{
|
||||
/* ConvertSkillShortcut(skillSCConfigArray1);
|
||||
AssignSkillShortcut(skillSCConfigArray1, hostPlayer.m_aSCSets1);*/
|
||||
/* ConvertSkillShortcut(skillSCConfigArray2);
|
||||
AssignSkillShortcut(skillSCConfigArray2, hostPlayer.m_aSCSets2);*/
|
||||
/* ConvertComboSkill();
|
||||
ValidateSkillGrpShortcut(skillGrpSCConfigArray1);
|
||||
AssignSkillGrpShortcut(skillGrpSCConfigArray1, hostPlayer.m_aSCSets1);
|
||||
ValidateSkillGrpShortcut(skillGrpSCConfigArray2);
|
||||
AssignSkillGrpShortcut(skillGrpSCConfigArray2, hostPlayer.m_aSCSets2);*/
|
||||
}
|
||||
|
||||
if (hostPlayer.HostIsReady())
|
||||
{
|
||||
// Update UI when profession changes, save all shortcut configurations
|
||||
// to remove effects from intermediate skills (invalid pointers)
|
||||
// C++: CECGameUIMan *pGameUIMan = g_pGame.GetGameRun().GetUIManager().GetInGameUIMan();
|
||||
// pGameUIMan.UpdateSkillRelatedUI();
|
||||
hostPlayer.UpdateSkillRelatedUI();
|
||||
}*/
|
||||
if (HostIsReady())
|
||||
{
|
||||
// Update UI when profession changes, save all shortcut configurations
|
||||
// to remove effects from intermediate skills (invalid pointers)
|
||||
// C++: CECGameUIMan *pGameUIMan = g_pGame.GetGameRun().GetUIManager().GetInGameUIMan();
|
||||
// pGameUIMan.UpdateSkillRelatedUI();
|
||||
CECUIManager.Instance.UpdateSkillRelatedUI();
|
||||
}
|
||||
}
|
||||
|
||||
public bool HostIsReady()
|
||||
@@ -2449,9 +2466,76 @@ namespace BrewMonster
|
||||
{
|
||||
PopupManager.Instance.OnPlayerRevived();
|
||||
// p1 is a byte[] buffer; parse into cmd_notify_hostpos then set position
|
||||
// p1 是一个 byte[] 缓冲区;解析为 cmd_notify_hostpos 然后设置位置
|
||||
byte[] buf = (byte[])Msg.dwParam1;
|
||||
cmd_notify_hostpos pCmd = GPDataTypeHelper.FromBytes<cmd_notify_hostpos>(buf);
|
||||
SetPos(new Vector3(pCmd.vPos.x, pCmd.vPos.y, pCmd.vPos.z));
|
||||
|
||||
int idInst = pCmd.tag;
|
||||
Vector3 vPos = new Vector3(pCmd.vPos.x, pCmd.vPos.y, pCmd.vPos.z);
|
||||
int iLine = pCmd.line;
|
||||
|
||||
|
||||
// Call Goto method to properly handle teleportation
|
||||
// 调用 Goto 方法来正确处理传送
|
||||
if (!Goto(idInst, vPos, iLine))
|
||||
{
|
||||
Debug.LogError($"OnMsgHstGoto: Failed to teleport to instance {idInst}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Return to a target town through skill
|
||||
// 通过技能返回目标城镇
|
||||
// This method implements the Goto logic from the original C++ code
|
||||
// 此方法实现了原始 C++ 代码中的 Goto 逻辑
|
||||
private bool Goto(int idInst, Vector3 vPos, int iParallelWorldID)
|
||||
{
|
||||
// Jump to instance (change world/instance)
|
||||
// 跳转到实例(更改世界/实例)
|
||||
// Note: JumpToInstance is currently a stub in CECGameRun, so we skip the call for now
|
||||
// 注意:JumpToInstance 目前在 CECGameRun 中是一个存根,所以我们现在跳过调用
|
||||
// if (CECGameRun.Instance != null && !CECGameRun.Instance.JumpToInstance(idInst, vPos, iParallelWorldID))
|
||||
// {
|
||||
// Debug.LogError($"CECHostPlayer::Goto, Failed to jump to instance {idInst}");
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// Stop all current work and goto specified position
|
||||
// 停止所有当前工作并转到指定位置
|
||||
if (m_pWorkMan != null)
|
||||
{
|
||||
// Stop auto-moving if active
|
||||
// 如果正在自动移动则停止
|
||||
// Note: IsAutoMoving check would go here if available
|
||||
// 注意:如果可用,IsAutoMoving 检查将放在这里
|
||||
|
||||
// Finish all work
|
||||
// 完成所有工作
|
||||
m_pWorkMan.FinishAllWork(true);
|
||||
}
|
||||
|
||||
// Add a little height to ensure player's AABB won't embed with building
|
||||
// 增加一点高度以确保玩家的 AABB 不会嵌入建筑物
|
||||
vPos.y += 0.1f;
|
||||
|
||||
// Ensure we are not under ground (terrain height check would go here)
|
||||
// 确保我们不会在地下(地形高度检查将放在这里)
|
||||
// Note: Terrain height check is skipped for now as it requires world access
|
||||
// 注意:暂时跳过地形高度检查,因为它需要世界访问
|
||||
|
||||
// Set position
|
||||
// 设置位置
|
||||
SetPos(vPos);
|
||||
|
||||
// Reset jump state if available
|
||||
// 如果可用则重置跳跃状态
|
||||
// ResetJump(); // Uncomment if ResetJump method exists
|
||||
|
||||
// Update camera if available
|
||||
// 如果可用则更新相机
|
||||
// UpdateFollowCamera(false, 10); // Uncomment if UpdateFollowCamera method exists
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnMsgHstStartAttack(in ECMSG Msg)
|
||||
@@ -3409,8 +3493,13 @@ namespace BrewMonster
|
||||
m_pActionSwitcher.PostMessge((int)EMsgActionSwitcher.MSG_CASTSKILL);
|
||||
|
||||
// Return-town skill is very special, handle it separately
|
||||
//if (idSkill == ID_RETURNTOWN_SKILL)
|
||||
// return ReturnToTargetTown(0, bCombo);
|
||||
// 回城技能非常特殊,单独处理
|
||||
Debug.Log($"ApplySkillShortcut: Checking skill {idSkill}, ID_RETURNTOWN_SKILL={ID_RETURNTOWN_SKILL}");
|
||||
if (idSkill == ID_RETURNTOWN_SKILL)
|
||||
{
|
||||
Debug.Log($"ApplySkillShortcut: Skill 167 detected, calling ReturnToTargetTown");
|
||||
return ReturnToTargetTown(0, bCombo);
|
||||
}
|
||||
|
||||
//if (idSkill == ID_SUMMONPLAYER_SKILL)
|
||||
// return SummonPlayer(idSelTarget, bCombo);
|
||||
@@ -4098,6 +4187,72 @@ namespace BrewMonster
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return to a target town through skill
|
||||
// 通过技能返回目标城镇
|
||||
private bool ReturnToTargetTown(int idTarget, bool bCombo = false)
|
||||
{
|
||||
|
||||
if (!CanDo(ActionCanDo.CANDO_SPELLMAGIC))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int idSkill = ID_RETURNTOWN_SKILL;
|
||||
CECSkill pSkill = GetPositiveSkillByID(idSkill);
|
||||
if (pSkill == null) pSkill = GetEquipSkillByID(idSkill);
|
||||
if (pSkill == null)
|
||||
{
|
||||
Debug.LogError("ReturnToTargetTown: Skill 167 not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!bCombo)
|
||||
{
|
||||
// ClearComboSkill(); // Uncomment if ClearComboSkill exists
|
||||
}
|
||||
|
||||
// Check skill cast condition (commented out in ApplySkillShortcut, so skip for now)
|
||||
// int iCon = CheckSkillCastCondition(pSkill);
|
||||
// if (iCon)
|
||||
// {
|
||||
// ProcessSkillCondition(iCon);
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// If this skill is in cooling time or we are casting other skill, return
|
||||
// 如果此技能在冷却时间或我们正在施放其他技能,返回
|
||||
if (!pSkill.ReadyToCast() ||
|
||||
!m_pWorkMan.CanCastSkillImmediately(pSkill.GetSkillID()))
|
||||
{
|
||||
// If the current Work in m_pWorkMan is CECHPWorkSpell or CECHPWorkFly, it should be executed first
|
||||
// Otherwise, when receiving OBJECT_CAST_SKILL protocol, CECHPWorkSpell cannot be executed
|
||||
// This causes CECHostPlayer::IsSpellingMagic() to return false, causing the client to send c2s_CmdCancelAction
|
||||
// When this CECHPWorkSpell executes, it cannot respond
|
||||
// After this method is executed, we use the return to city mechanism
|
||||
// 如果 m_pWorkMan 中的当前 Work 是 CECHPWorkSpell 或 CECHPWorkFly,则应先执行
|
||||
// 否则,当收到 OBJECT_CAST_SKILL 协议时,CECHPWorkSpell 无法执行
|
||||
// 这会导致 CECHostPlayer::IsSpellingMagic() 返回 false,导致客户端发送 c2s_CmdCancelAction
|
||||
// 当此 CECHPWorkSpell 执行时,它无法响应
|
||||
// 在此方法执行完成后,我们使用回城机制
|
||||
Debug.LogError($"ReturnToTargetTown: Skill not ready - ReadyToCast={pSkill.ReadyToCast()}, CanCastSkillImmediately={m_pWorkMan.CanCastSkillImmediately(pSkill.GetSkillID())}");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pPrepSkill = pSkill;
|
||||
byte byPVPMask = glb_BuildPVPMask(false);
|
||||
|
||||
// Call c2s_CmdCastSkill with target parameter
|
||||
// 使用目标参数调用 c2s_CmdCastSkill
|
||||
int targets = 1;
|
||||
int[] targetsCastSkill = new int[targets];
|
||||
targetsCastSkill[0] = idTarget;
|
||||
UnityGameSession.c2s_CmdCastSkill(idSkill, byPVPMask, targets, targetsCastSkill);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public A3DVECTOR3 GetDir()
|
||||
{
|
||||
// Return forward direction from transform
|
||||
@@ -6900,5 +7055,9 @@ namespace BrewMonster
|
||||
// todo make receive request
|
||||
UnityGameSession.c2s_CmdGetItemInfo(Inventory_type.IVTRTYPE_PACK, pCmd.equip_idx);
|
||||
}
|
||||
public EC_PetCorral GetPetCorral()
|
||||
{
|
||||
return m_pPetCorral;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user