Source-checkedWeapons, items & crafting

EasyWeapon

by s6652289 · for Valheim

[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).

63Downloads
39d agoLast updated
BepInExLoaders
ThunderstoreSource

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 传下去

Read the full description on Thunderstore →

Highlights

From source data

Loaders

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

LoaderGame versionsNewest
BepInEx

From 1 recorded build of EasyWeapon.

Dependencies

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 catalog
Listed on Thunderstore as “Content”

Weapons, 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

EasyWeapon, answered

Generated from the mod’s own source data.

Which loaders does it support?

BepInEx.

Is it free?

Yes. EasyWeapon is free to download from Thunderstore.

How do I add it to my Nxeon server?

Use “Add to a server” on this page, or open NxLabs from your dashboard. We install it, restart your server and switch it on.

NxLabs

Run EasyWeapon on a Valheim server.

Deploy in about a minute from $9.99 a month, then add EasyWeapon in one click.