- 游戏开发
- 插件系统
【免费下载链接】REPENTOGON
Script extender for The Binding of Isaac: Repentance
KnifeSubType 是 REPENTOGON 为《以撒的结合:忏悔》(The Binding of Isaac: Repentance)脚本扩展定义的一组实体子类型枚举,用于区分游戏内EntityKnife(飞刀实体,实体类型EntityType.ENTITY_KNIFE,值为 8)的不同行为形态。本文以 docs/docs/enums/KnifeSubType.md 为骨架,结合仓库源码,完整说明每个枚举值的含义、底层实现与在MC_PRE_KNIFE_COLLISION等回调中的过滤用法,帮助 Mod 作者在编写飞刀相关逻辑时做出正确的判断与过滤。
枚举定义总览
KnifeSubType是一个整数型枚举,完整定义如下:
| Value | Enumerator | Comment |
|---|---|---|
| 0 | DEFAULT | 默认飞刀 |
| 1 | PROJECTILE | 投射物式飞刀(自带寻路路径) |
| 3 | YES_MOTHER | 与“妈妈(Mother)”战斗机制相关的飞刀 |
| 4 | CLUB_HITBOX | 近战武器“挥击”产生的判定框(hitbox) |
该枚举在仓库中有两处权威来源,内容完全一致:
- 文档定义:docs/docs/enums/KnifeSubType.md
- Lua 侧枚举:repentogon/resources/scripts/enums_ex.lua(第 791–796 行)
enums_ex.lua中的实际定义:
KnifeSubType = { DEFAULT = 0, PROJECTILE = 1, YES_MOTHER = 3, CLUB_HITBOX = 4, }注意枚举值存在跳号:值 2 未出现在文档与enums_ex.lua中,说明该值在游戏中并未被占用或对外暴露,Mod 代码中不应使用 2 作为有效的KnifeSubType。
各枚举值的语义与源码依据
DEFAULT(0):默认飞刀
DEFAULT是KnifeSubType的默认值(值为 0),对应游戏中最普通的飞刀形态,例如由道具生成的常规飞刀。它是其他子类型的“基准形态”,也是大多数飞刀实体的默认状态。
PROJECTILE(1):投射物式飞刀
PROJECTILE表示“投射物式”飞刀,这类飞刀依赖一条寻路路径(homing path)驱动运动。从源码看,该类飞刀在初始化时会调用Entity_Knife::InitHomingPath计算路径:
- repentogon/LuaInterfaces/Entities/LuaEntityKnife.cpp 中
Lua_InitHomingPath暴露了knife:InitHomingPath(Direction, Source)接口,注释明确指出该接口用于 homing 飞刀或KnifeSubType.PROJECTILE(subtype 1)飞刀的路径(重新)计算:(Re)calculates the path used for homing knives or "projectile" knives (subtype 1;
KnifeSubType.PROJECTILE). - 底层函数签名定义在 libzhl/functions/EntityKnife.zhl:
Entity_Knife::InitHomingPath(Vector direction, Entity* source, float pathOffset)。
PROJECTILE飞刀还有一个重要的历史修复。仓库 repentogon/Patches/MiscFixes.cpp(第 275–288 行)中专门有一段修复注释与挂钩代码:
SubType 1 knives crash during Update if the HomingLaser stuff isn't initialized (like if a mod spawns one).
即:当 Mod 直接生成 subtype 1 的飞刀时,如果其 HomingLaser 相关数据未被初始化,会在Update阶段崩溃。REPENTOGON 通过挂钩LuaEngine::PostKnifeInit,在该类飞刀初始化后立即以直线路径调用InitHomingPath兜底,避免崩溃;之后若 Mod 再次调用InitHomingPath重新计算路径,则会被干净地覆盖。同一修复也记录在 changelog.txt:
Knives spawned as KnifeSubType.PROJECTILE (1) will no longer crash the game.
实战提示:Mod 自行Isaac.Spawn生成KnifeSubType.PROJECTILE飞刀时,建议主动调用一次InitHomingPath指定方向与来源,以获得可控的运动轨迹,而非依赖兜底直线路径。
YES_MOTHER(3):妈妈战斗机制飞刀
YES_MOTHER(值为 3)从命名上推断与最终 Boss“妈妈(Mother)”的战斗演出相关,属于游戏内部机制使用的子类型,在 docs/docs/EntityKnife.md 及源码中均未进一步暴露公开接口。对 Mod 而言,它的实际用途是在碰撞/更新回调中区分出这类由 Boss 机制生成的飞刀,避免误判为玩家道具飞刀。
CLUB_HITBOX(4):近战武器判定框
CLUB_HITBOX是近战武器(Bone Club、Spirit Sword 等)“挥击”动作所生成的特殊飞刀判定框。它与“主飞刀”(main knife)之间通过一个专属引用关联,REPENTOGON 为此提供了两个 Lua 接口(实现在 repentogon/LuaInterfaces/Entities/LuaEntityKnife.cpp):
knife:GetHitboxParentKnife():对KnifeSubType.CLUB_HITBOX判定框返回其所属近战武器的“主”EntityKnife;对非判定框飞刀或通过其他方式生成的判定框返回nil。knife:SetHitboxParentKnife(Knife):手动设置GetHitboxParentKnife的返回值。文档 docs/docs/EntityKnife.md 明确说明:该引用不影响任何原版逻辑,仅为 Mod 便利而提供,请妥善使用。
底层实现中,该引用保存在EntityKnifePlus扩展结构的hitboxSource字段(由 repentogon/Patches/EntityPlus.cpp 中的ENTITY_KNIFE分支挂接),读取时校验目标实体的类型为ENTITY_KNIFE后才返回。
实战场景:当你在MC_PRE_KNIFE_COLLISION/MC_POST_KNIFE_COLLISION中处理碰撞时,可以用GetHitboxParentKnife把近战判定框与武器本体关联起来,从而精确判断“是谁的武器命中了谁”。
在 ModCallbacks 回调中按子类型过滤
KnifeSubType最重要的实战价值,是作为飞刀相关回调的过滤参数。在 docs/docs/enums/ModCallbacks.md 中,以下回调的可选参数(Optional Args)均为KnifeSubType:
| ID | 回调名 | 函数参数 | 可选参数(过滤用) | 返回类型 |
|---|---|---|---|---|
| 53 | MC_PRE_KNIFE_COLLISION | (EntityKnife Knife, Entity Collider, boolean Low) | KnifeSubType | boolean或table |
| 1243 | MC_POST_KNIFE_COLLISION | (EntityKnife Knife, Entity Collider, boolean Low) | KnifeSubType | void |
| 1165 | MC_PRE_KNIFE_UPDATE | (EntityKnife Knife) | KnifeSubType | boolean |
也就是说,注册回调时传入KnifeSubType枚举值,即可让回调只针对特定形态的飞刀触发。典型用法:
-- 只响应“投射物式飞刀”的碰撞前回调 mod:AddCallback(ModCallbacks.MC_PRE_KNIFE_COLLISION, function(_, knife, collider, low) -- 只有 subtype == 1 的飞刀会进入这里 return false end, KnifeSubType.PROJECTILE) -- 只响应近战武器判定框的更新回调 mod:AddCallback(ModCallbacks.MC_PRE_KNIFE_UPDATE, function(_, knife) local parent = knife:GetHitboxParentKnife() if parent ~= nil then -- 关联到挥击武器的本体 end return false end, KnifeSubType.CLUB_HITBOX)其中MC_PRE_KNIFE_COLLISION还支持返回一个table来精细控制碰撞行为(详见 docs/docs/enums/ModCallbacks.md):
Collide:设为true强制实体发生物理碰撞(推开彼此),除非“碰撞者”忽略碰撞;设为false忽略物理碰撞而不必跳过碰撞效果。SkipCollisionEffects:设为true跳过该实体的碰撞后果代码(如碰撞伤害),不影响物理碰撞,也不会跳过“碰撞者”的碰撞代码。
源码级调用链参考
以下是编写飞刀相关 Mod 时可进一步查阅的仓库文件(均以仓库根目录为基准):
| 用途 | 文件 |
|---|---|
| 枚举文档 | docs/docs/enums/KnifeSubType.md |
| Lua 侧枚举定义 | repentogon/resources/scripts/enums_ex.lua |
EntityKnife类接口文档 | docs/docs/EntityKnife.md |
Lua 接口实现(InitHomingPath、Get/SetHitboxParentKnife、命中列表等) | repentogon/LuaInterfaces/Entities/LuaEntityKnife.cpp |
PROJECTILE飞刀崩溃修复 | repentogon/Patches/MiscFixes.cpp |
Entity_Knife内存结构定义 | libzhl/functions/EntityKnife.zhl |
| 回调注册与分发(碰撞/更新挂钩) | repentogon/LuaInterfaces/CustomCallbacks.cpp |
飞刀实体类型常量ENTITY_KNIFE = 8 | libzhl/functions/Global.zhl |
注意事项小结
- 跳号问题:
KnifeSubType只定义 0、1、3、4 四个值,值 2 未使用;判断子类型时应使用枚举名而非连续整数假设。 PROJECTILE飞刀必须初始化路径:Mod 直接生成 subtype 1 飞刀时,REPENTOGON 会兜底初始化直线路径防止崩溃,但建议主动调用InitHomingPath获得预期轨迹。CLUB_HITBOX是判定框而非武器本体:通过GetHitboxParentKnife/SetHitboxParentKnife关联主飞刀;该关联不影响原版逻辑,仅用于 Mod 内部逻辑。- 回调过滤:三个飞刀相关回调(53 / 1243 / 1165)均可将
KnifeSubType作为可选参数,是最简洁的按形态分流手段。
- 游戏开发
- 插件系统
【免费下载链接】REPENTOGON
Script extender for The Binding of Isaac: Repentance
相关推荐
使用 Pyro 的 `pyro.contrib.epidemiology` 构建传染病舱室模型:从 SVI/HMC 推断到轨迹预测与远期预报
使用 Pyro 的 pyro.contrib.epidemiology 构建传染病舱室模型:从 SVI/HMC 推断到轨迹预测与远期预报 pyro.contri
游戏开发插件系统REPENTOGON 中 WeaponModifier 枚举详解:武器修饰位掩码的定义、Lua 用法与源码实现
REPENTOGON 中 WeaponModifier 枚举详解:武器修饰位掩码的定义、Lua 用法与源码实现 本文围绕 REPENTOGON 的 Weapon
游戏开发插件系统TypeScript枚举类型详解:数字枚举与字符串枚举的完整用法
TypeScript枚举类型详解:数字枚举与字符串枚举的完整用法 TypeScript枚举类型是TypeScript中一个强大的特性,它允许我们定义一组命名的常
文档教程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考