禁用战斗武器切换

禁用战斗武器切换

锁定战斗中的武器配置槽位。你将用所带装备作战。任务和脚本装备不受影响,仅阻止从打开菜单手动进行的更改。

===============================================================================
战斗时禁止切换武器
===============================================================================

你的装备配置是你在开火之前做出的决定,而不是在交火之中。


//////////////////////////////////////////////////////////////////////////////////////////////////
版本 1.1 更新内容
//////////////////////////////////////////////////////////////////////////////////////////////////

1.1 版本新增了地面拾取切换功能。

最初版本存在一个明显的死局。锁定装备配置后,清空你携带的所有枪支弹药,战斗就会变得无法胜利,而这并非源于你做出的任何有趣决策。那不是什么紧张感,伙计,那只是站在原地听着自己手中武器发出空洞的击发声。

所以现在地面拾取开放了。在交火中弹药完全耗尽时,从地上捡起武器会直接装备到你手中。被替换的空枪会回到你的背包中。你不能浏览选择,不能计划,只能拿起地上现有的东西,然后继续行动。

1.0 版本的所有内容保持不变。如果你喜欢原有的装备锁定机制,它没有任何改动。


//////////////////////////////////////////////////////////////////////////////////////////////////
功能说明
//////////////////////////////////////////////////////////////////////////////////////////////////

一旦进入战斗,三个武器槽位将被锁定。在战斗结束前,你无法打开背包将不同的武器换入槽位。尝试这样做会在菜单中显示通知,并且装备操作会被拒绝。

其他一切功能都和以前一样:

* 在已装备武器之间切换不受影响。1、2、3号槽位,
滚轮、快捷切换,一切正常。此模组不会以任何方式减慢或
限制你的实际枪战操作。

* 手榴弹、消耗品和治疗物品不受影响。

* 义体、快速破解和服装不受影响。

* 潜行不算战斗。只要你未被发现,就可以自由更换装备配置。被发现才会锁定。

* 地面武器仍然可以使用,但仅限弹药完全耗尽时。见下文。


//////////////////////////////////////////////////////////////////////////////////////////////////
游戏设计意图
//////////////////////////////////////////////////////////////////////////////////////////////////

《赛博朋克2077》允许你在交火中暂停游戏,打开背包,重新构建装备配置来应对刚刚遇到的情况。碰到一个全副武装的军用科技打手而你手里只有霰弹枪?把你一直带着的技术狙击枪换上。敌人抵抗物理伤害?换成热能武器。这招有效,而且很快,但它悄无声息地消除了遭遇战设计中的大部分紧张感。

这也让准备工作变得毫无意义。如果你能在战斗中通过背包界面解决任何问题,就没有理由在事前考虑装备配置,也没有理由让游戏只限制你携带三把武器了。

这个模组恢复了这一决策的代价。

* 侦察变得重要。在交火前标记敌人现在能给你提供可操作的信息,你可以在还有能力时选择如何应对。

* 三个武器槽位有了真正的机会成本。带上霰弹枪意味着不带狙击枪。这就是装备配置的意义。

* 战斗可能会以你必须靠操作化解的方式出错。带着错误的工具被抓住,是需要用移动、掩体、手榴弹和快速破解来解决的局面,而不是打开菜单。

* 潜行会得到灵活性的回报。保持隐蔽能让你有更多选择。这是一个有意义的优势,而不仅仅是一个属性检验。

这个模组刻意保持精简。它不涉及伤害数值、敌人生命值、武器操控或其他任何内容。它只移除了一个特定的逃生通道,其余部分完全保留。它可以很好地与战斗大修和难度模组搭配使用,但它本身不是这类模组,单独使用也完全没问题。


//////////////////////////////////////////////////////////////////////////////////////////////////
弹药耗尽
//////////////////////////////////////////////////////////////////////////////////////////////////

地面拾取切换只在手中武器弹药完全耗尽时触发,弹匣和备用弹药都为零,且三个武器槽位都已占满。在此状态下拿起一把武器,它会直接装入你当时手持的槽位。

这个条件起着实际作用。没有它,这个功能每次你走过一把枪时都会变成一次免费的装备配置重置,而这正是本模组存在意义所要封堵的逃生通道。有了它,这个切换是最后的手段而非战术。在战斗中还有弹药时搜刮尸体不会触发任何效果。

