About EasyWeapon
From Thunderstore[AI-generated] Client-only weapon tweaks: faster reload (crossbows/grappling hook), reloads that survive run/jump/dodge, and a tuned chain lightning (weapon proc chance + ChainLightningRed effect parameters).
EasyWeapon
> AI 生成声明:本模组由 AI 智能体(WorkBuddy)在用户的明确需求与逐项验收下编写; > 功能设计、真机测试与发布决定均由用户主导。
武器手感。 纯客户端模组。
功能(3 项)
| # | 功能 | 默认 | 配置节 | | --- | --- | --- | --- | | 1 | 装填时间倍率 —— 弩 / 钩索 | 0.5(= 装填时间减半) | 1 - Reload Speed | | 2 | 装填不被打断 —— 奔跑 / 跳跃 / 闪避翻滚时不清掉装填 | 三项都开 | 2 - Uninterruptible Reload | | 3 | 连锁闪电强化 —— 武器触发率统一 + ChainLightningRed 特效参数 | 见 3 - Chain Lightning 节 | 3 - Chain Lightning |
这两个需求在游戏里其实是同一套机制
反汇编确认(游戏 1.0.14,assembly_valheim.dll):
| 物品 | 本地化键 | m_requiresReload | m_reloadTime | 装填动画 | 技能 | |---|---|---|---|---|---| | 钩索 | $item_graplinghook ⚠️ 游戏里就少一个 p | true | 2.0 s | reload_crossbow | 无(不吃技能) | | 弩(Arbalest / Ripper×4 / Gold×3 及其变体,共 8 把) | $item_crossbow_* | true | 3.5 s | reload_crossbow | Crossbows | | 闪电法杖(默认不动) | $item_staff_lightning | true | 1.9 s | recharge_lightningstaff | ElementalMagic |
两者共用 ItemData.GetWeaponLoadingTime():
if (!m_requiresReload) return 1f; ← 该分支必须绕开
float skill = Player.m_localPlayer.GetSkillFactor(m_skillType);
return Mathf.Lerp(m_reloadTime, m_reloadTime * 0.5f, skill); ← 弩技能满级本来就已减半
所以「弩减半」和「钩索减半」是一个挂载点,不需要写两套。
配置
BepInEx/config/easyweapon.client.only.cfg
1 - Reload Speed
| 键 | 默认 | 说明 | | --- | --- | --- | | Enabled | true | 总开关 | | ReloadTimeMultiplier | 0.5 | 时间倍率:0.5 = 装填时间减半(更快)。⚠️ 填 2 是变慢 | | Crossbows | true | 弩 | | GrapplingHook | true | 钩索 | | Staves | false | 法杖(目前走装填的是闪电法杖,充能 1.9 s) | | OtherReloadWeapons | false | 其它「需要装填」的武器(游戏更新新增、本模组还不认识的)。宁可不动,也不误伤 | | Verbose | true | 首次遇到某件武器时记一条日志(含前后耗时),同一件只记一次 |
2 - Uninterruptible Reload
| 键 | 默认 | 说明 | | --- | --- | --- | | Enabled | true | 总开关 | | OnRun | true | 奔跑时不打断装填 | | OnJump | true | 跳跃时不打断装填 | | OnDodge | true | 闪避翻滚时不打断装填 | | Verbose | true | 每次新的装填动作被保护时记一条(同一个动作只记一次,不刷屏) |
> 攻击仍然会打断装填 —— 那是原版设计,本模组不动。
3 - Chain Lightning
| 键 | 默认 | 说明 | | --- | --- | --- | | Enabled | true | 总开关(武器侧 + 特效侧一起管) | | WeaponProcChance | 0.66 | 所有「命中时生成连锁预制体」的攻击槽,主/副攻击统一用这个几率。原版主攻击 0.25 / 副攻击 0.20 | | RedStartChance | 1.0 | ChainLightningRed 的起始判定(原版 0.9)。⚠️ 判定是每帧一次(存活期间),不是"每次挥击的触发率" | | RedChancePerTarget | 0.66 | 每个候选目标被链上的几率(原版 0.3),各目标独立判定 | | RedMinTargets | 4 | 一次连锁最少链几个目标(原版 2) | | RedMaxTargets | 6 | 一次连锁最多链几个目标(原版 4),实际个数在 Min~Max 之间随机 | | RedFalloff | 0.8 | 逐跳衰减(原版 0.6):下一跳几率 = 本跳几率 × 该值。填 1 = 不衰减 | | RedStartDelay | 0.18 | 特效生成后多久开始判定(秒) | | RedRadius | 12 | 连锁判定半径(米),原版 8 | | RedTtl | -1(= 不改) | 特效存活时长。-1 = 保持游戏默认(3 秒),本模组完全不碰这个字段;填正数(0.1~30)才覆盖。⚠️ 它同时是连锁的判定窗口,填小了会明显削弱 | | RedLightningDamage | 90 | 每一跳的闪电伤害,原版 75 | | Verbose | true | 打印每条改动的前后数值(便于自证生效) |
> ⚠️ 本模组只改 ChainLightningRed —— 那是「雷血 / BloodLightning」那一族武器 > ($item_*_gold_bloodlightning)用的连锁特效。 > 另一族 ChainLightning(闪电附魔 $item_*_lightning)的参数不动, > 但那些武器的触发几率同样受 WeaponProcChance 影响。
⚠️ 改完必须重启游戏(BepInEx 只在插件 Awake 读一次配置)。
实现要点
功能 1:装填倍率
- 挂载点:
ItemDrop.ItemData.GetWeaponLoadingTime()的 postfix,返回值 × 倍率。 - 这个方法是全程序集唯一调用点为
Player.QueueReloadAction()的纯计算函数
(asm_member_refs.py 实测),返回值写进 MinorActionData.m_duration (进度条文案 $hud_reloading)。⇒ 影响面被天然圈死: 只影响本地玩家按下的那一次装填,不碰 NPC 的 Attack.Start 路径,也不改任何 prefab 数据。
- ⚠️ 必须绕开
!m_requiresReload的分支:那条路径原版返回常量1f,
对它乘倍率会破坏不装填武器的时长语义。代码里在分类之前就先判 m_requiresReload。
- 幂等:纯计算、每次由原始值重算,无累计副作用 ——
所以不需要「记账 + 原值」那套(对比:改写 prefab 数据的模组必须记账)。
- 分类判据用本地化键(
SharedData.m_name),不是显示名(会随语言变)、也不是类名
(游戏里没有 Crossbow / GrapplingHook 类型,行为全挂在 Attack + ItemDrop 上)。 归一化:去 $item_ 前缀 → 去 _/空格/-/. → 转小写。 弩与法杖用 StartsWith(变体多),钩索用精确等值(避免误伤名字相近的物品)。
功能 2:装填不被打断
原版有四个地方把整个动作队列清空(asm_member_refs.py Humanoid::ClearActionQueue 给出):
| 来源 | 位置 | 本模组 | | --- | --- | --- | | 奔跑 | Player.CheckRun(每帧) | 拦 | | 跳跃 | Player.OnJump(第一条指令就是 callvirt ClearActionQueue) | 拦 | | 闪避翻滚 | Player.UpdateDodge(偏移 0x0074) | 拦 | | 攻击 | Humanoid.StartAttack | 不拦(保持原版) |
- 拦截点是
Player.ClearActionQueue(override,真正执行的那份),不是
Humanoid.ClearActionQueue(基类是空实现,只有一句 ret;四个调用点写的都是 callvirt Humanoid::ClearActionQueue,虚拟分发到 Player 的重写)。
Player.ClearActionQueue的实现只有三条指令:ldarg.0 / ldfld m_actionQueue / callvirt List::Clear / ret,
没有任何其它副作用 —— 所以「只清空非装填动作」与「整体清空」在其它方面完全等价。
- 队列里的动作类型:
Player.MinorActionData.ActionType=Equip(0)/Unequip(1)/Reload(2)。
本模组遍历 m_actionQueue,移除除 Reload 外的所有条目,装填那条原地保留 ⇒ 装填进度(m_time)不丢、进度条不归零。
m_actionQueue是私有字段,用AccessTools.FieldRefAccess反射取(解析失败会在
启动自检里打 LogError,不会静默失效)。
- 来源判定用深度计数而非 bool:bool 一旦因异常卡住(prefix 跑了、postfix 没跑)
就会永久误保护;计数配合 > 0 夹紧可以自愈。
- 标了
[HarmonyPriority(Priority.Low)](数值越小越后执行)—— 让别的模组的判定先做。
功能 3:连锁闪电强化
游戏里「闪电伤害」和「连锁闪电」是两件事 —— 不是所有带闪电伤害的武器都会连锁。 反汇编 + prefab 数据核对(游戏 1.0.14)得到的完整链路:
武器命中
└─ Attack.SpawnOnHit(): if (m_spawnOnHitChance > 0 && m_spawnOnHit != null)
if (Random.Range(0f,1f) < m_spawnOnHitChance) ← 功能 3 改这里
在命中点实例化 m_spawnOnHit(连锁特效预制体)
└─ 特效上的 Aoe.CustomFixedUpdate(): ← 功能 3 也改这里
延迟 m_chainStartDelay 后,每帧判一次:Random.value < m_chainStartChance
→ 找目标,个数 = Random.Range(m_chainMinTargets, m_chainMaxTargets + 1)
→ 每个目标:Random.value < m_chainChancePerTarget
→ 生成下一个连锁对象,并把 m_chainChance × m_chainStartChanceFalloff 传下去Highlights
From source dataLoaders
Runs on BepInEx.
Footprint
Rated a light load on a server.
Last update
Its author last shipped an update 39d ago.
EasyWeapon on Nxeon
From our catalogue- One-click install
- Supported on Nxeon Valheim servers, for BepInEx servers. We download it from Thunderstore, place it, and restart the server.
- Server type needed
- BepInEx
- Server load
- light
- Smallest plan we suggest
- Valheim — 4 GB (4 GB RAM). This follows our own load rating above, not a benchmark.
- Latest build
- 1.1.0, released 2026-09-26
Game versions by loader
| Loader | Game versions | Newest |
|---|---|---|
| BepInEx |
From 1 recorded build of EasyWeapon.
Dependencies
- Required: BepInExPack Valheim
Declared by the newest build that lists any. Required ones are installed with it on one-click installs.
Run EasyWeapon on a Valheim server
Pick a server or deploy a new one above; it is installed in one click.
What kind of mod it is
From the catalogWeapons, items & crafting
New weapons, gear, items and the recipes to make them.
Compatibility
- Game
- Valheim
- Loaders
- BepInEx
- Requires
- One-click install needs a BepInEx server.
Verified at the source
- ✓ThunderstoreOfficial listing, checked 2026-10-01Open ↗
- ✓Authors6652289, as published on Thunderstore
- ✓LicenseNot published by the sourceFree






