Minecraft 1.12.2中,即使生成算法改变,末影之眼仍指向最近的末地堡

这是一篇《Minecraft攻略日记》。

环境

    • Minecraft 1.12.2 Java Edition

 

    forgeSrc-1.12.2-14.23.4.2705

背景 -在《Minecraft》的陆地世界中,存在着通向末地要塞(Stronghold)的地方。

    https://minecraft-ja.gamepedia.com/%E8%A6%81%E5%A1%9E

只有在世界上特定的地点才能找到它,必须投掷末影之眼进行探寻和攻略。末影之眼会飞向最近的末地遗迹。


好的,1.9版本更新时,终点要塞的数量从之前的3个增加到了128个。而且这些要塞似乎被配置在一个环状区域的电子壳中,每个壳一定有特定数量的要塞。

在世界的中心点周围以大致相等的角度生成了堡垒(例如,在一个由3个堡垒组成的环上,每个堡垒与其他堡垒的夹角约为120度,从起点开始计算)。这意味着堡垒的位置大致上是等距离的。


在下面的网站图中,图形之间不仅间隔不相等,而且角度也是不规律的。

    ジ・エンドに行くために、エンドポータル(要塞)を簡単に見つけるコツを解説 http://chanhino.com/minecraft-end-portal/
我个人想象[需要验证],这是将每个环均匀地分成n个部分,并在每个部分的某个地方生成要塞的情况。

请表达这个疑问的中文近义词嗯,不过这里有一个问题。Ender Eye 是指最近的(距离上最短的)遗迹呢?还是指投掷坐标所属方块中的遗迹呢?

从处理上来看,显然后者更容易。将坐标转换为棋子位置并转化为要塞坐标即可求得。如果选择前者,至少需要了解周围数个要塞的情况。

此外,在英文版维基百科中写着要飞往最近的大本营。

    Eye of Ender https://minecraft.gamepedia.com/Eye_of_Ender

调查
为了解决这个谜团,我调查了末影之眼的右键点击处理方法(net.minecraft.item.ItemEnderEye.onItemRightClick)。在那里,他们使用以下代码来获取坐标。

BlockPos blockpos = ((WorldServer)worldIn).getChunkProvider().getNearestStructurePos(worldIn, "Stronghold", new BlockPos(playerIn), false);

似乎要计算要塞的坐标,需要通过一个返回“最接近的建筑物坐标”的函数指定要塞并进行获取,而不是在物品的事件中写明。通过以下的方法,成功到达了目的地。

    • net.minecraft.world.gen.ChunkProviderServer.getNearestStructurePos

 

    net.minecraft.world.gen.ChunkGeneratorOverworld.getNearestStructurePos

这个方法net.minecraft.world.gen.structure.MapGenStronghold.getNearestStructurePos以及它的附属方法将返回最近的终点要塞的位置。

public BlockPos getNearestStructurePos(World worldIn, BlockPos pos, boolean findUnexplored)
{
    if (!this.ranBiomeCheck) {
        this.generatePositions();
        this.ranBiomeCheck = true;
    }

    BlockPos blockpos = null;
    BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(0, 0, 0);
    double d0 = Double.MAX_VALUE;

    for (ChunkPos chunkpos : this.structureCoords) {
        blockpos$mutableblockpos.setPos((chunkpos.x << 4) + 8, 32, (chunkpos.z << 4) + 8);
        double d1 = blockpos$mutableblockpos.distanceSq(pos);

        if (blockpos == null) {
            blockpos = new BlockPos(blockpos$mutableblockpos);
            d0 = d1;
        } else if (d1 < d0) {
            blockpos = new BlockPos(blockpos$mutableblockpos);
            d0 = d1;
        }
    }

    return blockpos;
}

private void generatePositions()
{
    this.initializeStructureData(this.world);
    int i = 0;
    ObjectIterator lvt_2_1_ = this.structureMap.values().iterator();

    while (lvt_2_1_.hasNext()) {
        StructureStart structurestart = (StructureStart) lvt_2_1_.next();

        if (i < this.structureCoords.length) {
            this.structureCoords[i++] = new ChunkPos(structurestart.getChunkPosX(), structurestart.getChunkPosZ());
        }
    }

    Random random = new Random();
    random.setSeed(this.world.getSeed());
    double d1 = random.nextDouble() * Math.PI * 2.0D;
    int j = 0;
    int k = 0;
    int l = this.structureMap.size();

    if (l < this.structureCoords.length) {
        for (int i1 = 0; i1 < this.structureCoords.length; ++i1) {
            double d0 = 4.0D * this.distance + this.distance * (double) j * 6.0D + (random.nextDouble() - 0.5D) * this.distance * 2.5D;
            int j1 = (int) Math.round(Math.cos(d1) * d0);
            int k1 = (int) Math.round(Math.sin(d1) * d0);
            BlockPos blockpos = this.world.getBiomeProvider().findBiomePosition((j1 << 4) + 8, (k1 << 4) + 8, 112, this.allowedBiomes, random);

            if (blockpos != null) {
                j1 = blockpos.getX() >> 4;
                k1 = blockpos.getZ() >> 4;
            }

            if (i1 >= l) {
                this.structureCoords[i1] = new ChunkPos(j1, k1);
            }

            d1 += (Math.PI * 2D) / (double) this.spread;
            ++k;

            if (k == this.spread) {
                ++j;
                k = 0;
                this.spread += 2 * this.spread / (j + 1);
                this.spread = Math.min(this.spread, this.structureCoords.length - i1);
                d1 += random.nextDouble() * Math.PI * 2.0D;
            }
        }
    }
}

这个结构坐标(structureCoords)是一个由128个元素组成的数组,其中存储了要塞的坐标序列。当我们在未初始化的状态下访问要塞坐标时,才会首次执行计算处理(generatePositions)操作。根据看到的getNearestStructurePos函数,明显是在获取最近的要塞坐标。

关于要塞坐标的确定部分,本次不会进行(可能会在之后做,所以把代码备份作为参考资料)。

结果-
安德拉之眼指的是距离最近的所有末地要塞,其中包括未生成的要塞。

bannerAds