被替换的武器会回到你的背包中,而不是掉在地上。这是有意设计的。将独特和传说武器掉落到世界中可能不可靠,在交火中因为物理引擎问题丢失一把独一无二的枪,不值得为任何人提供这种代价。

近战武器没有弹药类型,永远不会被视为弹药耗尽,所以刀剑流不会触发这个功能。剧情武器也永远不会被替换掉,这保证了脚本化过场的安全。

在战斗之外,这个功能完全禁用,所以普通的搜刮行为照常进行。如果你想要更宽松的触发条件,这两个条件都可以通过一行代码修改。


//////////////////////////////////////////////////////////////////////////////////////////////////
工作原理
//////////////////////////////////////////////////////////////////////////////////////////////////

该模组挂钩游戏的装备系统,并拦截武器装备和卸下请求。只有在以下三个条件全部满足时,请求才会被拒绝:

1. 物品的装备区域是武器槽位。
2. 玩家状态机报告玩家处于战斗中。
3. 当前有菜单打开。

第三个条件是让模组不会破坏你游戏的关键。任务、过场动画和脚本化剧情经常会强制装备武器,比如强尼附身、故事剧情递给你一把枪。这些请求并非来自打开的菜单,所以它们会被放行。只有你手动进行的更改才会被阻止。

拒绝通知使用的是游戏自带的菜单内弹窗系统,和你在战斗中尝试出售技能点时出现的是同一个,所以它符合游戏界面风格,并支持游戏所有语言版本。

地面拾取切换的工作原理不同,原因值得解释一下,因为它塑造了这个功能的一个粗糙边缘。

从地上捡起武器根本不会经过装备系统。当你的槽位已满时,游戏只会把物品放进你的背包,所以那里没有东西可以挂钩。因此,切换功能改为挂钩物品进入背包的时刻,这个时刻适用于物品进入的每一条途径:地面拾取、搜刮尸体、商人购买、制作、任务奖励。

这种广泛性是问题所在。在那一时刻没有明确的信号能表明物品来自地面还是尸体,所以弹药耗尽要求就承担了鉴别的工作。它恰好描述了该功能存在所针对的情况,并让误报率低到可以接受,但这是一种代理判断而非精确测试。如果在战斗中,你手持完全空枪且三个槽位已满,任何方式进入你背包的武器都会触发切换。实际上,这几乎总是你从地上捡枪。偶尔也可能是在最糟糕的时刻搜刮了尸体。

一旦这些条件满足,模组会排队一个标准的装备请求,标记为当前激活的槽位,剩下的工作由游戏自己的装备流程处理。


//////////////////////////////////////////////////////////////////////////////////////////////////
要求
//////////////////////////////////////////////////////////////////////////////////////////////////

《赛博朋克2077》2.3或更高版本 ..... 见下方版本说明。

redscript ....................... 必需。

不需要其他任何东西。不需要 Cyber Engine Tweaks、TweakXL、ArchiveXL、Codeware或 Mod Settings。三个脚本文件,仅此而已。

关于版本要求的说明:2.3 是该模组挂钩验证通过的补丁版本,不代表它不能工作在更早的版本上。它挂钩的函数很可能在更早的版本中也没有变化。如果你在旧版本上,它要么正常工作,要么在启动时编译出错明确失败,无论如何都不会损坏任何东西。


//////////////////////////////////////////////////////////////////////////////////////////////////
兼容性
//////////////////////////////////////////////////////////////////////////////////////////////////

存档安全。该模组不存储持久数据,不向游戏类添加字段,也不创建任何 TweakDB 记录。你可以在游戏过程中的任何时候添加或移除它。移除它不会在你的存档中留下任何痕迹。

没有归档文件,所以不会与纹理、网格或模型模组冲突。

使用包装而非替换。每个挂钩都是 @wrapMethod,它会与其他模组链式工作而不是覆盖它们。它不会对任何原版函数使用 @replaceMethod。这意味着它应该与触及相同装备功能的其他模组共存,包括背包大修、Equipment-EX、All Cyberware-EX 和 Always First Equip。

已知的交互点:

* 自动拾取和真空拾取模组。任何未经你同意就将物品吸入背包的模组与地面切换共享挂钩。如果这样的模组在你战斗中手持空枪且槽位已满时吸走一把武器,会触发你不想要的切换。如果你运行这类模组并觉得有干扰,删除地面切换文件即可。

