REPENTOGON 实体配置文件 entities2.xml 全解析:扩展属性与 customtags 自定义标签机制
游戏开发插件系统【免费下载链接】REPENTOGONScript extender for The Binding of Isaac: Repentance项目地址https://gitcode.com/gh_mirrors/re/REPENTOGON点击查看免费下载导读本文以 REPENTOGON 官方文档 docs/docs/xml/entities.md 为骨架深入剖析entities2.xml中由 REPENTOGON 新增的全部扩展属性coinvalue、customtags、bagofcrafting、meleecollide、boomerang、isactiveenemy、nosplit并结合 EntityConfigEx.cpp、FamiliarTags.cpp、GetCoinValue.cpp 等源码揭示每个属性的底层实现与生效时机。读完本文你将掌握如何通过纯 XML 声明为自定义实体注入捡拾物配方、金币价值、敌对判定等行为并能利用customtags体系让自定义跟班Familiar具备挡弹幕、可受伤、免疫 BFFS 等复杂特性从而摆脱逐个实体手写 Lua 代码的繁琐工作。一、文件定位与加载语义Resource-Folder vs Content-Folderentities2.xml即官方所称entities2.xml文件是 REPENTOGON 对原版实体配置 XML 的扩展载体。与绝大多数 REPENTOGON 扩展 XML 一致参见 docs/docs/xml/overview.md该文件存在两种截然不同的放置位置语义完全不同放置位置行为Resource-Folder资源文件夹使用该文件将替换原版同名文件属于整体覆盖式加载Content-Folder内容文件夹使用该文件将新增实体属于增量追加式加载这一机制意味着Mod 若想为游戏添加全新实体例如自定义 NPC 或捡拾物应当将entities2.xml放入 content 目录若想整体改写某类实体的默认配置则放入 resource 目录。另需注意 REPENTOGON 的通用规则REPENTOGON 引入的 XML 变量名不区分大小写见 docs/docs/xml/overview.mdcamelCase、全小写等命名习惯均被接受。二、扩展属性速查表REPENTOGON 在entities2.xml的实体节点上新增了以下属性。其中customtags同时适用于所有实体类型其余属性则按功能限定于特定类型捡拾物 / NPC变量名可选值说明coinvalueint该金币捡拾物在调用GetCoinValue无论是游戏内部还是 Lua 调用时的价值customtagsstring以空格分隔的字符串列表详见下文 CustomTags 章节nosplitboolean阻止该 NPC 被屠刀Meat Cleaver分裂bagofcraftingstring仅捡拾物。空格分隔的合成原料列表收集时最多向合成袋Bag of Crafting注入 8 个原料。示例bagofcraftingpenny bomb keymeleecollideboolean仅捡拾物。是否允许在受到骨棒Bone Club/ 灵剑Spirit Sword等近战武器命中时与玩家发生碰撞拾取boomerangboolean仅捡拾物。是否允许该捡拾物被回旋镖Boomerang与下颚骨Jawbone抓取isactiveenemyboolean该 EntityNPC 是否被判定为活跃敌人Active Enemy其中bagofcrafting的合法取值集合来自 EntityConfigEx.cpp 中的bagOfCraftingTags映射表完整列举如下none、redheart、soulheart、blackheart、eternalheart、goldheart、boneheart、rottenheart、penny、nickel、dime、luckypenny、key、goldkey、chargedkey、bomb、goldbomb、gigabomb、minibattery、battery、megabattery、card、pill、rune、diceshard、crackedkey、goldpenny、goldpill、goldbattery、poop每个取值对应合成袋中的一个内部 IDredheart→1、soulheart→2、blackheart→3……poop→29。三、逐属性深度解析与底层实现3.1coinvalue自定义金币的价值原版GetCoinValue()仅认识 0~7 号的原版金币子类型对模组新增的金币子类型会返回随机的大数值这会导致合成袋、贪婪模式Greed Mode等按金币价值结算的逻辑异常。REPENTOGON 通过 GetCoinValue.cpp 对该函数进行了整体重实现非金币拾取物直接返回 0子类型在 0~7 之间时返回原版价值表{1, 1, 5, 10, 2, 1, 5, 1}其余模组子类型情况下返回 XML 中coinvalue属性指定的值解析逻辑见 EntityConfigEx.cpp非金币变体的coinValue_恒为 0仍无法识别时兜底返回 1等价于 1 枚便士。在EntityEx::Parse()中coinvalue的读取条件是实体是金币entity.id ENTITY_PICKUP且变体为金币且子类型不在 0~7 的原版范围内且要求字符串以数字字符开头isdigit(it-second[0])否则回退默认值 1。此外GetCoinValue.cpp 还会在需要时触发MC_PICKUP_GET_COIN_VALUE回调 ID 1250Lua 回调允许脚本在 XML 值之上做进一步覆盖而贪婪模式路径上为性能考虑不触发该回调但 XML 属性依然生效。这也解释了为什么coinvalue的语义是GetCoinValue 返回值而不仅是拾取瞬间的金币数。3.2bagofcrafting为自定义捡拾物定制合成原料当玩家收集到带该属性的捡拾物时合成袋会按属性中声明的原料序列填充。其解析函数ParseBagOfCraftingAttributeEntityConfigEx.cpp的行为值得注意属性值先被整体转成小写再按空格切分逐个映射最多接受 8 个原料超出部分直接截断遇到none/false/-1内部 ID 均为 0会立即终止解析——它既表示此位置无原料也表示后续条目不再解析遇到未知字符串立即停止不报错也不影响已解析部分。在运行时ASMBagOfCrafting.cpp 中的TryAddToBagOfCraftingTrampoline会优先采用 XML 中声明的原料表而非原版按 TypeVariant 推断的原料并在收集前触发MC_TRY_ADD_TO_BAG_OF_CRAFTING1015回调成功加入后还会触发MC_POST_ADD_TO_BAG_OF_CRAFTING1016回调。此外若一个捡拾物声明了有效的bagofcrafting原料即使它被近战武器meleeVariant 4即骨棒类击中也会被强制允许碰撞拾取见 ASMBagOfCrafting.cpp保证合成原料能正常进入玩家背包。3.3meleecollide与boomerang控制捡拾物拾取途径这两个布尔属性都只对捡拾物生效用于覆盖该捡拾物能否被特定途径拾取的原版判定meleecollide决定拾取物是否会在被骨棒、灵剑等近战武器击中时与玩家发生碰撞即打飞金币再吸回类交互boomerang决定该拾取物是否允许被回旋镖与下颚骨抓取。二者共用同一套运行时逻辑CanPickupBePickedUpASMBagOfCrafting.cpp会根据拾取途径回旋镖途径取boomerang值近战途径取meleecollide值查询EntityEx中对应的 override 值。meleecollide/boomerang属于三态覆盖设计见 EntityConfigEx.h 的注释属性在 XML 中缺失时std::optionalbool保持nullopt此时回落至游戏默认行为只有显式写了true/false才强制覆盖。需要留意的是即便meleecollidetrue捡拾物仍需满足ignorePrice || price 0商店物品标价时仍不可免费拾取。3.4isactiveenemy自定义 NPC 的活跃敌人判定游戏中部分机制如某些刷怪逻辑、成就判定依赖Entity::IsActiveEnemy()。REPENTOGON 通过 ASMEntityNPC.cpp 中的HOOK_METHOD(Entity, IsActiveEnemy, ...)实现覆盖当实体类型处于ENTITY_GAPER与ENTITY_EFFECT之间即常规 NPC 区间且 XML 中声明了isactiveenemy时直接返回该值并叠加死亡判定!this-_dead || includeDead未声明则走原版逻辑。3.5nosplit阻止屠刀分裂nosplit同样是三态覆盖EntityEx::GetNoSplitOverride()返回std::optionalbool。在 ASMCallbacks.cpp 的TrySplitTrampoline中当该值为true时会把分裂结果resSplit强制置为 false。该 hook 同时位于MC_PRE_NPC_SPLIT实体分裂回调链路上意味着玩家脚本回调返回值优先XML 的nosplit次之最终才回落原版判定。四、customtags面向 Mod 的通用实体特征标签4.1 设计动机原版实体的行为特征依赖内置的EntityTag枚举Mod 无法在 XML 层面直接声明。REPENTOGON 新增的customtags属性允许 Mod 在entities2.xml中为任意实体声明任意数量的自定义字符串标签以空格分隔并在游戏内随时查询。其核心价值在于用纯 XML 声明常见实体特征/行为无需在 Lua 代码中逐个列出实体Mod 之间可以互相引用彼此的customtags从而显著降低 Mod 兼容成本例如 A Mod 的实体会自动获得 B Mod 声明的行为特性。4.2 语法与大小写规则customtags是一个以空格分隔的字符串列表大小写完全不敏感无论是写入、查询还是返回大小写均被忽略。customtagsyourcustomtag familiarignorebffs familiarblockprojectiles其解析入口是 XMLData.h 中的ParseTagsString先将整个属性值转为小写再按空格逐词切分非空词条插入集合。由于存入的是小写形式后续查询HasCustomTag也会在比较前做同样的处理因此大小写不影响匹配。4.3 Lua 查询 APIcustomtags可通过 EntityConfig 全局表在游戏内查询。查询入口是EntityConfig.GetEntity(entType, entVar, entSub)返回的 EntityConfigEntity 对象提供两个方法Lua 绑定实现见 LuaEntityConfig.cpplocal entConfig EntityConfig.GetEntity(entType, entVar, entSub) -- 若实体拥有指定标签字符串则返回 true大小写无关 if entConfig:HasCustomTag(yourcustomtag) then -- ... end -- 返回该实体声明的全部 customtags 表标签一律为小写 local customTags entConfig:GetCustomTags()要点HasCustomTag(tag)传入任意大小写均可底层通过EntityEx::HasCustomTag在std::setstd::string中做count判定EntityConfigEx.hGetCustomTags()返回的表中所有标签均为小写形式解析时已统一转小写查询对象未声明任何标签时HasCustomTag返回falseGetCustomTags返回空表。4.4 REPENTOGON 内置标签表REPENTOGON 自身预置了一批标签Mod 只需在 XML 中声明即可为自定义实体尤其是自定义跟班挂载行为无需任何 Lua 代码customtag效果familiarignorebffsBFFS 道具将不再影响该跟班例如不享受其属性加成倍率familiarcantakedamagebaseHP 大于 0 的跟班将能够受到伤害并死亡如来自敌人接触、激光或爆炸。注意除非同时具备familiarblockprojectiles标签否则它们仍不会受到弹幕伤害familiarblockprojectiles跟班接触敌方弹幕时自动摧毁弹幕nocharm使跟班不会被塞壬Siren魅惑noerase阻止实体被橡皮擦Eraser效果清除即使其 TypeVariant 已被擦除norerollpickup仅捡拾物。阻止重掷reroll、Jera、Ace 牌、移动盒Moving Box等效果nojera仅捡拾物。阻止通过 Jera 复制。注意若已声明norerollpickup则无需再声明本标签这些标签对应的内部常量统一定义在 EntityConfigEx.h 的CustomTags命名空间中如FAMILIAR_IGNORE_BFFS familiarignorebffs、ENTITY_NO_ERASE noerase等。4.5 内置标签的源码级实现这 7 个内置标签并非空壳而是由真实的 Hook / ASM 补丁驱动逐一印证如下familiarignorebffsFamiliarTags.cpp 中FamiliarGetMultiplierTrampoline检测到该标签时直接返回false并通过ASMPatchFamiliarGetMultiplier注入Entity_Familiar::GetMultiplier从而屏蔽 BFFS 的倍率加成familiarcantakedamage/familiarblockprojectiles见 FamiliarTags.cpp。CanBlockProjectilesHook 与CanBeDamagedByEnemyHook 分别让跟班能自动摧毁弹幕、能受到敌人与激光伤害由于Entity_Familiar::CanBeDamagedByProjectiles与CanBeDamagedByLaser被原版内联进了碰撞函数REPENTOGON 通过特征码扫描定位后注入了重新实现FamiliarCanBeDamagedByProjectilesReimplementation/FamiliarCanBeDamagedByLaserReimplementation其中弹幕伤害要求两个标签同时具备nocharm以HOOK_METHOD_PRIORITY(Entity_Familiar, CanCharm, -1000, ...)FamiliarTags.cpp在最低优先级拦截魅惑判定返回falsenoerase通过HOOK_STATIC(Game, AddErasedEnemy, ...)与HOOK_STATIC(Game, ShouldEraseEnemy, ...)实现EntityConfigEx.cpp在橡皮擦逻辑写入擦除记录前直接拦截norerollpickupHOOK_STATIC(Entity_Pickup, CanRerollVariant, ...)拦截重掷判定EntityConfigEx.cpp使重掷、Jera、Ace 牌、移动盒等依赖该判定的效果一并失效nojeraHOOK_METHOD(Entity_Pickup, CanJeraDuplicate, ...)直接禁止 Jera 复制EntityConfigEx.cpp。以上跟班相关补丁统一由ASMPatchesForFamiliarCustomTags()在游戏启动阶段注册见 ASMPatches.cpp 的调用金币、合成袋补丁则分别由ASMPatchesForGetCoinValue()、ASMPatchesForBagOfCrafting()注册同文件第 203、293 行。五、组合实战用纯 XML 打造一个完整功能的自定义跟班将上述机制组合起来可以在零 Lua 代码的情况下声明一个拥有多种行为的自定义跟班!-- content/xxx/entities2.xml示意 -- entity id1000 variant100 subtype0 ... tagsfamiliar/tags customtagsfamiliarignorebffs familiarcantakedamage familiarblockprojectiles nocharm/customtags /entity声明familiarignorebffsBFFS 不会改变其属性倍率同时声明familiarcantakedamage与familiarblockprojectiles它能被敌人、激光伤害并死亡同时会自动摧毁接触到的敌方弹幕弹幕伤害也因此可作用于它声明nocharm免疫塞壬魅惑。若希望该跟班被橡皮擦豁免再加入noerase。所有行为均来自 REPENTOGON 内置标签的 Hook/ASM 实现见上文 4.5 节无需编写任何脚本。六、扩展阅读customtags在其他配置中的延伸customtags并非entities2.xml独有。REPENTOGON 在同一套CustomTags机制上将其扩展到了物品配置ItemConfigEx.cpp物品Collectible / Trinket / NullItem的customtags同样走ParseTagsString解析并提供ItemConfigItem:GetCustomTags()/ItemConfigItem:HasCustomTag()两个 Lua 方法绑定见 LuaItemConfig.cpp还支持flying、revive等物品侧标签并自动设置cacheFlags触发属性重算。若你的 Mod 同时自定义实体与道具可以复用同一套标签语言降低学习成本。七、使用注意事项小结加载方式新增实体放 content 文件夹整体替换放 resource 文件夹docs/docs/xml/entities.md。大小写REPENTOGON 新增的 XML 属性名与customtags标签值均不区分大小写bagofcrafting的原料名同样大小写无关。范围限定bagofcrafting、meleecollide、boomerang、norerollpickup、nojera仅对捡拾物生效nosplit、isactiveenemy仅对 NPC 生效跟班标签仅对ENTITY_FAMILIAR生效。三态覆盖meleecollide、boomerang、nosplit、isactiveenemy未声明时回落原版行为声明true/false才强制覆盖。不冲突的依赖familiarcantakedamage若期望弹幕伤害必须同时声明familiarblockprojectilesnojera在已有norerollpickup时冗余。可验证依据以上全部行为均可追溯至 EntityConfigEx.cpp、FamiliarTags.cpp、GetCoinValue.cpp 与 ASMBagOfCrafting.cpp 的源码实现。赞分享游戏开发插件系统【免费下载链接】REPENTOGONScript extender for The Binding of Isaac: Repentance项目地址https://gitcode.com/gh_mirrors/re/REPENTOGON点击查看免费下载相关推荐TSDoc配置完全手册自定义标签和扩展配置详解TSDoc配置完全手册自定义标签和扩展配置详解 TypeScript文档注释标准TSDoc提供了强大的配置系统让开发者能够根据项目需求自定义标签和扩展配置。开发工具文档Weblate 的 Flat XML 文件格式从组件配置到自定义标签结构解析Weblate 的 Flat XML 文件格式从组件配置到自定义标签结构解析 本篇技术指南以 Weblate 官方文档 docs/formats/flatxm后端开发工具Weblate Flat XML 文件格式深度指南单语 XML 翻译支持与自定义标签配置Weblate Flat XML 文件格式深度指南单语 XML 翻译支持与自定义标签配置 导读 本文聚焦 Weblate 对 Flat XML扁平 XML后端开发工具上一篇Multer开源贡献者访谈核心开发者分享开发心得下一篇mlpack 在 Raspberry Pi 上交叉编译 ARMv7 实战从 Bootlin 工具链到 mlpack_knn 命令行程序创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考