服务端(Go): - GM 塞背包/带属性装备发放:在线角色推送 op14 增量物品行,背包实时刷新,无需回角色选择界面 - GM 改金币/改等级:去掉在线拒绝,落库后推送 op14 钱包/op37 等级状态,在线实时刷新 - 等级端点统一切换到新版 GMSetCharacterLevel(自带在线刷新) - 无限/锁死疲劳模式 + 燃烧疲劳:每房间消耗 2 点、打怪与通关经验双倍 - 燃烧疲劳开关时给所有在线角色推送系统提示(op12 mode 0) - 深渊史诗掉率:GM 全局倍率 + 城镇增益药剂窗口倍率,真实接入掉落结算 启动器(Python/JS): - 标题栏自绘、窗口 1204x717、禁止拖拽改大小、仅最小化/关闭 - GM 工具:疲劳与燃烧、深渊史诗掉率、拍卖行上架(单一定价对齐) - 拍卖行上架前端对齐服务端单一价格语义,修复 400 报错
89 lines
8.9 KiB
Markdown
89 lines
8.9 KiB
Markdown
# PVF 事件怪物位类遭遇勘察报告(一次性)
|
||
|
||
- 勘察对象:`D:/DNF/runtime/data/dnf/Script.pvf`(111,092,341 字节,protected_nkpi,1,057,625 文件,SHA256 前缀 `1f82563b9a84d1cb`,只读未修改)
|
||
- 勘察程序:`go-server/cmd/scratch/pvfsurvey/`(`main.go`+`q1..q5.go`+`objprofile.go`,构建产物 `out/pvfsurvey.exe`;`explore*.go` 为过程探查脚本,均带 `//go:build ignore`,不进生产路径)
|
||
- 加载方式:与生产一致 `platformpvf.Open` → `worldmap.LoadSource`(参照 `dungeon_suspicious_village_elevator_test.go`);obj/lst/act 文本用同一归档的 `ReadText` + `worldmap.ParseDocument` 直接解析
|
||
- 世界表规模:maps=18,374 areas=80 dungeons=1,450 mazes=2,654
|
||
- 结果文件:`out/survey_report.json`(全量结构化)、`out/q1_event_monster_maps.tsv`、`out/q2_special_spawn_combos.tsv`、`out/q3_obj_section_census.tsv`、`out/q3_obj_signatures.tsv`、`out/q3_missing_obj_refs.tsv`、`out/q4_destroy_object_conditions.tsv`、`out/q5_elevator_candidates.tsv`
|
||
- 复现:`cd go-server && ./cmd/scratch/pvfsurvey/out/pvfsurvey.exe -phase all`(全程约 8 秒)
|
||
|
||
---
|
||
|
||
## Q1 含 EventMonsterPositions 的地图总量
|
||
|
||
- **17,207 张地图**含 `[event monster position]`(占全部 18,374 张的 93.6%);其中 **17,182 张关联到 dungeon**(经 maze specification/boss/layered 引用或 map `[dungeon]` ownership),涉及 **1,108 个 dungeon**(全部 1,450 个的 76%)。
|
||
- 位置数分布直方图:
|
||
|
||
| 位置数 | 地图数 |
|
||
|---|---|
|
||
| 3 | 9 |
|
||
| **4** | **17,052** |
|
||
| 5 | 85 |
|
||
| 6 | 17 |
|
||
| 7 | 5 |
|
||
| 8 | 39 |
|
||
|
||
- 结论:**4 个事件位是全 PVF 的普适默认形态,完全不具备区分度**。疑惑之村电梯的"4 positions"不是特征,组合结构才是。
|
||
- 25 张无 dungeon 归属的地图均为 hell 图(`hell_*.map`)、quest 图(`q*.map`)与城镇/战场起始图,也全部是 4 位。
|
||
- 完整清单:`out/q1_event_monster_maps.tsv`(17,207 行,含 dungeon 归属)。
|
||
|
||
## Q2 special passive object 生成 monster 的组合
|
||
|
||
- 全 PVF 共 **15,515 个 special passive object 摆放**,14,115 个带 Spawns;spawn Kind 归一化分布:`item`=11,959、`trap`=2,144、**`monster`=1,332**、`hellparty`=79、`quest`=6。
|
||
- Kind=monster 的 **(ObjectID, monsterCode) 组合共 110 种**,来自 **41 个不同 ObjectID** × **58 个不同 monster code**。完整清单 `out/q2_special_spawn_combos.tsv`(110 行)。
|
||
- 出现次数 Top:木桶 `221→4`(158 次/67 图)、`221→3`(117 次)、mimicbox `10231→61479`(101 次/24 图/仅 dungeon 53)、浅栖棺材 `815→403`(66 次)、哥布林碉堡 `1015→4`(66 次)。
|
||
- **电梯组合 `1112→56716` 出现 3 次,地图 [16408, 76384, 400263],全部 dungeon 53** —— 全 PVF 无第四处。
|
||
|
||
## Q3 被动对象定义文件的行为线索
|
||
|
||
`passiveobject/passiveobject.lst` 共 **25,975 条**(单行 ``id `path` `` 序列);25,479 个 .obj 读取成功、**496 个引用在归档内无文件**(全部为 10900xxxxx 段 ActionObject 条目,见 `out/q3_missing_obj_refs.tsv`,属 PVF 自身数据缺口)、0 个解析失败。
|
||
|
||
1. **行为类型声明确实存在,但只覆盖少数对象**:
|
||
- `[passive object type]`:294 个文件、**25 种值**(`[cinematic object]`×134、`[nenguard]`×37、`[missile fairy]`×17、`[warp object]`×16、各类 fairy 等)。
|
||
- `[passive object sub type]`:144 个文件、**44 种值**——这是"房间事件导演"类:`[object pattern]`×67、`[frost cave qna room]`×15、以及大量 `... start room`/`... boss room`(`[sea chase start room]`、`[time crack boss room]`、`[vilmark second room]` 等)。
|
||
- `[object destroy condition]`:5,362 个文件,种类收敛:`[destroy condition]` 5,146(主流值 `[on end of animation]` 2,441、`[time limite] N` 约 2,500、`[parent dead]` 37 等)、`[destroy action]` 109、`[on end of animation]` 25、`[on attack]` 3、另两种各 1。
|
||
- 其余高频行为字段:`[hp destroy]` 4,555、`[hp max]` 4,204、`[team]` 5,999、`[attack info]` 10,138、`[pass type]` 17,574。
|
||
2. **真正的脚本在 .act**:19,173 个 .obj 带 `[basic action]`;.act 内含 `[TRIGGER]`/`[DO BEHAVIOR]`/`[BEHAVIOR]`/`[DESTROY]` 块(样本 `questdummy/Action/dummy2.act`:按 cinematic id 触发 destroy 行为)。即动作对象是**数据驱动**的。
|
||
3. 地图实际摆放的 5,492 个对象(5,483 个在 dungeon 图)按行为分类:**scripted_action(含 .act)4,064**、declared_behavior(有行为字段无 .act)1,078、**presentation_only 仅 125**、not_in_lst 214、missing 11。行为签名共 386 种(`out/q3_obj_signatures.tsv`)。
|
||
4. **电梯三件套(1111 ElevatorScroll / 1112 ElevatorSummon / 1113 ElevatorControl)全部是 presentation_only**:只有 `[layer]`+`[basic motion]`+`[int data]`+`[name]`(1113 多 `[etc motion]`),无 type/sub type/destroy condition/basic action。**电梯行为不是数据驱动,是 EXE 硬编码**,PVF 侧只能靠"对象身份 + 地图结构"识别。
|
||
|
||
## Q4 [destroy object] clear 条件关联
|
||
|
||
- 全 PVF 共 **37 个 `[destroy object]` clear 条件**,分布在 **26 个 dungeon / 37 个 maze**,**count 全部 = 1**。
|
||
- 关联结果:**36/37 count_match**(该 dungeon 至少一张地图恰好摆放 1 个目标对象,与现行空房结算修复形状一致);唯一例外 **dungeon 1002(永恒梦境)maze 0 目标 16072(`ActionObject/Monster/3_Time.obj`)在任何关联地图上都找不到摆放**。
|
||
- 目标 ID 与 op38 u16 分界:**11 个条件 target > 65535**(69291/69292/80454/80456/80458/80459/85194/64060/64062/53764…,即现行修复覆盖的形状),**26 个 ≤ 65535**(可进普通 actor 表)。目标 ID 全集 13 个值。
|
||
- 完整清单:`out/q4_destroy_object_conditions.tsv`。
|
||
|
||
## Q5 电梯同款候选
|
||
|
||
- 规则"≥1 EventMonsterPositions 且 special 生成 monster"共命中 **413 张地图**、35 个 dungeon。但按"special 对象 ID 集合"聚簇只有 **28 个类簇**:
|
||
|
||
| 类簇(special 对象) | 地图数 | dungeon | 性质 |
|
||
|---|---|---|---|
|
||
| [221] 木桶 | 182 | 2-9 | 破坏出怪(scripted) |
|
||
| [815] 浅栖棺材 | 49 | 31/32/35/3011/3012 | 破坏出怪 |
|
||
| [1015] 哥布林碉堡 | 34 | 3/4/7/9 | 陷阱出怪 |
|
||
| [10231] mimicbox | 24 | **53** | 破坏出怪(宝箱怪) |
|
||
| [109006930] SC_Coffin | 23 | 32 | 破坏出怪 |
|
||
| [221,1015] | 17 | 3/4/7/9 | 混合 |
|
||
| 其余 21 簇(773/775/8938+8939/779/…) | 81 | 各 1 簇 1 副本 | 副本专属机关 |
|
||
| **[1112] ElevatorSummon** | **3** | **53** | **电梯(presentation-only,EXE 硬编码)** |
|
||
|
||
- **电梯型结构全 PVF 恰好 3 张,无第四处**:
|
||
1. map **16408** `map/SuspiciousVillage/(2,5)start.map` — dungeon 53 maze 0 (2,5),4 位 + 1111/1113 + 1112→56716(纯 presentation_only)
|
||
2. map **400263** `map/SuspiciousVillage/M3786_(2,5)start.map` — dungeon 53 maze 1 (2,5),同上 + 多一个 scripted 对象 53858
|
||
3. map **76384** `map/Cataclysm/Northmyre/05_Town_of_doubt/3352_76384.map` — dungeon 53 maze 2 **(1,2)(layered spec)**,同上 + 多一个 scripted 对象 15336
|
||
- dungeon 53(疑惑之村)共 27 个候选:24 张是 mimicbox 宝箱怪图,3 张才是电梯。**maze 2 的 76384 不在已合并修复包的真实 PVF 测试覆盖(只测 16408/400263)内**,但现行识别纯按 PVF 语义(4 位 + 1111/1113 + 1112→56716 + 房内 special-monster actor),理论上自动覆盖;建议补一条 maze 2 的断言。
|
||
- 完整清单:`out/q5_elevator_candidates.tsv`(413 行,含每图对象行为分类)。
|
||
|
||
---
|
||
|
||
## 数据侧结论:能否一次性通用绑定?
|
||
|
||
1. **可以一次性枚举完,不存在"发现一个修一个"的长尾**:事件怪物位是普适结构(17,207 图/1,108 副本),但"位 + special 生成 monster"只收敛到 **413 图 / 28 个对象类簇**;真正的电梯机制收敛到 **3 图 / 1 个对象组合(1112→56716)**,全部位于 dungeon 53 三个 maze。全 PVF 没有第二部电梯机制。
|
||
2. **行为类簇极少且边界清晰**:
|
||
- **电梯类**(presentation-only 三件套 + 4 位 + summon→monster):3 图,EXE 硬编码行为,只能靠 PVF 语义识别 —— 现行方案方向正确,且已实质覆盖全部实例(含未测的 maze 2)。
|
||
- **破坏/陷阱出怪类**(木桶/棺材/碉堡/mimicbox 等 27 簇):对象带 `.act` 脚本或行为字段,是数据驱动的普通机制,**绝不能与电梯共用绑定**——若按"4 位 + special 生成 monster"裸绑定电梯逻辑会把 410 张普通图误判。
|
||
- **[destroy object] clear 类**:37 条件全部 count=1、36/37 精确匹配,形状高度统一,可以一次性通用绑定;注意 26/37 目标 ≤65535 不触发 u16 越界分支,1002/16072 是唯一无摆放例外。
|
||
3. **建议的绑定键**:按 `(特殊对象集合, presentation_only 判定, positions)` 三元组绑定,而不是按遭遇名单或 dungeon/map ID。对电梯而言该键在全 PVF 唯一({1111,1112,1113} + 4 位),天然不会误伤其余 27 簇。
|