
大猩猩宝箱模组
Valheim中箱子的便捷模组:更大的堆叠(1000),从附近的箱子制作,自动堆叠到所有箱子(按J键),以及收藏物品栏物品(Alt+点击)。
查看大图Valheim 的箱子体验优化,分为四部分:
- 从箱子中制作。 使用周围箱子内的物品进行制作、升级和建造,无需先将物品搬运到你的物品栏中。
- 超大箱子堆叠。 一个箱子槽位可容纳远超原版上限的数量,默认 1000,因此装满木头的箱子只占一个槽位而非二十个。你自己的物品栏仍保持原版上限。
- 快速堆叠。 按 J 键将物品栏中匹配的物品推入范围内的箱子。J 键在 Valheim 中是空闲的:V 是自动拾取,G 打开快捷栏径向菜单。
- 收藏。 用 Alt + 左键 标记一个堆叠,自动移动会将其忽略,包括上述的快速堆叠和箱子自身的堆叠按钮。
客户端和专用服务器均可运行。
构建所针对的游戏版本
| 项目 | 值 |
|---|---|
| 游戏版本 | 1.0.7 |
| Steam 构建 | 25185596 |
| 引擎 | Unity 6000.0.75f1,Mono 后端 |
| 游戏代码 | valheim_Data/Managed/assembly_valheim.dll |
由于后端是 Mono 而非 IL2CPP,常规的模组路径仍然适用:BepInEx 5 加 Harmony,在内存中打补丁。不修改任何游戏文件。
安装
- 为 Valheim 安装 BepInEx 5,即
denikson-BepInExPack_Valheim包。启动游戏一次以创建其文件夹。 - 将
GorilaChestMod.dll复制到Valheim/BepInEx/plugins/GorilaChestMod/,或将-nexus.zip发布包解压到游戏文件夹上。 - 启动游戏。
BepInEx/LogOutput.log应包含一行GorilaChestMod 2.4.0 loaded。
使用 r2modman 或 Thunderstore Mod Manager 时,使用 Import local mod 并选择 -thunderstore.zip 发布包。不要将模组管理器与手动安装在游戏根目录的 BepInEx 混用,这是模组重复加载或完全不加载的经典原因。
在专用服务器上
[url=https://github.com/trentinidev/GorilaChestMod#on-a-dedicated-server][/url]
面向服务器运营者的完整分步指南(Windows、Linux 和租用面板):docs/server-install.md。
简要版本与上述相同,放入服务器的 BepInEx/plugins,并且每位玩家也都需要安装。服务器端存在有两个原因:
- 将箱子加载到内存的服务器决定其堆叠可以有多大。原版服务器会将超大堆叠钳制回原版上限,并在下次写入该箱子时销毁多余部分。
- 服务器在每位客户端连接时将其箱子堆叠设置发送给客户端,因此整个会话对上限达成一致。
从箱子中制作和快速堆叠完全在玩家自己的机器上决定,因此这两项在原版服务器上仍可正常工作。
配置
BepInEx/config/dev.trentini.gorilachestmod.cfg 在首次启动时写入,可在游戏关闭时编辑。
| 节 | 选项 | 默认值 | 作用 |
|---|---|---|---|
| Craft from chests | Enabled |
true |
在制作、升级和建造时计入附近的箱子。 |
| Craft from chests | Range |
20 |
半径,单位为米。快速堆叠使用相同半径。 |
| Craft from chests | UseForBuilding |
true |
也从箱子中支付锤子、锄头和耕耘机的费用。 |
| Craft from chests | IncludeVehicleContainers |
true |
包含推车和船上的容器。 |
| Chest stacks | Enabled |
true |
允许箱子内的超大堆叠。 |
| Chest stacks | ChestStackSize |
1000 |
一个箱子槽位可容纳的数量,最高 10000。服务器的值优先。 |
| Chest stacks | ShrinkStackText |
true |
数字变长时保持槽位标签可读,1000 显示为 1k。 |
| Quick stack | Enabled |
true |
启用快速堆叠热键。 |
| Quick stack | SkipHotbar |
true |
不动快捷栏那一行。 |
| Quick stack | Hotkey |
J |
快速堆叠的热键,物品栏打开或关闭时均可。 |
| Quick stack | HotkeyNeedsInventory |
false |
要求物品栏打开才能使用热键。 |
| Favorites | Enabled |
true |
允许将堆叠标记为不可触碰。 |
| Favorites | Modifier |
LeftAlt |
按住此键并左键点击堆叠以标记。左右两侧的键均可。 |
| Favorites | ShowMarker |
true |
在标记的槽位上绘制一颗星。 |
| Favorites | Announce |
true |
标记或取消标记堆叠时打印一行提示。 |
| Debug | Verbose |
false |
记录每次取出、移动和已打补丁的调用。 |
当你连接到安装了该模组的服务器时,只要保持连接,该服务器在 Chest stacks 下的 Enabled 和 ChestStackSize 就会替换你的本地值。其他所有设置保持个人化。
哪些箱子会被计入
只有当箱子通过与你尝试打开它时游戏所应用的相同规则时,才会被使用:
- 它位于配置的半径内;
- 隐私为
Public,或为Private且你是该部件的创建者,因此团队箱子会像原版一样被排除在外; - 如果箱子检查守卫石,你需要拥有该守护区域的访问权限;
- 没有其他人打开它,正被其他玩家使用的箱子会被跳过。
在取走任何东西之前,模组通过 ZNetView.ClaimOwnership 声明箱子的网络所有权,这是将物品栏写回 ZDO 的授权方式。这与游戏用于“全部拿走”的机制相同。
工作原理
从箱子中制作
[url=https://github.com/trentinidev/GorilaChestMod#craft-from-chests][/url]
游戏方法直接从 m_inventory 字段读取玩家物品栏,没有任何扩展点。模组不会向你的背包注入虚假物品,而是使用转译器仅重写这些方法内的物品栏调用。实例调用已经将 this 作为其第一个堆叠参数,因此第一个参数为 Inventory 的静态方法可直接替换,而方法体的其余部分保持不变。
| 游戏方法 | 替换的调用 | 原因 |
|---|---|---|
Player.HaveRequirementItems |
CountItems |
解锁配方和制作按钮 |
Player.GetFirstRequiredItem |
CountItems、GetItem |
单一材料的配方,如蜜酒和盛宴 |
Player.ConsumeResources |
RemoveItem |
支付制作和放置部件的费用 |
Player.HaveRequirements(Piece) |
HaveItem、CountItems |
解锁建筑部件 |
InventoryGui.DoCrafting |
RemoveItem |
支付单一材料 |
InventoryGui.SetupRequirement |
CountItems |
UI 中的拥有/需要数量 |
Container.Awake 注册每个生成的箱子,因此永远不需要 FindObjectsOfType 扫描,而 Player.UpdatePlacement 和 Hud.SetupPieceInfo 标记建造上下文,以便可以遵守 UseForBuilding。
超大箱子堆叠
[url=https://github.com/trentinidev/GorilaChestMod#oversized-chest-stacks][/url]
堆叠上限是普通字段 ItemData.m_shared.m_maxStackSize,在 Inventory 和 InventoryGrid 内的少数地方被读取。转译器将每次字段读取转换为一个调用,该调用还接收正在操作的物品栏,因此同一物品类型在箱子中返回 1000,在背包中返回原版的 50。
之后降低上限永远不会销毁任何东西:当保存的箱子被重建时,从磁盘读取的堆叠会为该单个物品提高上限,因此在较大设置下装满的箱子会保留其内容。它只是停止增长。方法列表在启动时从游戏自身的 IL 中发现,而非硬编码,并写入日志。
这一单一更改也涵盖了保存和加载:从保存的字节重建物品栏的 Inventory.AddItem 重载会按同一字段进行钳制,这就是为什么原版服务器或原版客户端否则会裁掉多余部分。
三道防护防止超大堆叠泄漏出箱子:
Inventory.AddItem(ItemData)将对于目标来说过大的堆叠拆分到多个槽位,因此从箱子中按住 Shift 点击 1000 个木头会给你二十个原版堆叠。- 目标槽位的
Inventory.AddItem只移动原版大小的部分并将该移动报告为部分完成,因此其余部分留在箱子中。 ItemDrop.DropItem将超大堆叠拆分为多次掉落,因此被摧毁的箱子会散落普通堆叠而非一个不可能的巨大堆。
快速堆叠
[url=https://github.com/trentinidev/GorilaChestMod#quick-stack][/url]
热键在 InventoryGui.Update 中读取,并在物品栏关闭时工作,因此你可以站在箱子旁边按下它。当菜单、控制台、聊天或文本字段获得焦点时,以及玩家死亡时,它会暂停。刻意没有按钮:曾经有一个按钮位于物品栏旁边,却总是落在其他面板前面。物品只会移入已持有该物品的箱子,已装备和任务物品会被跳过,除非你另有说明,否则快捷栏会被跳过。
收藏
[url=https://github.com/trentinidev/GorilaChestMod#favorites][/url]
标记是物品自身自定义数据中的单个条目,即游戏已经与耐久度和品质一起序列化的字典。这无需任何簿记即带来三个好处:它随物品保存和加载,ItemData.Clone 会复制它,因此拆分堆叠会保留两半的标记,并且当你手动移动它时它会随堆叠一起移动。合并是游戏会丢失标记的唯一情况,因此目标槽位的 Inventory.AddItem 在任一侧有标记时会将其携带过去。
点击在 InventoryGui.OnSelectedItem 中被捕获:按住修饰键时点击会切换标记并被吞掉,否则原版照常运行。星星在启动时一次性绘制到纹理中,因为游戏 UI 没有星星可借用,并且同一精灵会被每个槽位复用。
箱子自身的堆叠按钮也会被遵守。它已经通过 Humanoid.IsItemEquiped 拒绝移动你已装备的物品,因此转译器将该调用指向一个对已标记堆叠也回答“是”的检查。
服务器端
[url=https://github.com/trentinidev/GorilaChestMod#server-side][/url]
该插件在 valheim_server.exe 以及 valheim.exe 中加载。在服务器上没有本地玩家,因此从箱子中制作和快速堆叠根本不会触发,而堆叠上限补丁会在服务器接触的每个箱子上发挥作用。
配置同步使用游戏自身网络层的两个路由 RPC:客户端在连接后请求一次,服务器以其箱子堆叠设置回应,服务器永远不会从客户端获取这些值。
已知限制
- 移除模组会留下超大堆叠。 原版在加载箱子时会将堆叠钳制回其正常上限,多余部分会消失。在卸载前清空你的箱子,或降低
ChestStackSize并让箱子稳定下来。没有安装模组的玩家打开装有超大堆叠的箱子也是如此。 - 在 Valheim 中修理不消耗材料,因此那里无需处理。
- 熔炉、窑和其他通过直接交互接收矿石或木材的站点不会从箱子中供给。制作、升级和建造则会。
- 快速堆叠按钮由鼠标驱动,目前没有手柄绑定。
- 其他玩家当时打开的箱子会被跳过,直到他们关闭它。
还没有人评论,去客户端里说两句吧。
评论在新手盒子客户端中发表,这里同步展示。