Minecraft 1.12.2 생성 알고리즘이 바뀌어도 엔더아이는 가장 거리가 가까운 엔드 요새를 가리킨다
19517 단어 minecraft
환경
배경
Minecraft의 지상 세계에는 엔드로의 요새(Stronghold)가 존재한다.
이것은 세계에 한정된 곳에만 존재하고 공략하기 위해서는 엔더아이를 던져 찾아야 한다. 엔더아이는 가장 가까운 엔드 유적을 향해 날아간다.
그런데, 엔드 요새의 개수는 버전 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
에 날아간다고 쓰고 있다.
조사
그 수수께끼를 규명하기 위해서, 엔더아이의 우클릭 처리( net.minecraft.item.ItemEnderEye.onItemRightClick
)를 조사했다. 거기에서는 다음과 같은 코드로 좌표를 취득하고 있었다.
BlockPos blockpos = ((WorldServer)worldIn).getChunkProvider().getNearestStructurePos(worldIn, "Stronghold", new BlockPos(playerIn), false);
요새의 좌표의 계산은 아이템의 이벤트에 쓰여지는 것이 아니라 「가장 가까운 구조물의 좌표」를 돌려주는 함수에 요새를 지정해 취득하는 것 같다. 다음 방법을 통해 목적지에 도착했다.
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
를 보면, 어떻게 봐도 가장 가까운 요새를 취득하고 있는 것처럼 보인다.요새의 좌표 결정 부분에 대해서는 이번은 실시하지 않는다(나중에 할지도 모르기 때문에 자료로서 코드를 둥글게 해 둔다).
결과
엔더아이는 미생물을 포함한 월드의 모든 엔드 요새 중에서 가장 거리적으로 가까운 것을 말한다.
Reference
이 문제에 관하여(Minecraft 1.12.2 생성 알고리즘이 바뀌어도 엔더아이는 가장 거리가 가까운 엔드 요새를 가리킨다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/MirrgieRiana/items/32b6588ee5358887983a
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Minecraft 1.12.2 생성 알고리즘이 바뀌어도 엔더아이는 가장 거리가 가까운 엔드 요새를 가리킨다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/MirrgieRiana/items/32b6588ee5358887983a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)