整理背包 SortBag 完整实现逻辑

核心目标:堆叠同类、按规则排序、空位后置、锁定物品位置不动 ,不修改物品属性(强化、时效、绑定、唯一性) 前置前提:背包是数组结构 items[pos],pos 从 1~最大格子数;格子分【锁定格子】和【普通格子】

一、整体流程总览

markdown 复制代码
输入:player玩家对象 → 取出背包数据
1. 分离锁定物品 和 待排序物品(锁定物品原位保留,不参与排序)
2. 对待排序物品做堆叠合并(满足堆叠条件才合并)
3. 对合并后的物品列表按策划排序规则排序
4. 重建背包格子:先放回锁定物品,再依次往空位填入排序后的物品
5. 落地存库 + 全量同步背包给客户端
6. 返回结果码

二、分步详细逻辑拆解

步骤1:遍历背包,分离锁定物品 & 可排序物品

遍历每一个背包格子(1 ~ 背包最大格子)

  • 如果格子有物品,并且 item.is_lock == true:放入 lock_map,key=格子位置pos,value=物品,这个格子后续不动

    锁定物品一般:穿戴中的装备、绑定锁、限时活动锁定道具、交易挂单物品

  • 如果格子有物品、非锁定 :加入待排序列表 sort_list

  • 空格子直接跳过

判断分支:如果待排序列表是空,直接返回【无需整理】,提前return,节省性能。

步骤2:物品堆叠合并(最容易出bug的环节)

堆叠判定条件必须全部同时满足:

  1. item_id 相同

  2. bind(绑定标记)相同

  3. expire_time(过期时间)相同

    理由:绑定/非绑定不能堆一起;不同到期时间的时效道具不能堆一起

拿到物品配置表 ConfigMgr:GetItemCfg(item_id),读取该物品的 stack_max(最大堆叠数量)

  • 不可堆叠物品(stack_max = 1):直接进入排序列表,跳过合并

  • 可堆叠物品:

    • 用拼接key item_id|bind|expire_time 做字典分组
    • 同key分组内,往已有物品里面加数量,加到 stack_max 上限为止
    • 填满之后剩下的数量生成新物品条目

示例: 物品A,最大堆叠99,已有60,新来50 → 原有变成99,剩余11,新建一条物品A(11)

步骤3:物品排序(策划可配优先级)

合并完成后,对 new_sort 数组执行 table.sort,排序优先级:

  1. 优先按 item_type 物品类型升序(策划配置:装备→消耗→材料→其他)

  2. 同类型下,按 item_id 升序(也可以配品质、等级,按需改)

    这里是配置驱动,想改成【品质优先】只需要修改sort回调

步骤4:回填格子(重点!锁定物品位置优先保留)

  1. 先把背包 items 数组清空

  2. 把 lock_map 里面锁定物品,原样放回原来的 pos 位置

    css 复制代码
    lock_map[5] = 屠龙 → 背包第5格固定放屠龙,不会被挤走
  3. 从头遍历所有格子 1~max_grid,找到空位依次填入排序好的物品

    • 遇到已经有锁定物品的格子:跳过
    • 遇到空位:取排序列表下一个物品填入
    • 排序列表填完,剩下所有格子保持为空

✅ 效果:锁定物品原地不动;所有可排序物品挤到锁定物品之后的空位,全部空格子集中到背包末尾

步骤5:数据持久化 + 客户端同步

  1. 把新的背包数据写入玩家存档(DbMgr落地)
  2. 调用 SyncBagAll(player),下发全量背包协议给客户端,刷新界面
  3. 写操作日志(GM调用写GM日志;玩家自助整理写普通操作日志)

三、关键业务约束(边界规则)

  1. ❌ 整理不会改变:物品uid、强化、幸运、鉴定属性、绑定、过期时间、数量
  2. ❌ 不参与排序:交易中、摆摊上架中的物品(上层加前置判断拦截)
  3. ❌ 唯一性物品(不可堆叠)不会合并
  4. ✅ 只移动格子位置,物品本身数据不变
  5. ✅ 背包最大格子上限不变,整理不会扩容

四、两种模式区分

  1. 玩家自助整理(C2S消息) :玩家点击按钮触发,权限无限制,只写普通操作日志
  2. GM指令整理 bag_sort:运营后台调用,增加角色存在校验、GM审计日志;可扩展高危参数强制忽略锁定

五、对比【仓库整理 StoreMgr:SortStore】

逻辑几乎完全复用这套算法,区别:

  • 数据源换成个人仓库/行会仓库数据
  • 同步对象:个人仓库只同步本人;行会仓库整理后同步给行会全部在线成员

六、常见坑清单(上线必查)

  1. 堆叠key没带上过期时间 → 不同时效道具合并,导致批量过期bug
  2. 锁定物品回填顺序错误 → 锁定物品被挤位置,玩家投诉
  3. 堆叠的时候超过 stack_max 上限
  4. 整理时玩家正在交易/摆摊,物品位置变动引发交易异常
  5. 只改内存数据,忘记持久化,重登变回原来顺序
相关推荐
Marcus学原理1 小时前
Playwright 入门:让浏览器自动完成重复操作
后端
弦儿1 小时前
后端 Web 实战:部门管理模块全流程(前后端分离 + RESTful + 三层架构 + 日志)
后端·restful
房西杭1 小时前
背包<->仓库转移接口(BagMgr + StoreMgr,Lua)
后端
tntxia1 小时前
设计模式中模板方法的钩子使用
后端
我的div丢了肿么办1 小时前
go语言对路由中的业务逻辑进行抽离
后端·go
leo在掘金1 小时前
纯Rust重写Photoshop,一个月7.2万Star
后端·架构
韩振方1 小时前
Kubernetes 通过资源 requests 决定 Pending Pod 能否找到节点
后端
用户360055579001 小时前
Kestrel_VLLM - 18 · 投机解码位级对拍收口:batch 与 M=1 一致,注意力路径与 CPU 逐字节对齐
后端
Thneonl1 小时前
git reset --hard 之后先别哭:reflog 里存着你刚弄丢的那个分支
运维·后端