* 弹药模组。任何改变备用弹药计数或存储方式的模组都会直接影响弹药耗尽检查。保留隐藏弹药的模组可能会阻止切换触发;让弹药耗尽更常见(比如弹药限制器)的模组会让切换更频繁触发。第二种情况可以说正是模组的本意。

* 其他改变菜单通知的模组。可选的定制文本文件包装了通知队列。如果另一个模组直接替换了同一个函数,两者只能胜其一。基础模组没有这个问题,如果遇到冲突,删除可选文件即可。

* 添加装备区域的模组。只有标准武器区域会被锁定。其他模组添加的定制武器槽位不会被覆盖,除非你自己把它们加入检查列表(见配置)。

* 允许不打开菜单装备武器的模组。如果某个模组允许你通过 HUD 或环形菜单更换装备配置而无需打开菜单,该路径会绕过上述第三个条件且不会被阻止。目前没有已知的此类模组,但这是这种方法的诚实局限性。


//////////////////////////////////////////////////////////////////////////////////////////////////
安装方法
//////////////////////////////////////////////////////////////////////////////////////////////////

解压到你的《赛博朋克2077》安装目录。你最终应该得到:

Cyberpunk 2077/r6/scripts/NoCombatWeaponSwap/NoCombatWeaponSwap.reds
Cyberpunk 2077/r6/scripts/NoCombatWeaponSwap/NoCombatWeaponSwap_GroundSwap.reds
Cyberpunk 2077/r6/scripts/NoCombatWeaponSwap/NoCombatWeaponSwap_CustomText.reds

Vortex 和 Mod Organizer 2 可以直接安装该压缩包。

卸载:删除 r6/scripts/NoCombatWeaponSwap 文件夹。

从 1.0 升级:先删除旧文件夹,然后全新安装。1.1 重命名了一个配置函数,残留旧文件会导致编译失败。


//////////////////////////////////////////////////////////////////////////////////////////////////
配置
//////////////////////////////////////////////////////////////////////////////////////////////////

没有设置菜单。每个选项都是一行代码修改,每个功能都是独立文件,所以删除文件即可干净地移除该功能。

更改或还原弹窗文本。编辑 NoCombatWeaponSwap.reds 中的 NCWS_CustomMessage() 来重新措辞通知。返回空字符串,或直接删除整个 NoCombatWeaponSwap_CustomText.reds 文件,即可使用游戏自带的本地化战斗信息。

同时锁定重型武器槽位。在 NoCombatWeaponSwap.reds 中,将 gamedataEquipmentArea.WeaponHeavy 添加到 NCWS_IsWeaponArea() 中。

放宽地面拾取切换。在 NoCombatWeaponSwap_GroundSwap.reds 中,将 NCWS_RequireEmptyWeapon() 设置为 false,允许任何武器拾取触发切换,而不仅限于弹药耗尽时;或将 NCWS_SwapCombatOnly() 设置为 false,使其在战斗外也生效。请注意,关闭第一个条件会大大削弱本模组的核心意义。

移除地面拾取切换。删除 NoCombatWeaponSwap_GroundSwap.reds。装备锁定将表现得和 1.0 版本完全相同。


//////////////////////////////////////////////////////////////////////////////////////////////////
鸣谢
//////////////////////////////////////////////////////////////////////////////////////////////////

地面拾取切换的想法来自 BALLSACKVLAD 的 DROP CURRENT WEAPON, CET, IMMERSIVE HOTKEY DROP AUTO SWAP 模组。我从他的模组中第一次看到了这个问题的恰当表述:满装备配置不应该意味着你无法从地上拿起武器。感谢他的原创和允许衍生作品。

这不是移植,两者差异大到值得明确说明,以免反映到他的作品上:

* 他的模组是使用 Lua 编写的 Cyber Engine Tweaks 模组。这是 redscript,不需要 CET。

* 他的模组通过每帧轮询循环监测拾取动作。这是直接挂钩背包添加事件,没有轮询,没有时间窗口。

* 他的模组在任何符合条件的武器拾取时触发。这仅在手持武器完全耗尽弹药且三个槽位已满时触发。

* 他的模组把你旧武器丢到地上,这正是模组名称所指的行为。这会把旧武器还回你的背包。

同样的核心思路,不同的实现和不同的感受。这个模组的任何缺陷都是我的,不是他的。如果你想要丢到地上的行为、快捷键或支持战斗外触发的版本,去用他的模组,它把那个工作做得很好,而且有意地用了不同的方式。