UniversalInteractableRenderer
地图中立可交互渲染器
基本信息
| 属性 | 值 |
|---|---|
| 路径 | com.gtnewhorizons.navigator.api.model.layers.UniversalInteractableRenderer |
| 行数 | 200 |
| 声明 | extends UniversalLayerRenderer implements InteractableLayer(:25) |
| 实现 | InteractableLayer |
三个字段(:28-29)
protected InteractableLayerManager manager; // :28 ⚠️ 遮蔽父类的 manager!
protected UniversalInteractableStep<?> hoveredRenderStep = null; // :29
⚠️ manager 字段遮蔽了父类 LayerRenderer 的
protected final LayerManager manager:
| 位置 | 类型 | 修饰 |
|---|---|---|
父类 LayerRenderer :29 |
LayerManager |
final |
本类 :28 |
InteractableLayerManager |
非 final |
因为本类的 manager 是协变收窄(InteractableLayerManager 是子类),
所以能遮蔽。
⚠️ 代价:父类方法里写 manager 指的是父类字段,
本类方法里写 manager 指的是子类字段 ——
同名不同对象,且父类字段是 final 不能重新赋值。
子类的构造器必须给子类字段赋值(父类的 final 已在 super 里定死)。
⚠️ 字段名相同 + 都是 manager,是本 mod 最容易看错的一处。
构造器(:35-39)
public UniversalInteractableRenderer(@Nonnull InteractableLayerManager manager)
参数类型是 InteractableLayerManager(收窄),
且未标 @Nonnull 校验。
悬停追踪(:41-52)
public void onMouseMove(int mouseX, int mouseY) { ... }
遍历 getRenderStepsForInteraction()(倒序,见
LayerRenderer 的 :111)找出鼠标下的步骤,
存进 hoveredRenderStep。
⚠️ 用倒序是为了让重叠元素里最上层被选中。
onMapClick(:54-68)—— final
public final boolean onMapClick(boolean isDoubleClick, int mouseX, int mouseY, int blockX, int blockZ)
final,是交互的总入口(各地图的 mixin 调它)。
处理顺序(据源码注释 :22-24):
- 命中测试找
hoveredRenderStep - 若配了
withClickAction(action)→ 调它(见下) - 若它未消费(返回
false)→ 走onClick(...)默认路径 - 默认路径里双击切换路点
⚠️ 返回 boolean = 是否消费了这次点击,
调用方(mixin)据此决定是否继续原地图自己的点击处理。
四个可覆写方法
| 方法 | 行 | 说明 |
|---|---|---|
onClick(boolean, int, int, int, int) |
:74-90 |
点击命中步骤时的处理(17 行) |
onClickOutsideRenderStep(boolean, int, int, int, int) |
:92-95 |
点在空白处 |
getTooltip() |
:97-104 |
悬停 tooltip(List<String>) |
drawCustomTooltip(FontRenderer, int, int, int, int) |
:106-~116 |
自定义 tooltip 绘制 |
onKeyPressed(int) |
:118-~132 |
按键处理(15 行) |
⚠️ onClickOutsideRenderStep 只有 4 行 ——
默认不做任何事(false),即「点空白不消费」。
两个链式配置器
| 方法 | 行 | 参数 |
|---|---|---|
withClickAction(Predicate<ClickPos>) |
:141-150 |
点击前运行的回调 |
withKeyPressAction(IntPredicate) |
:152-~160 |
按键回调 |
⚠️ withClickAction 用 Predicate<ClickPos> 而非 Consumer ——
因为 Predicate 的返回值表示是否消费,
这是本类「自定义优先、默认兜底」契约的实现基础。
参数是 ClickPos(见该条目)。
⚠️ withKeyPressAction 用 IntPredicate(int = keyCode),
配了就接管按键(onKeyPressed 不再走
NavigatorApi.ACTION_KEY 的默认派发)。
与 WaypointManager 的关系
默认路点切换通过
InteractableLayerManager 的
setActiveWaypoint / clearActiveWaypoint / hasActiveWaypoint
(:82-112)完成,而不是直接用 WaypointManager。
相关
- UniversalLayerRenderer - 父类
- InteractableLayer - 实现的接口
- UniversalLocationInteractableStep - 被追踪的步骤
- InteractableLayerManager -
manager字段的类型 - ClickPos -
withClickAction的参数