兼容模组
基本信息
| 属性 | 值 |
|---|---|
| 类型 | 特殊机制(运行时第三方 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 挂载,不参与任何运行时分支。
相关条目
- Mixin 加载阶段 - 加载期的第三方 mod 判定与全部 7 个 Mixin 的枚举表
- 显示手部 -
AngelicaCompat监听器与原版注入共用的门控项 - 切换自由相机 - 受 Controlling 修饰键与 EFR F3 规避影响的按键
- 覆盖层可见性 - 三个后期 Mixin 依赖的
RevealGate