兼容模组

基本信息

属性 值
类型 特殊机制(运行时第三方 mod 适配)
探测实现 com.caedis.freecam.compat.Mods(enum,共 4 个取值)
Angelica 适配 com.caedis.freecam.compat.AngelicaCompat(独立类)
探测方式 Loader.isModLoaded(modid) + class 文件资源存在性探测
结果缓存 首次调用 isLoaded() 后写入 Boolean loaded,此后不再重算

⚠️ 本条目只讲运行时行为分支。用于决定是否应用 Mixin 的第三套判定(TargetedMod)见 Mixin 加载阶段。

Mods 四个取值

枚举值 判定条件 触发后的行为
ANGELICA Loader.isModLoaded("angelica") 滚轮事件里检查 Angelica 的 Zoom.getZoomKey().getIsKeyPressed(),按下则不调整相机速度
ANGELICA_HAND_EVENT isModLoaded("angelica") 且 class com/gtnewhorizons/angelica/event/RenderHandEvent.class 存在 ClientEventHandler 构造时调用 AngelicaCompat.registerAngelicaHandListener()
CONTROLLING isModLoaded("controlling") 且 class com/blamejared/controlling/keybinding/ComboKeyBinding.class 存在 按键匹配改走 isComboModifierActive(binding) 判定
EFR Loader.isModLoaded("etfuturum") F4 按下时检查 EFR 的切换游戏模式键,命中则本次不进入 freecam

⚠️ ANGELICA_HAND_EVENT 与 CONTROLLING 的 modid 字段是 null:这两个枚举项走的是 Supplier<Boolean> 构造器,只提供判定逻辑不提供 modId 字面量。

ANGELICA_HAND_EVENT 的源码注释记录了版本门槛:RenderHandEvent 是 Angelica 2.1.30 才加入的, 所以只判 isModLoaded("angelica") 不够,必须再探测 class 文件。

classFileExists(String) 的实现是 Mods.class.getClassLoader().getResource(path) != null—— 在未初始化目标类的前提下做类加载器资源探测,因此不会因为类缺失而抛 NoClassDefFoundError。

AngelicaCompat

AngelicaCompat 被拆成独立类,源码注释写明原因:让判定表达式不会提前 classload Angelica 的类。

@Optional.Method(modid = "angelica")
public static void registerAngelicaHandListener() {
    RenderHandEvent.BUS.addListener(
        event -> FreecamController.instance().isActive() && !MiscConfig.showHand);
}
项目 值
注解 @Optional.Method(modid = "angelica")——缺 Angelica 时整段代码不加载
入口守卫 Mods.ANGELICA_HAND_EVENT.isLoaded()(ClientEventHandler 构造函数内)
订阅 Angelica 的 RenderHandEvent.BUS
谓词 isActive() && !MiscConfig.showHand
效果 注释说明:Angelica 从 HandRenderer#canRender 派发该事件,取消它即可在光影下隐藏手部

即 显示手部 这个配置项有两条实现路径:原版侧走 MixinEntityRenderer.renderHand 注入,Angelica 光影侧走这个事件监听器。

Controlling:组合键判定

ClientEventHandler.matchesKeyBinding(ClientEventHandler.java:155):

if (keyCode != binding.getKeyCode()) return false;
if (Mods.CONTROLLING.isLoaded()) return isComboModifierActive(binding);
return true;

isComboModifierActive 带 @Optional.Method(modid = "controlling"):若该 KeyBinding 是 Controlling 的 ComboKeyBinding 实例,则要求其组合键修饰符处于激活状态,否则返回 true(不拦截)。 因此安装 Controlling 后,本 mod 的三个按键都能挂上 Ctrl/Shift/Alt 修饰键而不会误触发。

EFR:F3 冲突规避

isEFRGameModeSwitcherKeyPressed()(@Optional.Method(modid = "etfuturum"))读取 ConfigFunctions.enableGamemodeSwitcher && Keyboard.isKeyDown(Keyboard.KEY_F3)。 命中时 onKeyInput 直接 return,既不进入 freecam 也不清空按键队列。

两套判定的区别

Mods(本条目) TargetedMod(Mixin 加载阶段)
阶段 运行时 加载期
依据 Loader.isModLoaded + class 资源探测 TargetModBuilder.setModId
用途 事件处理中切换行为分支 决定是否把 Mixin 应用到目标类
覆盖的 mod Angelica、Angelica 2.1.30+、Controlling、Et Futurum Waila、Thaumcraft、holoinventory

⚠️ Thaumcraft、WAILA、holoinventory 不在 Mods 枚举里——它们只出现在 TargetedMod 中, 仅用于 Mixin 挂载,不参与任何运行时分支。

相关条目