Merge pull request 'fixbug/task-bug-resolve' (#168) from fixbug/task-bug-resolve into develop
Reviewed-on: https://git.pthub.vn/Unity/perfect-world-unity/pulls/168
This commit is contained in:
@@ -530,19 +530,10 @@ namespace BrewMonster.Network
|
||||
return iIndex;
|
||||
}
|
||||
|
||||
public static int GetObjectCoord(string strTargetID, ref List<OBJECT_COORD> TargetCoord)
|
||||
public static int GetObjectCoord(string strTargetID, out List<OBJECT_COORD> TargetCoord)
|
||||
{
|
||||
int count = 0;
|
||||
foreach(var coord in TargetCoord)
|
||||
{
|
||||
if(coord.strMap == strTargetID)
|
||||
{
|
||||
count++;
|
||||
TargetCoord.Add(coord);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
TargetCoord = m_CoordTab[strTargetID];
|
||||
return TargetCoord.Count;
|
||||
}
|
||||
|
||||
public static bool IsPetAutoSkill(int skill_id)
|
||||
|
||||
@@ -1278,10 +1278,42 @@ namespace BrewMonster.Scripts
|
||||
m_vMoveDest,
|
||||
null);
|
||||
|
||||
if (ret != CECIntelligentRoute.SearchResult.enumSearchSuccess)
|
||||
if (ret == CECIntelligentRoute.SearchResult.enumSearchNoPath)
|
||||
{
|
||||
// Calculate map coordinates from world coordinates
|
||||
// 从世界坐标计算地图坐标
|
||||
// Map coord formula: (world / 10) + offset (X: +400, Z: +550)
|
||||
// 地图坐标公式:(世界坐标 / 10) + 偏移量 (X: +400, Z: +550)
|
||||
int mapX = Mathf.RoundToInt(m_vMoveDest.x / 10.0f) + 400;
|
||||
int mapY = Mathf.RoundToInt(m_vMoveDest.y / 10.0f);
|
||||
int mapZ = Mathf.RoundToInt(m_vMoveDest.z / 10.0f) + 550;
|
||||
|
||||
// Show popup notification to player that path cannot be found
|
||||
// 显示弹窗通知玩家无法找到路径
|
||||
if (CECUIManager.Instance != null)
|
||||
{
|
||||
string message = $"Cannot find path to target position.\nPlease move manually to target location.\n\nMap Coordinates: ({mapX}, {mapZ}, ↑{mapY})";
|
||||
string messageCN = $"无法找到到目标位置的路径。\n请手动移动到目标位置。\n\n地图坐标: ({mapX}, {mapZ}, ↑{mapY})";
|
||||
|
||||
CECUIManager.Instance.ShowMessageBox(
|
||||
"Path Not Found", // 路径未找到
|
||||
message, // English message with map coordinates
|
||||
BrewMonster.MessageBoxType.YesButton
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[CECIntelligentRoute] Cannot find path to target position. Map Coordinates: ({mapX}, {mapZ}, ↑{mapY}). Please move manually.");
|
||||
}
|
||||
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
else if (ret != CECIntelligentRoute.SearchResult.enumSearchSuccess)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
bSwitchTo2D = false;
|
||||
break;
|
||||
|
||||
@@ -364,9 +364,12 @@ namespace BrewMonster.Scripts
|
||||
{
|
||||
if (DEBUG_AUTOPF)
|
||||
{
|
||||
BMLogger.LogWarning($"[CECIntelligentRoute] Search: no path. start=({start.x:F2},{start.y:F2},{start.z:F2}) end=({end.x:F2},{end.y:F2},{end.z:F2}) agentIndex={idx}");
|
||||
BMLogger.Log($"[CECIntelligentRoute] Search: no path found, ignoring. End position=({end.x:F2},{end.y:F2},{end.z:F2})");
|
||||
}
|
||||
ResetSearch();
|
||||
// Don't call ResetSearch() again - it was already called at the start of Search()
|
||||
// This prevents the idle state deadlock that blocks all movement
|
||||
// 不再调用 ResetSearch() - 已在 Search() 开始时调用
|
||||
// 这防止了阻止所有移动的空闲状态死锁
|
||||
return SearchResult.enumSearchNoPath;
|
||||
}
|
||||
|
||||
|
||||
@@ -1122,7 +1122,7 @@ namespace BrewMonster.Scripts.Task
|
||||
// p += sizeof(TASK_NPC_PACK_HEADER);
|
||||
|
||||
TASK_NPC_PACK_HEADER header = GPDataTypeHelper.FromBytes<TASK_NPC_PACK_HEADER>(data);
|
||||
var p = Marshal.SizeOf<TASK_NPC_PACK_HEADER>();
|
||||
long p = Marshal.SizeOf<TASK_NPC_PACK_HEADER>();
|
||||
|
||||
if (header.version != TASK_NPC_INFO_VERSION)
|
||||
{
|
||||
@@ -1150,8 +1150,7 @@ namespace BrewMonster.Scripts.Task
|
||||
// const NPC_INFO& info = pInfos[i];
|
||||
// m_NPCInfoMap[info.id] = info;
|
||||
|
||||
NPC_INFO info = GPDataTypeHelper.FromBytes<NPC_INFO>(data, p);
|
||||
p += Marshal.SizeOf<NPC_INFO>();
|
||||
NPC_INFO info = GPDataTypeHelper.FromBytes<NPC_INFO>(data, ref p);
|
||||
|
||||
m_NPCInfoMap[info.id] = info;
|
||||
}
|
||||
|
||||
@@ -129,10 +129,13 @@ namespace BrewMonster.Scripts.Task
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct NPC_INFO
|
||||
{
|
||||
public uint id;
|
||||
public uint id; // uint in C++ // uint in C++
|
||||
public short x;
|
||||
public short y;
|
||||
public short z;
|
||||
//Add padding to because the c++ struct size is auto add 2 bytes padding if not have pragmapack.
|
||||
public byte padding1; // 1 byte padding to match C++ struct size (12 bytes total) // 1字节填充以匹配C++结构体大小(总共12字节)
|
||||
public byte padding2; // 1 byte padding to match C++ struct size (12 bytes total) // 1字节填充以匹配C++结构体大小(总共12字节)
|
||||
}
|
||||
|
||||
// public class ServerNotificationConstants
|
||||
|
||||
@@ -133,7 +133,7 @@ namespace BrewMonster.UI
|
||||
m_TargetPos = new A3DVECTOR3(0, 0, 0);
|
||||
bool bInTable = false;
|
||||
m_TargetPos = EC_Game.GetGameRun().GetHostPlayer().GetObjectCoordinates(
|
||||
idTarget, ref m_Targets, ref bInTable);
|
||||
idTarget, out m_Targets, ref bInTable);
|
||||
//todo: add map feature here.
|
||||
if(!bInTable /*&& MAJOR_MAP== CECWorld.Instance.GetInstanceID())*/)
|
||||
{
|
||||
|
||||
@@ -249,7 +249,7 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
|
||||
if(cur != worldid)
|
||||
{
|
||||
EC_Game.GetObjectCoord(mapName, ref tempCoord);
|
||||
EC_Game.GetObjectCoord(mapName, out tempCoord);
|
||||
var iter = tempCoord.Find(coord => coord.strMap == strCurMap);
|
||||
instCoord.Add(iter);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,8 @@ namespace BrewMonster.Scripts.UI
|
||||
GPDataTypeHelper.ISNPCID(id) ||
|
||||
GPDataTypeHelper.ISMATTERID(id) ||
|
||||
(id > 100000000); // player ids are typically huge; template ids are usually small
|
||||
|
||||
|
||||
A3DVECTOR3 ret = new A3DVECTOR3(0);
|
||||
var world = EC_Game.GetGameRun()?.GetWorld();
|
||||
if (world != null && isLikelyRuntimeObjectId)
|
||||
{
|
||||
@@ -33,22 +34,45 @@ namespace BrewMonster.Scripts.UI
|
||||
{
|
||||
var objPos = obj.transform.position;
|
||||
in_table = true;
|
||||
return new A3DVECTOR3(objPos.x, objPos.y, objPos.z);
|
||||
BMLogger.Log($"[CECUIHelper] GetTaskObjectCoordinates isLikelyRuntimeObjectId: objPos={objPos.x},{objPos.y},{objPos.z}, inTable={in_table}");
|
||||
ret.Set(objPos.x, objPos.y, objPos.z);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
List<OBJECT_COORD> TargetTemp = new List<OBJECT_COORD>();
|
||||
ret = EC_Game.GetGameRun()?.GetHostPlayer().GetObjectCoordinates(id, out TargetTemp, ref in_table) ?? new A3DVECTOR3(0);
|
||||
|
||||
// 1) Try live NPC/Monster in scene by template id (best match to "click name -> go to that entity")
|
||||
// 1) 先尝试在场景中按模板ID查找活体NPC/怪物(最符合“点名字就去找它”)
|
||||
var npcMan = EC_ManMessageMono.Instance != null ? EC_ManMessageMono.Instance.CECNPCMan : null;
|
||||
if (npcMan != null)
|
||||
|
||||
//This only work in Major map not A61. Skip for now.
|
||||
// if(!in_table)
|
||||
// {
|
||||
// var npcMan = EC_ManMessageMono.Instance != null ? EC_ManMessageMono.Instance.CECNPCMan : null;
|
||||
// if (npcMan != null)
|
||||
// {
|
||||
// var npc = npcMan.FindNPCByTemplateID(id);
|
||||
// if (npc != null)
|
||||
// {
|
||||
// UnityEngine.Vector3 npcPos = npc.transform.position;
|
||||
// in_table = true;
|
||||
// BMLogger.Log($"[CECUIHelper] GetTaskObjectCoordinates npcMan: npcPos={npcPos.x},{npcPos.y},{npcPos.z}, inTable={in_table}");
|
||||
// ret.Set(npcPos.x, npcPos.y, npcPos.z);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// BMLogger.Log($"[CECUIHelper] GetTaskObjectCoordinates in_table: ret={ret.x},{ret.y},{ret.z}, inTable={in_table}");
|
||||
// }
|
||||
if(ret.x != 0 && ret.y != 0 && ret.z != 0)
|
||||
{
|
||||
var npc = npcMan.FindNPCByTemplateID(id);
|
||||
if (npc != null)
|
||||
{
|
||||
UnityEngine.Vector3 npcPos = npc.transform.position;
|
||||
in_table = true;
|
||||
return new A3DVECTOR3(npcPos.x, npcPos.y, npcPos.z);
|
||||
}
|
||||
BMLogger.Log($"[CECUIHelper] GetHostPlayer GetObjectCoordinates True ret={ret.x},{ret.y},{ret.z}, inTable={in_table}");
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
BMLogger.Log($"[CECUIHelper] GetHostPlayer TryGetFirstObjectCoord False ret={ret.x},{ret.y},{ret.z}, inTable={in_table}");
|
||||
}
|
||||
|
||||
// Fallback to task_npc table (C++: ATaskTemplMan::GetTaskNPCInfo)
|
||||
@@ -59,19 +83,25 @@ namespace BrewMonster.Scripts.UI
|
||||
// NOTE: Keep original PW coordinate mapping: ret.Set(x, z, y)
|
||||
// 注意:保持原版坐标映射:ret.Set(x, z, y)
|
||||
in_table = true;
|
||||
BMLogger.Log($"[CECUIHelper] GetTaskObjectCoordinates TryGetTaskNPCInfo: info.x={info.x}, info.z={info.z}, info.y={info.y}, inTable={in_table}");
|
||||
return new A3DVECTOR3(info.x, info.z, info.y);
|
||||
}
|
||||
else{
|
||||
BMLogger.Log($"[CECUIHelper] GetTaskObjectCoordinates TryGetTaskNPCInfo: not found for id={id}");
|
||||
}
|
||||
|
||||
// Fallback to coord_data.txt (C++: Configs/Coord_data.txt via CECGame::GetObjectCoord)
|
||||
// 回退到 coord_data.txt(C++:Configs/Coord_data.txt,通过 CECGame::GetObjectCoord)
|
||||
if (BrewMonster.Network.EC_Game.TryGetFirstObjectCoord(id.ToString(), out var coordPos, out var mapName))
|
||||
{
|
||||
in_table = true;
|
||||
BMLogger.Log($"[CECUIHelper] GetTaskObjectCoordinates TryGetFirstObjectCoord: coordPos.x={coordPos.x}, coordPos.y={coordPos.y}, coordPos.z={coordPos.z}, inTable={in_table}");
|
||||
return new A3DVECTOR3(coordPos.x, coordPos.y, coordPos.z);
|
||||
}
|
||||
|
||||
UnityEngine.Debug.LogWarning($"[CECUIHelper] GetTaskObjectCoordinates: Not found for id={id} (isLikelyRuntimeObjectId={isLikelyRuntimeObjectId}).");
|
||||
return new A3DVECTOR3(0);
|
||||
BMLogger.Log($"[CECUIHelper] GetTaskObjectCoordinates default return ret={ret.x},{ret.y},{ret.z}, inTable={in_table}");
|
||||
return ret;
|
||||
|
||||
// TODO: Implement this method properly
|
||||
// A3DVECTOR3 ret(0.f);
|
||||
@@ -144,6 +174,7 @@ namespace BrewMonster.Scripts.UI
|
||||
// Resolve coordinates
|
||||
bool inTable = false;
|
||||
A3DVECTOR3 vPos = GetTaskObjectCoordinates(id, ref inTable);
|
||||
BMLogger.Log($"[CECUIHelper] FollowCoord: vPos={vPos.x},{vPos.y},{vPos.z}, inTable={inTable}");
|
||||
if (!inTable)
|
||||
{
|
||||
// Fallback: use task regions if available (move to the center of the first region)
|
||||
|
||||
@@ -3653,21 +3653,19 @@ namespace BrewMonster
|
||||
public CECCounter GetIncantCnt() { return m_IncantCnt; }
|
||||
|
||||
// Get key object(NPC..) coordinates
|
||||
public A3DVECTOR3 GetObjectCoordinates(int idTarget, ref ObjectCoords TargetCoord, ref bool bInTable)
|
||||
public A3DVECTOR3 GetObjectCoordinates(int idTarget, out List<OBJECT_COORD> TargetCoord, ref bool bInTable)
|
||||
{
|
||||
if (TargetCoord == null)
|
||||
{
|
||||
TargetCoord = new ObjectCoords();
|
||||
}
|
||||
TargetCoord.Clear();
|
||||
|
||||
TargetCoord = new List<OBJECT_COORD>();
|
||||
|
||||
A3DVECTOR3 vDestPos = new A3DVECTOR3(0, 0, 0);
|
||||
|
||||
bInTable = false;
|
||||
// Get object coordinates from CECGame::m_CoordTab
|
||||
string szText = idTarget.ToString();
|
||||
List<OBJECT_COORD> tempCoord = new List<OBJECT_COORD>();
|
||||
int iCount = EC_Game.GetObjectCoord(szText, ref tempCoord);
|
||||
List<OBJECT_COORD> originalCoords = new List<OBJECT_COORD>();
|
||||
int iCount = EC_Game.GetObjectCoord(szText, out originalCoords);
|
||||
|
||||
if (iCount == 0)
|
||||
{
|
||||
return vDestPos;
|
||||
@@ -3680,11 +3678,12 @@ namespace BrewMonster
|
||||
CECInstance pInstance = CECGameRun.Instance.GetInstance(idInstance);
|
||||
string strCurMap = pInstance.GetPath();
|
||||
// �ȼ��ͬһ��ͼ���Ƿ���Ҫ���ҵ���Ʒ
|
||||
bool bHasObjectInCurrentInstance = tempCoord.Any(coord => coord.strMap == strCurMap);
|
||||
bool bHasObjectInCurrentInstance = originalCoords.Any(coord => coord.strMap == strCurMap);
|
||||
|
||||
// Iterate over original list and build filtered TargetCoord list
|
||||
for (int i = 0; i < iCount; i++)
|
||||
{
|
||||
OBJECT_COORD objCoord = tempCoord[i];
|
||||
|
||||
OBJECT_COORD objCoord = originalCoords[i];
|
||||
if (strCurMap == objCoord.strMap)
|
||||
{
|
||||
TargetCoord.Add(objCoord);
|
||||
@@ -3696,22 +3695,24 @@ namespace BrewMonster
|
||||
fMinDist = tempDist;
|
||||
bInTable = true;
|
||||
vDestPos = objCoord.vPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
// ��ǰ��ͼ��û��Ŀ��Ļ�����Ŀ�����ڵ�ͼ�ڵ�ǰ��ͼ�����
|
||||
else if (!bHasObjectInCurrentInstance)
|
||||
{
|
||||
|
||||
// find the entrance of instance
|
||||
List<OBJECT_COORD> instCoord = new List<OBJECT_COORD>();
|
||||
int iCount2 = EC_Game.GetObjectCoord(objCoord.strMap, ref instCoord);
|
||||
for (int j = 0; j < iCount2; ++j)
|
||||
int iCount2 = EC_Game.GetObjectCoord(objCoord.strMap, out instCoord);
|
||||
for (int j = 0; j < iCount2; ++j)
|
||||
{
|
||||
if (instCoord[j].strMap == strCurMap)
|
||||
{
|
||||
TargetCoord.Add(instCoord[j]);
|
||||
|
||||
|
||||
// Check if this is the nearest target
|
||||
float tempDist = (instCoord[i].vPos - GetPos()).Magnitude();
|
||||
float tempDist = (instCoord[j].vPos - GetPos()).Magnitude();
|
||||
|
||||
if (tempDist < fMinDist)
|
||||
{
|
||||
fMinDist = tempDist;
|
||||
|
||||
Reference in New Issue
Block a user