找回密码
 register

QQ登录

只需一步,快速开始

查看: 1300|回复: 0

[系统函数] SetBagItemParam 设置背包中物品的参数 物品信息 物品数据

[复制链接]

[系统函数] SetBagItemParam 设置背包中物品的参数 物品信息 物品数据

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

主题

0

回帖

1万

积分

仙帝

积分
11929
Waylee 2021-5-30 21:39 | 显示全部楼层 |阅读模式

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

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

×

函数用法说明

函数名称LuaFnSetBagItemParam
注册函数SetBagItemParam
功能说明:设置背包中物品的参数 ***付费内容***

C++源代码(武侠世界)

VOID    _ITEM::SetItemParam(UINT start,ItemParamValue& ipv,INT value)
{
    INT TotalSize = sizeof(INT)*MAX_ITEM_PARAM;
    INT size;

    switch(ipv)
    {
    case IPV_CHAR:
        {
            size = 1;
            if( start > ( (UINT)TotalSize - (UINT)size ) )
            {
                Assert(FALSE);
            }
            *((CHAR*)m_Param+start) = (CHAR)value;
        }
        break;
    case IPV_SHORT:
        {
            size = 2;
            if(start>((UINT)TotalSize - (UINT)size))
            {
                Assert(FALSE);
            }
            *((SHORT*)((CHAR*)m_Param+start)) = (SHORT)value;
        }
        break;
    case IPV_INT:
        {
            size = 4;
            if(start>((UINT)TotalSize - (UINT)size))
            {
                Assert(FALSE);
            }
            *((INT*)((CHAR*)m_Param+start)) = (INT)value;
        }
        break;
    default:
        Assert(FALSE);
    }
}

IDA伪代码(0.85.0600)

void __cdecl _ITEM::SetItemParam(_ITEM *const this, UINT start, const ItemParamValue *const ipv, INT value)
{
  ItemParamValue v4; // eax

  v4 = *ipv;
  if ( *ipv == ItemParamValue::IPV_SHORT )
  {
    if ( start > 0xA )
      __assert__(
        "../../Common/GameStruct.cpp",
        0x213u,
        "void _ITEM::SetItemParam(UINT, const ItemParamValue&, INT)",
        "FALSE");
    *(_WORD *)((char *)this->m_Param + start) = value;
  }
  else if ( *(int *)ipv <= 1 )
  {
    if ( v4 )
LABEL_4:
      __assert__(
        "../../Common/GameStruct.cpp",
        0x223u,
        "void _ITEM::SetItemParam(UINT, const ItemParamValue&, INT)",
        "FALSE");
    if ( start > 0xB )
      __assert__(
        "../../Common/GameStruct.cpp",
        0x209u,
        "void _ITEM::SetItemParam(UINT, const ItemParamValue&, INT)",
        "FALSE");
    *((_BYTE *)this->m_Param + start) = value;
  }
  else
  {
    if ( v4 != ItemParamValue::IPV_INT )
      goto LABEL_4;
    if ( start > 8 )
      __assert__(
        "../../Common/GameStruct.cpp",
        0x21Du,
        "void _ITEM::SetItemParam(UINT, const ItemParamValue&, INT)",
        "FALSE");
    *(INT *)((char *)this->m_Param + start) = value;
  }
}

C++模拟(非游戏环境,外部模拟)

#include <iostream>
#include <cassert>
#include <cstring>

enum ItemParamValue
{
    IPV_CHAR = 0,
    IPV_SHORT = 1,
    IPV_INT = 2
};

#define MAX_ITEM_PARAM 3 // 相当于12字节的存储空间

struct _ITEM
{
    char m_Param[sizeof(int) * MAX_ITEM_PARAM]; // 12字节空间

    void SetItemParam(unsigned int start, ItemParamValue ipv, int value)
    {
        int TotalSize = sizeof(int) * MAX_ITEM_PARAM; // 12字节
        int size = 0;

        switch (ipv)
        {
        case IPV_CHAR: size = 1; break;
        case IPV_SHORT: size = 2; break;
        case IPV_INT: size = 4; break;
        default: assert(false);
        }

        if (start > (unsigned int)(TotalSize - size))
        {
            assert(false);
        }

        switch (ipv)
        {
        case IPV_CHAR:
            *((char*)(m_Param + start)) = (char)value;
            break;
        case IPV_SHORT:
            *((short*)(m_Param + start)) = (short)value;
            break;
        case IPV_INT:
            *((int*)(m_Param + start)) = (int)value;
            break;
        }
    }

