***付费内容***
IDA伪代码(085)
// 定义 LuaFnTbl 类中的 LuaFnSetPos 函数,使用 __cdecl 调用约定
int __cdecl LuaFnTbl::LuaFnSetPos(lua_State *L)
{
// 声明局部变量
int i; // 循环计数器
unsigned int v2; // 存储对象 ID
Scene_3 *Scene; // 指向 Scene_3 对象的指针
Obj_Human *v4; // 指向 Obj_Human 对象的指针
long double v5; // 临时变量,用于存储 Z 坐标
Map *m_pMap; // 指向 Map 对象的指针
long double m_fX; // 临时变量,用于存储 X 坐标
long double v8; // 临时变量,用于存储 X 坐标的处理结果
long double m_CX; // 地图的最大 X 坐标
long double v10; // 处理后的 X 坐标
long double v11; // 临时变量,用于存储 Z 坐标的处理结果
long double v12; // 地图的最大 Z 坐标
long double v13; // 处理后的 Z 坐标
ORESULT v14; // 操作结果
Obj_Human *CanLogic; // 检查是否可以进行逻辑处理
AI_Human *HumanAI; // 指向 AI_Human 对象的指针
const CHAR *v18; // 指向错误描述的指针
SceneManager_1 *const v19; // 指向 SceneManager_1 对象的常量指针
const CHAR *v20; // 指向错误信息的指针
__int64 m_CZ; // 地图的最大 Z 坐标
float z; // 目标 Z 坐标
float x; // 目标 X 坐标
WORLD_POS New; // 新的世界坐标位置
char s[1048]; // 用于存储错误日志信息的缓冲区
// 参数验证:确保传递给 Lua 函数的前四个参数都是数字
for (i = 1; i <= 4; ++i)
{
if (L) // 如果 Lua 状态指针有效
{
// 检查第 i 个参数是否为数字
if (lua_isnumber((lua_State_0 *)L, i) == 1)
continue; // 如果是数字,继续循环
// 如果第 i 个参数不是数字,格式化错误信息
snprintf(s, 0x200u, "ERROR: [%s]Param %d is illegal!", "LuaFnSetPos", i);
}
else // 如果 Lua 状态指针为空
{
// 格式化错误信息
snprintf(s, 0x200u, "ERROR: [%s] Lua_State==NULL!", "LuaFnSetPos");
}
// 记录错误日志,错误级别为 3
CacheLog(3, s);
}
// 从 Lua 栈中获取参数并转换为相应的类型
lua_tonumber((lua_State_0 *)L, 1); // 获取第一个参数(场景 ID),但未使用
v2 = (unsigned int)lua_tonumber((lua_State_0 *)L, 2); // 获取第二个参数,对象 ID
x = lua_tonumber((lua_State_0 *)L, 3); // 获取第三个参数,目标 X 坐标
z = lua_tonumber((lua_State_0 *)L, 4); // 获取第四个参数,目标 Z 坐标
// 获取当前场景对象
Scene = SceneManager::GetScene(v19, g_pSceneManager);
if (!Scene) // 如果未找到场景
{
v20 = "Scene ID Error LuaFnSetPos"; // 设置错误信息
v18 = "pScene"; // 设置错误指针
LABEL_27:
// 断言失败,输出错误信息并终止程序
__assertex__("./Script/LuaFnTbl_Attr.h", 0x55u, "int LuaFnTbl::LuaFnSetPos(lua_State*)", v18, v20);
}
// 检查当前线程 ID 是否与场景的线程 ID 一致
if (ThreadValueManager::GetCurrentThreadID() != Scene->m_ThreadID)
__assertex__(
"./Script/LuaFnTbl_Attr.h",
0x55u,
"int LuaFnTbl::LuaFnSetPos(lua_State*)",
"ThreadValueManager::GetCurrentThreadID()==pScene->m_ThreadID",
"ThreadValueManager::GetCurrentThreadID()==pScene->m_ThreadIDLuaFnSetPos");
// 检查对象 ID 是否在有效范围内,并获取对应的 Obj_Human 对象
if (v2 > 0x752F || (v4 = (Obj_Human *)Scene->m_pObjManager->m_pObj[v2]) == 0)
{
v20 = "selfId Error LuaFnSetPos"; // 设置错误信息
v18 = "pObj"; // 设置错误指针
goto LABEL_27; // 跳转到断言失败处理
}
// 调用 Obj_Human 对象的第三个虚函数,检查其状态
if ( (unsigned int)((*((int (__cdecl **)(Obj_Human *))v4->_vptr_Obj + 2))(v4) - 1) <= 2 )
{
// 设置新的 X 坐标
New.m_fX = x;
v5 = 0.0; // 初始化 Z 坐标
m_pMap = Scene->m_pMap; // 获取地图对象
m_fX = 0.0; // 初始化临时变量
// 确保 X 坐标非负
if (x >= 0.0)
m_fX = New.m_fX;
// 确保 Z 坐标非负
if (z >= 0.0)
v5 = z;
v8 = m_fX; // 处理后的 X 坐标
m_CX = (long double)m_pMap->m_CX; // 获取地图的最大 X 坐标
// 确保 X 坐标不超过地图边界,保留一定余量
v10 = v8 <= m_CX ? v8 : m_CX - 0.1;
m_CZ = m_pMap->m_CZ; // 获取地图的最大 Z 坐标
New.m_fX = v10; // 设置新的 X 坐标
v11 = v5; // 处理后的 Z 坐标
v12 = (long double)m_CZ; // 地图的最大 Z 坐标
// 确保 Z 坐标不超过地图边界,保留一定余量
v13 = v11 <= v12 ? v11 : v12 - 0.1;
New.m_fZ = v13; // 设置新的 Z 坐标
// 检查新的位置是否可以到达
if (Map::IsCanGo(m_pMap, &New))
{
// 再次调用第三个虚函数,获取操作结果
v14 = (*((int (__cdecl **)(Obj_Human *))v4->_vptr_Obj + 2))(v4) - 1;
if (v14)
goto LABEL_23; // 如果操作结果满足条件,跳转到后续处理
// 检查对象是否可以进行逻辑处理
CanLogic = (Obj_Human *)Obj_Human::IsCanLogic(v4);
if (CanLogic)
{
// 获取 AI 对象,并推送空闲命令
HumanAI = Obj_Human::GetHumanAI(CanLogic);
v14 = AI_Human::PushCommand_Idle(HumanAI);
LABEL_23:
// 调用第 14 个虚函数,执行传送操作
(*((void (__cdecl **)(Obj_Human *, WORLD_POS *, _DWORD, ORESULT))v4->_vptr_Obj + 14))(v4, &New, 0, v14);
}
}
}
return 0; // 返回 0,表示函数执行完成,但不向 Lua 返回任何值
}
剩余 9% 内容需要支付 1.00
金币 后可完整阅读
支持付费阅读,激励作者创作更好的作品。
|