找回密码
 register

QQ登录

只需一步,快速开始

查看: 1786|回复: 0

[系统函数] GetMonsterObjID 根据索引号取得怪物的ObjID

[复制链接]

[系统函数] GetMonsterObjID 根据索引号取得怪物的ObjID

[复制链接]
  • 打卡等级:热心大叔
  • 打卡总天数:94
  • 打卡月天数:17
  • 打卡总奖励:94
  • 最近打卡:2025-01-18 01:28:20
Waylee

主题

0

回帖

1万

积分

仙帝

积分
11929
Waylee 2020-8-8 21:25 | 显示全部楼层 |阅读模式

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

×

***付费内容***

IDA伪代码(地址:82DF72C):

int __cdecl LuaFnTbl::LuaFnGetMonsterObjID(lua_State_0 *L)
{
    int i;                // 循环索引,用于参数验证
    int v2;               // 存储Lua传入的第二个参数(对象索引)
    Scene *Scene;         // 指向当前场景的指针
    unsigned int v4;      // 存储从场景对象列表中获取的对象ID
    unsigned int *v5;     // 指向对象的指针(假设为Obj类型的某些属性)
    SceneManager *const v7; // 指向场景管理器的指针(可能是全局或传入的参数)
    CHAR msg[1048];       // 用于存储错误消息的缓冲区

    // 参数检查循环
    // 函数期望接收两个参数,均为数字类型。
    // 如果参数数量不足或类型不匹配,将记录错误日志。
    for (i = 1; i <= 2; ++i)
    {
        if (L) // 确保Lua状态指针不为空
        {
            if (lua_isnumber(L, i) == 1) // 检查第i个参数是否为数字
                continue; // 如果是数字,继续检查下一个参数

            // 如果第i个参数不是数字,格式化错误消息
            sub_804AC20(msg, 512, "ERROR: [%s]Param %d is illegal!", "LuaFnGetMonsterObjID", i);
        }
        else
        {
            // 如果Lua状态指针为空,格式化错误消息
            sub_804AC20(msg, 512, "ERROR: [%s] Lua_State==NULL!", "LuaFnGetMonsterObjID");
        }

        // 记录错误日志,级别为3(假设3表示错误级别)
        CacheLog(3, msg);
    }

    // 从Lua堆栈中获取参数
    // 第一个参数(索引为1):通常是SceneID,但在此函数中未使用
    lua_tonumber(L, 1); // 获取第一个参数,但未存储,可能用于其他目的或被忽略

    // 第二个参数(索引为2):对象索引(ObjIDList中的索引)
    v2 = (int)lua_tonumber(L, 2); // 将第二个参数转换为整数并存储在v2中

    // 获取当前场景
    // SceneManager::GetScene 接受场景管理器指针和SceneID作为参数,返回对应的Scene对象
    Scene = SceneManager::GetScene(v7, SceneID);
    if (!Scene)
        // 如果未找到场景对象,触发断言错误并输出错误信息
        __assertex__(
            "./Script/LuaFnTbl_Scene.h",
            0x5B0u,
            "int LuaFnTbl::LuaFnGetMonsterObjID(lua_State*)",
            "pScene",
            "Scene ID Error LuaFnGetMonsterObjID");

    // 检查当前线程ID是否与场景绑定的线程ID一致,确保线程安全
    if (ThreadValueManager::GetCurrentThreadID() != Scene->m_ThreadID)
        // 如果线程ID不匹配,触发断言错误并输出错误信息
        __assertex__(
            "./Script/LuaFnTbl_Scene.h",
            0x5B0u,
            "int LuaFnTbl::LuaFnGetMonsterObjID(lua_State*)",
            "ThreadValueManager::GetCurrentThreadID()==pScene->m_ThreadID",
            "ThreadValueManager::GetCurrentThreadID()==pScene->m_ThreadIDLuaFnGetMonsterObjID");

    // 检查对象索引v2是否在有效范围内
    if (Scene->m_ObjIDList.m_nCount <= v2)
        // 如果索引超出范围,触发断言错误
        __assert__("./Script/LuaFnTbl_Scene.h", 0x5B3u, "int LuaFnTbl::LuaFnGetMonsterObjID(lua_State*)", "FALSE");

    // 检查v2是否超过ObjIDList的最大大小(假设MAX_LIST_SIZE为512)
    if (v2 > 511)
        // 如果索引超过最大值,触发断言错误
        __assertex__(
            "./Script/LuaFnTbl_Scene.h",
            0x5B6u,
            "int LuaFnTbl::LuaFnGetMonsterObjID(lua_State*)",
            "nIndex < ObjID_List::MAX_LIST_SIZE");

    // 从场景的ObjIDList中获取对象ID
    v4 = Scene->m_ObjIDList.m_aIDs[v2];

    // 检查对象ID是否在合法范围内,且对象存在且为怪物类型
    if (v4 <= 0x752F // 检查对象ID是否小于等于0x752F(29999)
        && (v5 = (unsigned int *)Scene->m_pObjManager->m_pObj[v4]) != 0 // 检查对象指针是否不为空
        && (*(int (__cdecl **)(unsigned int *))(*v5 + 8))(v5) == 2) // 调用对象的虚函数,检查类型是否为2(假设2表示怪物)
    {
        // 如果对象是怪物,获取其ObjID并推送到Lua堆栈
        lua_pushnumber(L, (double)v5[1]); // v5[1] 假设为ObjID
    }
    else
    {
        // 如果对象不是怪物或不存在,推送-1.0到Lua堆栈表示无效
        lua_pushnumber(L, -1.0);
    }

    // 返回1,表示向Lua返回了一个值
    return 1;
}
付费看帖
剩余 9% 内容需要支付 1.00 金币 后可完整阅读
支持付费阅读,激励作者创作更好的作品。
您需要登录后才可以回帖 登录 | register

本版积分规则

雪舞知识库 | 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 |天天打卡

GMT+8, 2025-1-18 14:44 , Processed in 0.100572 second(s), 7 queries , Redis On.

Powered by XueWu Licensed

Copyright © Tencent Cloud.

快速回复 返回顶部 返回列表