    int GetItemParamValue(unsigned int start, ItemParamValue ipv)
    {
        int TotalSize = sizeof(int) * MAX_ITEM_PARAM;
        int size = 0;

        switch (ipv)
        {
        case IPV_CHAR: size = 1; break;
        case IPV_SHORT: size = 2; break;
        case IPV_INT: size = 4; break;
        default: assert(false);
        }

        if (start > (unsigned int)(TotalSize - size))
        {
            assert(false);
        }

        switch (ipv)
        {
        case IPV_CHAR:
            return *((char*)(m_Param + start));
        case IPV_SHORT:
            return *((short*)(m_Param + start));
        case IPV_INT:
            return *((int*)(m_Param + start));
        }

        return -1; // 理论上不会执行到这里
    }
};

int main()
{
    _ITEM item;
    memset(item.m_Param, 0, sizeof(item.m_Param));

    // 存储一个CHAR类型(值65)、一个SHORT类型(值300)、一个INT类型(99999)
    item.SetItemParam(0, IPV_CHAR, 65);
    item.SetItemParam(2, IPV_SHORT, 300);
    item.SetItemParam(4, IPV_INT, 99999);

    // 读取并打印,只显示数值
    int cVal = item.GetItemParamValue(0, IPV_CHAR);   // 读取CHAR存储的值 IPV_CHAR
    int sVal = item.GetItemParamValue(2, IPV_SHORT);  // 读取SHORT存储的值 IPV_SHORT
    int iVal = item.GetItemParamValue(4, IPV_INT);    // 读取INT存储的值 IPV_INT

    std::cout << "CHAR Value at offset 0: " << cVal << std::endl;
    std::cout << "SHORT Value at offset 2: " << sVal << std::endl;
    std::cout << "INT Value at offset 4: " << iVal << std::endl;

    return 0;
}

模拟函数的原理解释

一、固定大小的连续内存块:

m_Param 是一个字节数组,为物品的参数预留了一段连续内存空间。例如,如果 MAX_ITEM_PARAM = 3,则 m_Param 的大小是 sizeof(int)*3 = 12 个字节。可以把 m_Param 想象成一条长为 12 的字节格子序列,从索引0到11。

二、类型占用字节数不同:

  • IPV_CHAR:占用1字节
  • IPV_SHORT:占用2字节
  • IPV_INT:占用4字节

写入时需要根据类型确定将多少字节的数据写入到 m_Param 中。

三、偏移量(start)的含义:

start 指定了从 m_Param 的第几个字节(索引)开始存储该参数的值。
例如:

  • start=0,表示从 m_Param[0] 开始存数据。
  • 若类型为 IPV_SHORT,则在 m_Param[0]m_Param[1] 两个字节中存放这个参数的值。

四、写入操作(SetItemParam):

当执行 SetItemParam(start, ipv, value) 时,函数会:

  • 根据 ipv 确定要写入的字节数(1、2或4字节)。
  • 检查 start 和数据长度是否越过 m_Param 的边界(即不能超出总的12字节)。
  • 将传入的 value 强制转换成相应类型(char/short/int),然后以对应类型的指针将值写入到(m_Param + start) 处的内存中。

五、读取操作(GetItemParamValue):

当执行 GetItemParamValue(start, ipv) 时:

  • 根据 ipv 确定要读取几字节并如何解释这些字节。
  • (m_Param + start) 开始读取对应字节数量的数据。
  • 将这段数据解释为指定类型(char/short/int)的值,并以 int 类型返回。

六、不重叠、不越界存储:

由于不同类型占用的空间不同,为确保数据不会重叠和破坏之前存放的值,调用者需要合理分配每个参数的 start 值。

  • 比如存3个 int 类型数据(每个4字节),就应将它们存放在start=0, start=4, start=8的位置,刚好12字节排满,不会出现重叠和越界。

相关函数

GetBagItemParam 获取背包中物品的参数 物品信息 物品数据 道具信息

付费看帖
剩余 36% 内容需要支付 188.00 金币 后可完整阅读
支持付费阅读,激励作者创作更好的作品。
您需要登录后才可以回帖 登录 | register

本版积分规则

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

GMT+8, 2025-1-18 16:07 , Processed in 0.121771 second(s), 10 queries , Redis On.

Powered by XueWu Licensed

Copyright © Tencent Cloud.

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