170 lines
9.4 KiB
Java
170 lines
9.4 KiB
Java
package net.minecraft.world.level.levelgen.structure.structures;
|
|
|
|
import java.util.Map;
|
|
import net.minecraft.Util;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Vec3i;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.resources.ResourceKey;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.util.RandomSource;
|
|
import net.minecraft.world.RandomizableContainer;
|
|
import net.minecraft.world.level.ChunkPos;
|
|
import net.minecraft.world.level.ServerLevelAccessor;
|
|
import net.minecraft.world.level.StructureManager;
|
|
import net.minecraft.world.level.WorldGenLevel;
|
|
import net.minecraft.world.level.block.Mirror;
|
|
import net.minecraft.world.level.block.Rotation;
|
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
|
import net.minecraft.world.level.levelgen.Heightmap;
|
|
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
|
import net.minecraft.world.level.levelgen.structure.StructurePieceAccessor;
|
|
import net.minecraft.world.level.levelgen.structure.TemplateStructurePiece;
|
|
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
|
|
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceType;
|
|
import net.minecraft.world.level.levelgen.structure.templatesystem.BlockIgnoreProcessor;
|
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
|
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
|
import net.minecraft.world.level.storage.loot.BuiltInLootTables;
|
|
import net.minecraft.world.level.storage.loot.LootTable;
|
|
|
|
public class ShipwreckPieces {
|
|
private static final int NUMBER_OF_BLOCKS_ALLOWED_IN_WORLD_GEN_REGION = 32;
|
|
static final BlockPos PIVOT = new BlockPos(4, 0, 15);
|
|
private static final ResourceLocation[] STRUCTURE_LOCATION_BEACHED = new ResourceLocation[]{
|
|
ResourceLocation.withDefaultNamespace("shipwreck/with_mast"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/sideways_full"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/sideways_fronthalf"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/sideways_backhalf"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/rightsideup_full"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/rightsideup_fronthalf"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/rightsideup_backhalf"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/with_mast_degraded"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/rightsideup_full_degraded"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/rightsideup_fronthalf_degraded"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/rightsideup_backhalf_degraded")
|
|
};
|
|
private static final ResourceLocation[] STRUCTURE_LOCATION_OCEAN = new ResourceLocation[]{
|
|
ResourceLocation.withDefaultNamespace("shipwreck/with_mast"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/upsidedown_full"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/upsidedown_fronthalf"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/upsidedown_backhalf"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/sideways_full"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/sideways_fronthalf"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/sideways_backhalf"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/rightsideup_full"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/rightsideup_fronthalf"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/rightsideup_backhalf"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/with_mast_degraded"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/upsidedown_full_degraded"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/upsidedown_fronthalf_degraded"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/upsidedown_backhalf_degraded"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/sideways_full_degraded"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/sideways_fronthalf_degraded"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/sideways_backhalf_degraded"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/rightsideup_full_degraded"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/rightsideup_fronthalf_degraded"),
|
|
ResourceLocation.withDefaultNamespace("shipwreck/rightsideup_backhalf_degraded")
|
|
};
|
|
static final Map<String, ResourceKey<LootTable>> MARKERS_TO_LOOT = Map.of(
|
|
"map_chest", BuiltInLootTables.SHIPWRECK_MAP, "treasure_chest", BuiltInLootTables.SHIPWRECK_TREASURE, "supply_chest", BuiltInLootTables.SHIPWRECK_SUPPLY
|
|
);
|
|
|
|
public static ShipwreckPieces.ShipwreckPiece addRandomPiece(
|
|
StructureTemplateManager p_334187_, BlockPos p_334016_, Rotation p_333925_, StructurePieceAccessor p_330683_, RandomSource p_331305_, boolean p_332987_
|
|
) {
|
|
ResourceLocation resourcelocation = Util.getRandom(p_332987_ ? STRUCTURE_LOCATION_BEACHED : STRUCTURE_LOCATION_OCEAN, p_331305_);
|
|
ShipwreckPieces.ShipwreckPiece shipwreckpieces$shipwreckpiece = new ShipwreckPieces.ShipwreckPiece(
|
|
p_334187_, resourcelocation, p_334016_, p_333925_, p_332987_
|
|
);
|
|
p_330683_.addPiece(shipwreckpieces$shipwreckpiece);
|
|
return shipwreckpieces$shipwreckpiece;
|
|
}
|
|
|
|
public static class ShipwreckPiece extends TemplateStructurePiece {
|
|
private final boolean isBeached;
|
|
|
|
public ShipwreckPiece(StructureTemplateManager p_229354_, ResourceLocation p_229355_, BlockPos p_229356_, Rotation p_229357_, boolean p_229358_) {
|
|
super(StructurePieceType.SHIPWRECK_PIECE, 0, p_229354_, p_229355_, p_229355_.toString(), makeSettings(p_229357_), p_229356_);
|
|
this.isBeached = p_229358_;
|
|
}
|
|
|
|
public ShipwreckPiece(StructureTemplateManager p_229360_, CompoundTag p_229361_) {
|
|
super(StructurePieceType.SHIPWRECK_PIECE, p_229361_, p_229360_, p_391081_ -> makeSettings(p_229361_.read("Rot", Rotation.LEGACY_CODEC).orElseThrow()));
|
|
this.isBeached = p_229361_.getBooleanOr("isBeached", false);
|
|
}
|
|
|
|
@Override
|
|
protected void addAdditionalSaveData(StructurePieceSerializationContext p_229373_, CompoundTag p_229374_) {
|
|
super.addAdditionalSaveData(p_229373_, p_229374_);
|
|
p_229374_.putBoolean("isBeached", this.isBeached);
|
|
p_229374_.store("Rot", Rotation.LEGACY_CODEC, this.placeSettings.getRotation());
|
|
}
|
|
|
|
private static StructurePlaceSettings makeSettings(Rotation p_229371_) {
|
|
return new StructurePlaceSettings()
|
|
.setRotation(p_229371_)
|
|
.setMirror(Mirror.NONE)
|
|
.setRotationPivot(ShipwreckPieces.PIVOT)
|
|
.addProcessor(BlockIgnoreProcessor.STRUCTURE_AND_AIR);
|
|
}
|
|
|
|
@Override
|
|
protected void handleDataMarker(String p_229376_, BlockPos p_229377_, ServerLevelAccessor p_229378_, RandomSource p_229379_, BoundingBox p_229380_) {
|
|
ResourceKey<LootTable> resourcekey = ShipwreckPieces.MARKERS_TO_LOOT.get(p_229376_);
|
|
if (resourcekey != null) {
|
|
RandomizableContainer.setBlockEntityLootTable(p_229378_, p_229379_, p_229377_.below(), resourcekey);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void postProcess(
|
|
WorldGenLevel p_229363_,
|
|
StructureManager p_229364_,
|
|
ChunkGenerator p_229365_,
|
|
RandomSource p_229366_,
|
|
BoundingBox p_229367_,
|
|
ChunkPos p_229368_,
|
|
BlockPos p_229369_
|
|
) {
|
|
if (this.isTooBigToFitInWorldGenRegion()) {
|
|
super.postProcess(p_229363_, p_229364_, p_229365_, p_229366_, p_229367_, p_229368_, p_229369_);
|
|
} else {
|
|
int i = p_229363_.getMaxY() + 1;
|
|
int j = 0;
|
|
Vec3i vec3i = this.template.getSize();
|
|
Heightmap.Types heightmap$types = this.isBeached ? Heightmap.Types.WORLD_SURFACE_WG : Heightmap.Types.OCEAN_FLOOR_WG;
|
|
int k = vec3i.getX() * vec3i.getZ();
|
|
if (k == 0) {
|
|
j = p_229363_.getHeight(heightmap$types, this.templatePosition.getX(), this.templatePosition.getZ());
|
|
} else {
|
|
BlockPos blockpos = this.templatePosition.offset(vec3i.getX() - 1, 0, vec3i.getZ() - 1);
|
|
|
|
for (BlockPos blockpos1 : BlockPos.betweenClosed(this.templatePosition, blockpos)) {
|
|
int l = p_229363_.getHeight(heightmap$types, blockpos1.getX(), blockpos1.getZ());
|
|
j += l;
|
|
i = Math.min(i, l);
|
|
}
|
|
|
|
j /= k;
|
|
}
|
|
|
|
this.adjustPositionHeight(this.isBeached ? this.calculateBeachedPosition(i, p_229366_) : j);
|
|
super.postProcess(p_229363_, p_229364_, p_229365_, p_229366_, p_229367_, p_229368_, p_229369_);
|
|
}
|
|
}
|
|
|
|
public boolean isTooBigToFitInWorldGenRegion() {
|
|
Vec3i vec3i = this.template.getSize();
|
|
return vec3i.getX() > 32 || vec3i.getY() > 32;
|
|
}
|
|
|
|
public int calculateBeachedPosition(int p_332021_, RandomSource p_332823_) {
|
|
return p_332021_ - this.template.getSize().getY() / 2 - p_332823_.nextInt(3);
|
|
}
|
|
|
|
public void adjustPositionHeight(int p_331508_) {
|
|
this.templatePosition = new BlockPos(this.templatePosition.getX(), p_331508_, this.templatePosition.getZ());
|
|
}
|
|
}
|
|
} |