Minecraft 1.12.2 생성 알고리즘이 바뀌어도 엔더아이는 가장 거리가 가까운 엔드 요새를 가리킨다

19517 단어 minecraft
Minecraft 공략 일기입니다.

환경


  • Minecraft 1.12.2 Java Edition
  • forgeSrc-1.12.2-14.23.4.2705

  • 배경



    Minecraft의 지상 세계에는 엔드로의 요새(Stronghold)가 존재한다.
  • h tps : // 미네 c 등 ft 그럼. 가메페아. 이 m / % 8 % A 6 % 81 % E 5 % A 1 % 9 E

  • 이것은 세계에 한정된 곳에만 존재하고 공략하기 위해서는 엔더아이를 던져 찾아야 한다. 엔더아이는 가장 가까운 엔드 유적을 향해 날아간다.

    그런데, 엔드 요새의 개수는 버전 1.9의 갱신시에, 이전의 3개소로부터 128개소로 늘어났다. 그리고 그 요새는 링 모양의 영역에 특정 개수씩 배치되어 있는 것 같은 전자 껍질.



    그래서 그 안에 The strongholds are generated at roughly equal angles from the center point of the world (for instance, each stronghold in a ring of 3 is in the region of 120 degrees from the others, measured from the origin). 라는 문장으로 설명되는 배치로 요새가 존재한다고 한다. 즉 대체로 등간격이라는 것이다.

    한편, 이하의 사이트의 도면에서는 등간격이 아니라 각도도 편차에 존재하고 있다.
  • 엔드 포털 (요새)을 쉽게 찾는 팁을 설명하십시오.

  • h tp // 찬 히노. 코 m / 미네 c 등 ft-en d-po rta l /

    이것은 각 링을 균등하게 n개의 조각으로 나누고, 각 조각의 어딘가에 요새가 스폰한다는 것일까, 나는 마음대로 상상하고 있다[요검증].

    의문



    글쎄 그것은 그렇게 여기에 하나의 문제가 나온다. 엔더아이는 가장 가까운 (거리적으로 가장 짧은) 유적을 가리키는가? 아니면 던진 좌표가 소속된 조각에 있는 유적을 가리키는가?

    처리상은 분명히 후자 쪽이 즐거울 것 같다. 좌표를 피스 위치로 변환하여 요새 좌표로 하면 구한다. 전자라면 적어도 주변의 요새를 몇 개 알아야 한다.

    덧붙여 영어판 Wiki에서는 the nearest stronghold에 날아간다고 쓰고 있다.
  • 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;
                }
            }
        }
    }
    
    this.structureCoords는 128 요소의 배열이며 요새 좌표 열을 포함합니다. 초기화되지 않은 상태에서 요새의 좌표에 액세스했을 때 처음으로 계산 처리 generatePositions getNearestStructurePos 를 보면, 어떻게 봐도 가장 가까운 요새를 취득하고 있는 것처럼 보인다.

    요새의 좌표 결정 부분에 대해서는 이번은 실시하지 않는다(나중에 할지도 모르기 때문에 자료로서 코드를 둥글게 해 둔다).

    결과



    엔더아이는 미생물을 포함한 월드의 모든 엔드 요새 중에서 가장 거리적으로 가까운 것을 말한다.

    좋은 웹페이지 즐겨찾기