Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
| Date uploaded | 2 weeks ago |
| Version | 3.7.0 |
| Download link | Sparkle_Twilight-SparkleBanditTweaks-3.7.0.zip |
| Downloads | 19 |
| Dependency string | Sparkle_Twilight-SparkleBanditTweaks-3.7.0 |
This mod requires the following mods to function
bbepis-BepInExPack
Unified BepInEx all-in-one modding pack - plugin framework, detour library
Preferred version: 5.4.2120README
BanditSmokeBombSpeed — 盗贼烟雾弹重做
技能总览(v3.7.0)
- 主要技能:迸射 100%×5(500%)→80%×5(400%),触发系数 0.5→0.75;轰击 330%→380%。
- 次要技能:锯齿匕首、锯齿小刀 未暴击改为流血,暴击仍出血。
- 辅助技能:烟雾弹 伤害降低、移速 +40%→+150% 起,每 0.3 秒衰减 15%、3 秒归零。
- 特殊攻击:熄灯 600%→800%,击杀不再重置冷却,命中清除目标流血与出血层数并按层数结算伤害;亡命徒 600%→800%,每层增幅 +10%→+5% 且作用于主要技能。
以上数值均可配置(见下文的配置文件说明)。
当前状态:v3.7.0 已编译完成,用 r2modman 的「+ → Install from file」装进
BepInEx\plugins\SparkleBanditTweaks.dll后直接启动游戏即可生效。
效果
烟雾弹(Shift)
盗贼 Shift 技能「Smoke Bomb / 烟雾弹」进入隐身后,同时改三件事:
1. 移动速度(阶梯衰减)
- 起始 +150% 移速(最终移速是基础值的 2.5 倍)
- 每 0.3 秒减 15 个百分点
- 正好 3 秒减完(10 档 × 0.3 秒),与技能持续时间一致
- 隐身中断立刻归零(比如隐身期间用了攻击技能提前现身)
| 时间 | 0.0s | 0.3s | 0.6s | 0.9s | 1.2s | 1.5s | 1.8s | 2.1s | 2.4s | 2.7s | 3.0s |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 加成 | +150% | +135% | +120% | +105% | +90% | +75% | +60% | +45% | +30% | +15% | 0% |
把配置里的 DecayMode 改成 Relative 会切成按比例衰减(每档 ×0.85),
那就是 +150% → +127.5% → +108% → …,前段掉得快、后段拖尾,但不会减到 0。
2. 伤害从每段 200% 降到 120%
改的是 EntityStates.Bandit2.StealthMode.blastAttackDamageCoefficient,
进隐身和出隐身各炸一次(OnEnter / OnExit 都调 FireSmokebomb),两段都会受影响,
所以技能说明里才写「造成 120% 伤害……然后再次造成 120% 伤害」。
眩晕不受影响 —— 眩晕来自 damageType 里的 DamageType.Stun1s(值 32),
和伤害高低无关,所以现在是「120% 伤害 + 眩晕」,和原版一样会晕人。
3. 技能说明文本
用 R2API 的 LanguageAPI 覆盖 BANDIT2_UTILITY_DESCRIPTION,中英文都改成:
眩晕。造成 120%的伤害,进入 隐身,然后再次造成 120%的伤害。在此期间获得持续衰减的 +150%移动速度。
<style=cIsDamage> / <style=cIsUtility> 是游戏原生的富文本标记,
进游戏后会自动显示成对应的伤害色 / 功能色,和原版技能的排版一致。
不喜欢可以把配置里的 OverrideSkillDescription 设成 false 恢复原版文案。
两个 R 技能(亡命徒 / 熄灯)
- 亡命徒与熄灯的基础倍率都从 600% → 800%
- 亡命徒的叠层增伤 每层 +10% → 每层 +5%
- 叠层增伤现在对 M1 也生效 —— 迸射(霰弹)和轰击(步枪)都吃到同样的每层加成
实际倍率 = DesperadoDamagePercent × (1 + StackDamageBonus × 层数)。
举例 5 层时:亡命徒 800% × 1.25 = 1000%,M1 则是在自己基础倍率上 ×1.25。
原版只有亡命徒自己读
BanditSkullbuff(FireSidearmSkullRevolver.ModifyBullet), M1 完全不读,所以第三条是新增行为。
倍率改动为什么是"缩放"而不是"改字段":damageCoefficient 是实例字段
(IL 里是 ldfld 不是 ldsfld),值由 EntityStateConfiguration 按技能填进去,
没法像烟雾弹那样直接改静态字段。所以改成在 ModifyBullet 之后按比例缩放 damage。
两个 R 技能的类(亡命徒 FireSidearmSkullRevolver、熄灯 FireSidearmResetRevolver)
都在自己的 ModifyBullet 第一条指令就 call base.ModifyBullet,
因此补丁打在共用的基类 BaseFireSidearmRevolverState.ModifyBullet 上就能一次覆盖两个。
技能说明会按配置值自动生成,例如:
屠戮者。使用左轮手枪进行射击,造成 800%的伤害。击败敌人可以 叠加效果,使亡命徒与主武器的伤害提高 5%。
熄灯(默认 R 技能)重做
- 移除原版的「击败敌人可以重置所有能力的冷却时间」
- 新增:命中时清掉目标身上所有的出血与流血,并按移除的层数一次性结算伤害
- 每层 出血 = 2000% 基础伤害(出血 = 盗贼 M2 暴击造成的效果)
- 每层 流血 = 240% 基础伤害(流血 = 三尖匕首造成的效果)
- 这次伤害
procCoefficient = 0,不会触发任何道具效果 - 举例:目标身上 5 层出血 + 3 层流血 →
5 × 2000% + 3 × 240% = 10720%基础伤害
「出血」在游戏里的 DoT 类型是
DotController.DotIndex.SuperBleed, 「流血」是DotController.DotIndex.Bleed,两者都挂在目标的DotController上。
移除击杀重置冷却的原理:熄灯的 FireSidearmResetRevolver.ModifyBullet 会给子弹打上
bulletAttack.damageType |= DamageType.ResetCooldownsOnKill(枚举值 4),
击杀时游戏读到这个标记就清冷却。所以在子弹发射前把这个位清掉,效果就整体失效了。
两个 M2(锯齿匕首 / 锯齿小刀)
保留原版的「暴击造成出血」,新增「未暴击造成流血」:
- 锯齿匕首(360%,突进挥砍)
- 锯齿小刀(240%,隐匿掷刀)
两个技能都不自己施加 debuff,只在伤害上打标记
DamageType.SuperBleedOnCrit(值 134217728),暴击与否由GlobalEventManager统一处理。 所以只要在命中回调里补一句「带这个标记但没暴击 → 施加 Bleed」, 原版的暴击出血完全不受影响。
两个 M1(迸射 / 轰击)
| 技能 | 原版 | 改后 | 触发系数 |
|---|---|---|---|
| 迸射(霰弹枪) | 5 × 100% | 5 × 80%(满命中 400%) | 0.75 |
| 轰击(步枪) | 330% | 380% | 不变 |
damageCoefficient/procCoefficient都是实例字段,由EntityStateConfiguration按技能填值(IL 里看不到数字,语言文件写着 5x100% / 330%), 所以沿用亡命徒那套:在ModifyBullet之后按比例缩放bulletAttack.damage, 触发系数直接覆盖bulletAttack.procCoefficient。 霰弹的FireBullet按bulletCount循环调Fire(),整个过程是同一个BulletAttack对象,改一次对 5 颗弹丸都有效。
变更历史
-
3.7.0 两个 M1 调整:迸射每段 100% → 80% 且触发系数改为 0.75;轰击 330% → 380%(系数不变)。 新增
[Primary]配置段,说明文本按配置值生成。 -
3.6.1 调整两个 M2 的技能说明文案(「造成 N%的伤害并流血。暴击则造成出血。」)。
-
3.6.0 两个 M2 保留暴击出血的同时,未暴击改为造成流血(三尖匕首那种)。 新增
[BanditSecondary]配置段。 -
3.5.0 重做熄灯:移除「击杀重置冷却」,改为命中时清除目标所有出血 / 流血并按层数结算伤害 (出血每层 2000%、流血每层 240%,无触发系数);改用 MMHOOK 挂
BulletAttack.Fire与GlobalEventManager.OnHitEnemy,不再依赖 Harmony 的PatchAll()。 -
3.4.0 修掉 3.3.0 的致命问题:
PatchAll()一个补丁都没挂上(日志里本模组的补丁记录为 0 条), 改成显式harmony.Patch()并加挂载/生效日志;顺带按用户要求把熄灯也一起改成 800%。 -
3.3.0 新增亡命徒改动:倍率 600% → 800%、叠层 10% → 5%、叠层增伤扩展到 M1;技能文本按配置动态生成。
-
3.2.0 移速降到 +150% 起每档 −15 个百分点;伤害提到每段 120%;技能文本同步更新。
-
3.1.0 移除 v3.0.0 加的「隐身期间必定暴击」效果;新增技能说明文本覆盖。
-
3.0.0 移速改为 +200% 起每档 −20 个百分点;伤害 200% → 50%;加入必暴效果(已在 3.1.0 移除)。
-
2.0.0 首版衰减移速(+300% 起,每档 −30 个百分点)。
原理
- 盗贼进入隐身走
EntityStates.Bandit2.StealthMode,OnEnter里(服务端)给角色挂上RoR2Content.Buffs.Cloak和RoR2Content.Buffs.CloakSpeed。 - 移速:实际计算在
CharacterBody.RecalculateStats()里,带CloakSpeed时固定+0.4f。 本模组通过 R2API 的RecalculateStatsAPI.GetStatCoefficients补上当前加成 - 0.4的差额。 属性默认只在数据变脏时才重算,所以插件在Update()里盯着档位,跳档就调一次body.RecalculateStats(),玩家才看得到移速一档一档往下降。 - 伤害:这个
EntityState的静态字段没有静态构造函数,值由 EntityStateConfiguration 在关卡加载后才填入,所以每帧写一次比启动时写一次稳。 - 文本:
LanguageAPI.Add(token, text, langid),中英文都塞同一句中文, 这样不管游戏选什么语言都能看到对应描述。 - 两个 R 技能:叠层 buff 是
RoR2Content.Buffs.BanditSkull,由GlobalEventManager.OnCharacterDeath授予、由FireSidearmSkullRevolver.ModifyBullet消费(原版damage *= 1 + 0.1 × 层数)。 基础倍率在BaseFireSidearmRevolverState.damageCoefficient(实例字段)里, 开火链路是OnEnter(算 damage)→ModifyBullet→Fire()。 两个 M1 都继承Bandit2FirePrimaryBase且各自调用base.ModifyBullet, 因此补丁打在基类上就能同时覆盖迸射与轰击。
配置项
首次启动生成于 BepInEx\config\com.yourname.banditsmokebombspeed.cfg:
[Primary]
ShotgunDamagePercent = 80 ; 迸射每段伤害(原版 100),5 颗共 400%
VanillaShotgunDamagePercent = 100 ; 原版每段,仅用于换算比例
ShotgunProcCoefficient = 0.75 ; 迸射触发系数
RifleDamagePercent = 380 ; 轰击伤害(原版 330)
VanillaRifleDamagePercent = 330 ; 原版值,仅用于换算比例
OverridePrimaryDescription = true
[BanditSecondary]
BleedOnNonCrit = true ; 两个 M2 未暴击时造成流血
BleedDuration = 3 ; 流血持续秒数(3 = 与原版三尖匕首一致)
BleedDamageMultiplier = 1 ; 流血伤害倍率
ScaleByProcCoefficient = true ; 持续时间是否乘以技能触发系数
RequireBanditAttacker = true ; 只处理盗贼打出的命中
OverrideSecondaryDescription = true
[LightsOut]
RemoveKillResetCooldown = true ; 移除「击败敌人重置所有冷却」
DetonateBleedStacks = true ; 开启「清除出血/流血并按层数结算伤害」
HemorrhageDamagePercent = 2000 ; 每层出血的伤害百分比
BleedDamagePercent = 240 ; 每层流血的伤害百分比
RemoveStacksAfterDetonate = true ; 结算后是否真的移除层数(false = 层数保留白嫖伤害)
StrictSourceCheck = true ; 是否额外用 damageType 标记确认命中来自熄灯
OverrideLightsOutDescription = true
[Desperado]
DesperadoDamagePercent = 800 ; 亡命徒基础倍率,800 = 800%(原版 600)
StackDamageBonus = 0.05 ; 每层叠层加成,0.05 = +5%(原版 0.1 = +10%)
ApplyStackToPrimary = true ; 叠层增伤是否也作用于 M1(迸射 / 轰击)
OverrideDesperadoDescription = true
[Smoke Bomb]
InitialBonus = 1.5 ; 起始加成,1.5 = +150%
DecayInterval = 0.3 ; 多少秒衰减一档
DecayPerTick = 0.15 ; 每档减少多少,0.15 = 减 15 个百分点
Duration = 3 ; 加成总时长(秒),到点归零
DecayMode = Flat ; Flat = 按百分点减(默认);Relative = 按比例乘
OnlyAffectBandit = true
[Damage]
SmokeBombDamageCoefficient = 1.2 ; 每段伤害系数,1.2 = 120%(原版 2.0);0 = 无伤害但保留眩晕
[Description]
OverrideSkillDescription = true ; 是否覆盖技能说明文本
DecayPerTick 的含义随 DecayMode 变化:Flat 下是"减多少加成值"(0.15 = 减 15 个百分点),
Relative 下是"降低多少比例"(0.15 = 每档 ×0.85)。
改完重启游戏即可,不用重新编译。想完全还原原版就把 InitialBonus 设成 0.4、
SmokeBombDamageCoefficient 设成 2、OverrideSkillDescription 设成 false。
⚠️ 改了数值没生效? BepInEx 的配置文件一旦生成就不会被新默认值覆盖, 一直沿用文件里写死的值。所以光改源码默认值不够,要直接改
BepInEx\config\com.yourname.banditsmokebombspeed.cfg, 或者把这个文件删掉让它重新生成。
怎么确认改动真的生效了
打开 BepInEx\LogOutput.log,搜 BanditSmokeBombSpeed,应该能看到这几类日志:
| 日志 | 含义 |
|---|---|
补丁已挂载:BaseFireSidearmRevolverState.ModifyBullet ← RevolverPostfix() |
倍率补丁挂上了(共 3 条) |
左轮倍率补丁已生效:600% → 800% |
第一次开左轮枪时触发,说明真的跑到了 |
亡命徒叠层补丁已生效:每层 +10% → +5% |
亡命徒专属那条也跑到了 |
M1 叠层补丁已生效:当前 N 层,加成 ×1.25 |
M1 那条也跑到了,并显示当前层数 |
钩子已挂载:BulletAttack.Fire / GlobalEventManager.OnHitEnemy |
熄灯改动的两条 MMHOOK 钩子挂上了 |
熄灯:damageTypeCombined 是 ulong,标记位可用 |
命中来源判定用的是 damageType 标记 + 时间窗双保险 |
熄灯:已移除「击败敌人重置冷却」 |
第一次开熄灯时触发,标记位已清掉 |
熄灯引爆已生效:出血 N 层 × 2000% + 流血 M 层 × 240% = X 伤害 |
引爆逻辑真的跑到了 |
钩子已挂载:GlobalEventManager.OnHitEnemy(M2 未暴击流血) |
M2 流血的钩子挂上了 |
M2 未暴击流血已生效:3 秒 ×1 |
第一次用 M2 打非暴击时触发 |
补丁已挂载:Bandit2FirePrimaryBase.ModifyBullet ← PrimaryPostfix() |
M1 倍率/系数补丁挂上了 |
M1 迸射补丁已生效:100% → 80%(×5 颗),触发系数 0.75 |
第一次开霰弹枪时触发 |
M1 轰击补丁已生效:330% → 380%(触发系数不变) |
第一次开步枪时触发 |
只有"已挂载"没有"已生效"说明补丁挂上了但那条代码路径没走到;
连"已挂载"都没有说明 Harmony 那步就失败了。RoR2BepInExPack 也会把每个模组的补丁
打成 Harmony ... added by XXX.dll 的 Debug 日志,可以用来交叉核对。
编译
需要 .NET SDK 6/7/8(或 Visual Studio 2022):
dotnet build -c Release
会自动把 DLL 复制到 r2modman 的 plugins 目录。不想自动复制加 -p:DeployToProfile=false。
游戏或 r2modman 装在别处就改 BanditSmokeBombSpeed.csproj 里的
<RoR2GameDir> 和 <R2ModManProfileDir>。
发布成 Thunderstore 模组包
dist\BanditSmokeBombSpeed.zip 已是标准结构(manifest.json + plugins\*.dll),
可直接用 r2modman 的「Import local mod」导入。
已知限制
- 依赖 R2API(本机 R2API 5.3.0,兼容),用到了 RecalculateStats 与 Language 两个子模块。
- 联机时所有玩家都要装,否则各自看到的移速不一致。
- 隐身计时用
Time.time,游戏暂停时不会继续衰减。 - 不要用
Harmony().PatchAll()的特性自动发现:本机实测它一个补丁都没挂上 (日志里本模组的补丁记录为 0 条,而其他模组都有),必须显式harmony.Patch(target, postfix)。 - 亡命徒的技能文本是按配置值动态生成的,改配置重启后文本自动同步。
但烟雾弹的文本是源码里写死的字符串 —— 调了
InitialBonus的话要同步改SmokeBombSpeedPlugin.cs里的SkillDescription再重新编译。 - 依赖 Harmony(BepInEx 自带
0Harmony),亡命徒的两处改动都是 Postfix 补丁。 - 熄灯改动依赖 MMHOOK(
RiskofThunder-HookGenPatcher生成的MMHOOK_RoR2.dll), 编译时需要能引用到它;运行时它由 HookGenPatcher 自动加载,不用手动加依赖。 - 熄灯的"命中来源判定"是「开火后 0.25 秒内 + 同一个攻击者」(可选再加 damageType 标记)。
如果游戏里引爆没触发,先把
StrictSourceCheck设成false再看日志。