光照等级覆盖层(Light Level Overlay)

基本信息

属性 值
实现类 lightoverlay/LightLevelOverlayRenderer.java
事件接线 lightoverlay/OverlayEventHandler.java
切换键 L(见 按键与指令)
默认模式 MODE_OFF(关闭)
扫描半径 RADIUS = 8(横向 17×17 格)
扫描高度 HEIGHT = 12(纵向 25 格)
唯一配置项 LightOverlayConfig.DisableFollowNumber(默认 false)

功能类似 F3 的光照调试:在玩家周围把每格的光照等级数字画在方块上。

5 种模式

LightLevelOverlayRenderer.java:25-29:

public static final int MODE_OFF        = 0;
public static final int MODE_ALL        = 1;
public static final int MODE_SPAWNABLE  = 2;
public static final int MODE_SKY        = 3;
public static final int MODE_CAN_SPAWN  = 4;
public static int currentMode = MODE_OFF;

toggleMode()(LightLevelOverlayRenderer.java:172-175)是循环递增:

public static void toggleMode() {
    currentMode++;
    if (currentMode > MODE_CAN_SPAWN) {
        currentMode = MODE_OFF;
    }
    ...
}

⇒ 循环顺序 OFF → ALL → SPAWNABLE → SKY → CAN_SPAWN → OFF。

模式 值 显示 lang(en_US.lang:34-38)
MODE_OFF 0 不渲染(render 首行 if (currentMode == MODE_OFF) return;,40) §cDisabled
MODE_ALL 1 所有光照等级 §aAll Light Levels
MODE_SPAWNABLE 2 只显示 0–7(可刷怪等级) §eMob Spawnable Only (0-7)
MODE_SKY 3 只显示天空光照 §bSky Light Only
MODE_CAN_SPAWN 4 实际生成判定(getSpawnMode) §6Spawn Check

MODE_SPAWNABLE 的过滤在 LightLevelOverlayRenderer.java:118:

if (currentMode == MODE_SPAWNABLE && light > 7) continue;

MODE_SKY 在 112;MODE_CAN_SPAWN 在 103-106(先算 getSpawnMode, spawnMode == 0 则 continue)。

扫描范围与渲染

render(float partialTicks)(LightLevelOverlayRenderer.java:39):

步骤 行 内容
早退 40 MODE_OFF 直接返回
空值检查 42-45 player / world 为 null 则返回
惰性创建 47-52 dummyEntity = new EntityPig(null);aabb = AxisAlignedBB.getBoundingBox(0,0,0,0,0,0)
插值坐标 54-56 用 partialTicks 在 lastTickPos* 与 pos* 之间插值
GL 变换 58-59 glPushMatrix + glTranslated(-px, -py, -pz)(抵消玩家位移)
GL 状态 61-64 关 GL_LIGHTING、开 GL_BLEND(SRC_ALPHA / ONE_MINUS_SRC_ALPHA)、开 GL_TEXTURE_2D

三重循环(86-90):

for (int x = bx - RADIUS; x <= bx + RADIUS; x++)
    for (int z = bz - RADIUS; z <= bz + RADIUS; z++)
        for (int y = by - HEIGHT; y <= by + HEIGHT; y++) {
            if (y < 0 || y > 255) continue;

⇒ 17 × 17 × 25 = 7225 格每帧遍历。

范围 值 循环边界
X bx ± 8 86
Z bz ± 8 87
Y by ± 12,并夹在 0–255 88-90

bx/by/bz 由 Math.floor(player.pos*) 取整(LightLevelOverlayRenderer.java:82-84)。

数字朝向

LightLevelOverlayRenderer.java:68-80:

float snapYaw;
if (LightOverlayConfig.DisableFollowNumber) {
    snapYaw = 180;
} else {
    float yaw = mc.renderViewEntity.rotationYaw;
    while (yaw < 0) yaw += 360;
    yaw = yaw % 360;
    if (yaw >= 315 || yaw < 45) snapYaw = 0;
    else if (yaw < 135) snapYaw = 270;
    else if (yaw < 225) snapYaw = 180;
    else snapYaw = 90;
}
DisableFollowNumber 行为
false(默认) 数字朝向跟随视角,但吸附到 4 个正方向(0/90/180/270)
true 数字固定朝 180(不跟随)

配置名 DisableFollowNumber 意为「禁用数字跟随」, 默认 false = 默认跟随。这是本 mod 少数「名字是 Disable 但默认是启用跟随」的配置。

生成判定 getSpawnMode(LightLevelOverlayRenderer.java:143)

供 MODE_CAN_SPAWN 使用。返回 byte,调用侧以 if (spawnMode == 0) continue; 过滤(LightLevelOverlayRenderer.java:104-106)。

源码用 getSpawnMode(world, x, y + 1, z)(104)—— 判定的是方块上方一格,符合原版「实体占据空间」的刷怪规则。

关联