PRD-021 掉落与拾取
文档编号:PRD-021
版本:v1.0
状态:已通过
适用端:服务端 / 客户端
关联模块:LootManager、tbl/DropGroup.xml、ScenesServer
1. 背景与目标
掉落是经济系统的入口。当前存在归属不清、Roll 点重复、自动拾取漏捡等问题。本 PRD 统一掉落生成、归属保护、分配方式与拾取校验。
2. 核心规则
2.1 掉落生成
- 怪物死亡时按
drop_group独立判定每组掉落。 - 支持固定掉落、概率掉落、必掉保底、首杀掉落。
- 掉落物在地面生成实体,有独立
drop_uid与归属。 - 掉落物存在时间
drop_ttl,到期消失并写日志。
2.2 归属
- 首个有效伤害者获得归属,持续
owner_protect秒。 - 队伍/帮会按分配模式共享归属。
- 治疗者、路过者不获得归属。
- 归属者离图/下线超过 60 秒,转为公共掉落。
2.3 分配模式
| 模式 | 规则 |
|---|---|
| 自由拾取 | 归属保护期内仅归属者可捡 |
| 队长分配 | 队长拾取后手动分配 |
| Roll 点 | 归属队伍内需求/贪婪 Roll |
| 自动拾取 | 归属者自动入包,满包则留地面 |
3. 服务端设计
3.1 数据结构
struct DropEntity {
uint64_t drop_uid;
uint32_t item_id;
uint32_t count;
uint64_t owner_id;
uint32_t expire_ms;
uint8_t bind_type;
};
struct LootGroup {
uint32_t group_id;
std::vector<LootEntry> entries; // item_id, rate, min, max, bind
};
3.2 协议
| 方向 | 协议 | 说明 |
|---|---|---|
| S→C | SC_DropSpawn | 地面掉落出现 |
| S→C | SC_DropRemove | 掉落消失/被捡 |
| C→S | CS_Pickup | 拾取指定 drop_uid |
| C→S | CS_LootRoll | Roll 点选择 |
| S→C | SC_LootRollStart | 开始 Roll |
| S→C | SC_LootRollResult | Roll 结果 |
3.3 拾取流程
CS_Pickup(drop_uid)
→ 校验掉落存在、距离/地图、归属保护
→ 校验背包空间/堆叠
→ 扣地面掉落、加背包(事务)
→ 广播 SC_DropRemove
→ 写拾取日志
3.4 防作弊
- 距离校验以服务端坐标为准,容忍值 ≤ 2 格。
- 同一
drop_uid只能被拾取一次。 - Roll 点由服务端计时/结算,客户端只提交选择。
- 自动拾取也走完整校验,不跳过背包检查。
4. 客户端设计
- 地面掉落显示图标、名称、品质光柱、归属标记。
- 靠近后显示拾取提示,支持 F 键/点击拾取。
- 自动拾取可在设置中开关,只对归属自己的掉落生效。
- Roll 面板显示物品、需求/贪婪/放弃、倒计时。
- 背包满时提示“背包已满”,掉落保留在地面。
5. 配置
DropGroup.xml:group_id、item_id、rate、min_count、max_count、bind_type、announce。
Monster.xml 通过 drop_group 引用掉落组。
6. 边界与异常
| 场景 | 处理 |
|---|---|
| 多人同时拾取 | 先到先得,其余返回已消失 |
| 背包满 | 拒绝,掉落保留 |
| 归属者掉线 | 60 秒后转公共 |
| 掉落物在地图外 | 不生成或立即回收 |
| Roll 超时 | 默认放弃,重新分配 |
| 服务器重启 | 地面掉落清空,按日志补偿高价值物品 |
7. 验收标准
- 掉落组概率、数量、绑定符合配置。
- 归属保护、公共掉落、队伍分配正确。
- 拾取/自动拾取/Roll 不复制物品。
- 背包满、距离异常、重复请求被拒绝。
- 高价值掉落有公告与日志。