地图扫描效果

玩家只要主物品栏里带着 Antique Atlas,就会持续被动地把周围群系写进地图。全部逻辑在 ItemAtlas.onUpdate,不需要手持、不需要右键。

效果信息

项目 值
效果名称 地图扫描
来源物品 antiqueatlas:antiqueAtlas(ItemStack 的 damage = atlasID)
触发条件 物品在玩家主物品栏内,Item.onUpdate 每 tick 调用;entity 必须是 EntityPlayer
触发频率 每 newScanInterval tick 一次,见下
作用范围 以玩家所在区块为圆心、半径 scanRadius 的圆形区域
数值 扫描半径 11 区块(默认),1 区块 = 16×16 格

触发时机

int newScanInterval  = Math.round(settings.newScanInterval * 20);   // 秒 → tick
int rescanInterval   = newScanInterval * settings.rescanRate;
if (player.ticksExisted % newScanInterval != 0) return;             // 不是间隔点,直接跳过

用 player.ticksExisted % interval == 0 做节流,所有玩家的间隔相位一致(都锚在 0 tick),所以同一 tick 内多人同时持有图册时会一起触发。

扫描范围

for (double dx = -scanRadius; dx <= scanRadius; dx++)
  for (double dz = -scanRadius; dz <= scanRadius; dz++) {
    if (dx*dx + dz*dz > scanRadius*scanRadius) continue;   // 圆外跳过
    int x = (int)(playerX + dx), z = (int)(playerZ + dz);

playerX/Z = floor(player.posX|posZ) >> 4,即玩家所在区块坐标。半径默认 11 时约 π × 11² ≈ 380 个区块每轮。

单格处理顺序

对范围内每个区块坐标 (x, z):

  1. 查 extBiomeData.getBiomeIdAt(player.dimension, x, z) 得 biomeId。
  2. biomeId != -1(有伪群系) → 直接 setTile,必要时 markDirty(),不查区块。注释:Custom tiles overwrite even the chunks already seen. 伪群系每轮都重写。
  3. biomeId == -1(无伪群系) → 取 worldObj.getChunkFromChunkCoords(x, z):
    • 若 settings.forceChunkLoading 且 !chunk.isChunkLoaded → chunkProvider.loadChunk(x << 4, z << 4)。
    • 若 !chunk.isChunkLoaded → continue(未加载,跳过)。
    • 该区块已有 tile(oldTile != null):
      • 若 !settings.doRescan 或 ticksExisted % rescanInterval != 0 → continue(本轮不重扫)。
      • 否则 biomeId = biomeDetector.getBiomeID(chunk);返回 NOT_FOUND 则 data.removeTile(...)(群系消失则抹掉),ID 不同才 setTile。
    • 该区块首次扫描:biomeId = getBiomeID(chunk),!= NOT_FOUND 才 setTile。

群系 ID 由按维度选出的 IBiomeDetector 给出,详见 群系检测。

数值

数值 配置项 默认 换算
扫描半径(区块) area_scan_radius 11 圆面积约 380 区块
新区块扫描间隔 area_scan_interval 1.0 秒 round(1.0 × 20) = 20 tick
完全重扫间隔 area_rescan_rate 4 20 × 4 = 80 tick = 4 秒
强制区块加载 force_chunk_loading false 开启会严重降性能
是否重扫 do_rescan true 关闭则已扫描区块永不更新
扫描小水塘 do_scan_ponds true 只影响主世界检测器

调大 area_scan_interval 或 area_rescan_rate 是主要的省性能手段——两者都只影响重新计算的频率,不影响首次发现新地块。

数据同步

扫描写入的是服务端数据,客户端靠两条机制拿到:

阶段 触发 封包
首次见到该玩家的该图册 !data.isSyncedOnPlayer(player) && !data.isEmpty() MapDataPacket + 每维度 TileGroupsPacket
此后每轮扫描 无显式推送 靠服务端后续的 TileGroupsPacket / PutBiomeTilePacket

playersSentTo 集合保证每本图册对每个玩家只全量同步一次。& !isEmpty() 前置条件意味着拿到全新空白图册时不会收到任何包。

与标记系统的关系

扫描只写群系地图(AtlasData),不写标记。标记由三个独立 watcher 产生,见 自动标记。

相关条目