地图扫描效果
玩家只要主物品栏里带着 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):
- 查
extBiomeData.getBiomeIdAt(player.dimension, x, z)得biomeId。 biomeId != -1(有伪群系) → 直接setTile,必要时markDirty(),不查区块。注释:Custom tiles overwrite even the chunks already seen. 伪群系每轮都重写。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 产生,见 自动标记。
相关条目
- Antique Atlas - 效果的来源物品
- 空白 Antique Atlas - 新图册要先右键建出浏览位置
- 群系检测 - 每格颜色怎么算
- 地图数据模型 - 扫描结果存哪
- 网络消息 - 扫描结果怎么同步到客户端
- SettingsConfig - 6 个 Performance 选项