Started TemplateStructure class
This commit is contained in:
parent
95434107ec
commit
9ac0d78d30
8 changed files with 248 additions and 24 deletions
|
@ -29,6 +29,7 @@ import org.betterx.bclib.world.processors.DestructionStructureProcessor;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
//TODO: 1.19 Check if we can merge this with the new TemplateFeature!
|
||||
public abstract class NBTFeature extends DefaultFeature {
|
||||
private final BlockState defaultBlock;
|
||||
|
||||
|
|
|
@ -39,7 +39,11 @@ public abstract class SurfaceFeature<T extends FeatureConfiguration> extends Fea
|
|||
if (pos.isPresent()) {
|
||||
int y2 = ctx.level().getHeight(Heightmap.Types.WORLD_SURFACE_WG, ctx.origin().getX(), ctx.origin().getZ());
|
||||
int y3 = ctx.level().getHeight(Heightmap.Types.WORLD_SURFACE, ctx.origin().getX(), ctx.origin().getZ());
|
||||
System.out.println("Surfaces:" + pos.get().getY() + ", " + y2 + ", " + y3 + ", " + ctx.origin().getY());
|
||||
int y4 = ctx.level().getHeight(Heightmap.Types.OCEAN_FLOOR, ctx.origin().getX(), ctx.origin().getZ());
|
||||
int y5 = ctx.level().getHeight(Heightmap.Types.OCEAN_FLOOR_WG, ctx.origin().getX(), ctx.origin().getZ());
|
||||
System.out.println("Surfaces:" + pos
|
||||
.get()
|
||||
.getY() + ", " + y2 + ", " + y3 + ", " + y4 + ", " + y5 + ", " + ctx.origin().getY());
|
||||
|
||||
generate(pos.get(), ctx);
|
||||
return true;
|
||||
|
|
|
@ -40,6 +40,6 @@ public class TemplateFeature<FC extends TemplateFeatureConfig> extends Feature<F
|
|||
|
||||
@Override
|
||||
public boolean place(FeaturePlaceContext<FC> ctx) {
|
||||
return ctx.config().structure.generate(ctx.level(), ctx.origin(), ctx.random());
|
||||
return ctx.config().structure.generateInRandomOrientation(ctx.level(), ctx.origin(), ctx.random());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,6 @@ public class TemplateFeatureConfig implements FeatureConfiguration {
|
|||
public final StructureWorldNBT structure;
|
||||
|
||||
public TemplateFeatureConfig(ResourceLocation location, int offsetY, StructurePlacementType type) {
|
||||
structure = new StructureWorldNBT(location, offsetY, type);
|
||||
structure = StructureWorldNBT.create(location, offsetY, type);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,10 +16,12 @@ import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
|||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import org.betterx.bclib.BCLib;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
|
||||
public class StructureNBT {
|
||||
public final ResourceLocation location;
|
||||
|
@ -27,7 +29,7 @@ public class StructureNBT {
|
|||
protected Mirror mirror = Mirror.NONE;
|
||||
protected Rotation rotation = Rotation.NONE;
|
||||
|
||||
public StructureNBT(ResourceLocation location) {
|
||||
protected StructureNBT(ResourceLocation location) {
|
||||
this.location = location;
|
||||
this.structure = readStructureFromJar(location);
|
||||
}
|
||||
|
@ -37,6 +39,12 @@ public class StructureNBT {
|
|||
this.structure = structure;
|
||||
}
|
||||
|
||||
private static final Map<ResourceLocation, StructureNBT> STRUCTURE_CACHE = Maps.newHashMap();
|
||||
|
||||
public static StructureNBT create(ResourceLocation location) {
|
||||
return STRUCTURE_CACHE.computeIfAbsent(location, r -> new StructureNBT(r));
|
||||
}
|
||||
|
||||
public StructureNBT setRotation(Rotation rotation) {
|
||||
this.rotation = rotation;
|
||||
return this;
|
||||
|
@ -81,7 +89,13 @@ public class StructureNBT {
|
|||
return true;
|
||||
}
|
||||
|
||||
private static final Map<ResourceLocation, StructureTemplate> READER_CACHE = Maps.newHashMap();
|
||||
|
||||
private static StructureTemplate readStructureFromJar(ResourceLocation resource) {
|
||||
return READER_CACHE.computeIfAbsent(resource, r -> _readStructureFromJar(r));
|
||||
}
|
||||
|
||||
private static StructureTemplate _readStructureFromJar(ResourceLocation resource) {
|
||||
String ns = resource.getNamespace();
|
||||
String nm = resource.getPath();
|
||||
|
||||
|
|
|
@ -7,37 +7,53 @@ import net.minecraft.util.RandomSource;
|
|||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.ServerLevelAccessor;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import org.betterx.bclib.util.BlocksHelper;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class StructureWorldNBT extends StructureNBT {
|
||||
public final StructurePlacementType type;
|
||||
public final int offsetY;
|
||||
|
||||
public StructureWorldNBT(ResourceLocation location, int offsetY, StructurePlacementType type) {
|
||||
protected StructureWorldNBT(ResourceLocation location, int offsetY, StructurePlacementType type) {
|
||||
super(location);
|
||||
this.offsetY = offsetY;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
private static final Map<String, StructureWorldNBT> READER_CACHE = Maps.newHashMap();
|
||||
|
||||
public boolean generate(ServerLevelAccessor level, BlockPos pos, RandomSource random) {
|
||||
public static StructureWorldNBT create(ResourceLocation location, int offsetY, StructurePlacementType type) {
|
||||
String key = location.toString() + "::" + offsetY + "::" + type.getSerializedName();
|
||||
return READER_CACHE.computeIfAbsent(key, r -> new StructureWorldNBT(location, offsetY, type));
|
||||
}
|
||||
|
||||
|
||||
public boolean generateInRandomOrientation(ServerLevelAccessor level, BlockPos pos, RandomSource random) {
|
||||
randomRM(random);
|
||||
return generate(level, pos);
|
||||
}
|
||||
|
||||
public boolean generate(ServerLevelAccessor level, BlockPos pos) {
|
||||
if (canGenerate(level, pos)) {
|
||||
return generateCentered(level, pos.above(offsetY));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean canGenerate(LevelAccessor world, BlockPos pos) {
|
||||
protected boolean canGenerate(LevelAccessor level, BlockPos pos) {
|
||||
if (type == StructurePlacementType.FLOOR)
|
||||
return canGenerateFloor(world, pos);
|
||||
return canGenerateFloor(level, pos);
|
||||
else if (type == StructurePlacementType.LAVA)
|
||||
return canGenerateLava(world, pos);
|
||||
return canGenerateLava(level, pos);
|
||||
else if (type == StructurePlacementType.UNDER)
|
||||
return canGenerateUnder(world, pos);
|
||||
return canGenerateUnder(level, pos);
|
||||
else if (type == StructurePlacementType.CEIL)
|
||||
return canGenerateCeil(world, pos);
|
||||
return canGenerateCeil(level, pos);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
@ -75,16 +91,31 @@ public class StructureWorldNBT extends StructureNBT {
|
|||
return getAirFractionBottom(world, pos) > 0.8 && getAirFraction(world, pos) < 0.6;
|
||||
}
|
||||
|
||||
public BoundingBox boundingBox(Rotation r, BlockPos p) {
|
||||
MutableBlockPos size = new MutableBlockPos().set(new BlockPos(structure.getSize()).rotate(rotation));
|
||||
size.setX(Math.abs(size.getX()) >> 1);
|
||||
size.setY(Math.abs(size.getY()) >> 1);
|
||||
size.setZ(Math.abs(size.getZ()) >> 1);
|
||||
return new BoundingBox(
|
||||
p.getX() - size.getX(),
|
||||
p.getY() - size.getY(),
|
||||
p.getZ() - size.getZ(),
|
||||
p.getX() + size.getX(),
|
||||
p.getY() + size.getY(),
|
||||
p.getZ() + size.getZ()
|
||||
);
|
||||
}
|
||||
|
||||
protected float getAirFraction(LevelAccessor world, BlockPos pos) {
|
||||
final MutableBlockPos POS = new MutableBlockPos();
|
||||
int airCount = 0;
|
||||
|
||||
MutableBlockPos size = new MutableBlockPos().set(new BlockPos(structure.getSize()).rotate(rotation));
|
||||
size.setX(Math.abs(size.getX()));
|
||||
size.setZ(Math.abs(size.getZ()));
|
||||
size.setX(Math.abs(size.getX()) >> 1);
|
||||
size.setZ(Math.abs(size.getZ()) >> 1);
|
||||
|
||||
BlockPos start = pos.offset(-(size.getX() >> 1), 0, -(size.getZ() >> 1));
|
||||
BlockPos end = pos.offset(size.getX() >> 1, size.getY() + offsetY, size.getZ() >> 1);
|
||||
BlockPos start = pos.offset(-size.getX(), 0, -size.getZ());
|
||||
BlockPos end = pos.offset(size.getX(), size.getY() + offsetY, size.getZ());
|
||||
int count = 0;
|
||||
|
||||
for (int x = start.getX(); x <= end.getX(); x++) {
|
||||
|
@ -108,11 +139,11 @@ public class StructureWorldNBT extends StructureNBT {
|
|||
int lavaCount = 0;
|
||||
|
||||
MutableBlockPos size = new MutableBlockPos().set(new BlockPos(structure.getSize()).rotate(rotation));
|
||||
size.setX(Math.abs(size.getX()));
|
||||
size.setZ(Math.abs(size.getZ()));
|
||||
size.setX(Math.abs(size.getX()) >> 1);
|
||||
size.setZ(Math.abs(size.getZ()) >> 1);
|
||||
|
||||
BlockPos start = pos.offset(-(size.getX() >> 1), 0, -(size.getZ() >> 1));
|
||||
BlockPos end = pos.offset(size.getX() >> 1, 0, size.getZ() >> 1);
|
||||
BlockPos start = pos.offset(-(size.getX()), 0, -(size.getZ()));
|
||||
BlockPos end = pos.offset(size.getX(), 0, size.getZ());
|
||||
int count = 0;
|
||||
|
||||
POS.setY(pos.getY() - 1);
|
||||
|
@ -135,11 +166,11 @@ public class StructureWorldNBT extends StructureNBT {
|
|||
int airCount = 0;
|
||||
|
||||
MutableBlockPos size = new MutableBlockPos().set(new BlockPos(structure.getSize()).rotate(rotation));
|
||||
size.setX(Math.abs(size.getX()));
|
||||
size.setZ(Math.abs(size.getZ()));
|
||||
size.setX(Math.abs(size.getX()) >> 1);
|
||||
size.setZ(Math.abs(size.getZ()) >> 1);
|
||||
|
||||
BlockPos start = pos.offset(-(size.getX() >> 1), -1, -(size.getZ() >> 1));
|
||||
BlockPos end = pos.offset(size.getX() >> 1, 0, size.getZ() >> 1);
|
||||
BlockPos start = pos.offset(-(size.getX()), -1, -(size.getZ()));
|
||||
BlockPos end = pos.offset(size.getX(), 0, size.getZ());
|
||||
int count = 0;
|
||||
|
||||
for (int x = start.getX(); x <= end.getX(); x++) {
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
package org.betterx.bclib.world.structures;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
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.structure.BoundingBox;
|
||||
import net.minecraft.world.level.levelgen.structure.StructurePiece;
|
||||
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
|
||||
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceType;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
|
||||
public class TemplatePiece extends StructurePiece {
|
||||
public static final StructurePieceType INSTANCE = register("template_piece", TemplatePiece::new);
|
||||
|
||||
private static StructurePieceType register(String id, StructurePieceType pieceType) {
|
||||
return Registry.register(Registry.STRUCTURE_PIECE, BCLib.makeID(id), pieceType);
|
||||
}
|
||||
|
||||
public final StructureWorldNBT structure;
|
||||
public final BlockPos pos;
|
||||
public final Rotation rot;
|
||||
public final Mirror mir;
|
||||
|
||||
protected TemplatePiece(StructureWorldNBT structure,
|
||||
BlockPos pos,
|
||||
Rotation rot,
|
||||
Mirror mir) {
|
||||
super(INSTANCE, 0, structure.boundingBox(rot, pos));
|
||||
this.structure = structure;
|
||||
this.rot = rot;
|
||||
this.mir = mir;
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
public TemplatePiece(StructurePieceSerializationContext ctx, CompoundTag compoundTag) {
|
||||
super(INSTANCE, compoundTag);
|
||||
|
||||
ResourceLocation location = new ResourceLocation(compoundTag.getString("L"));
|
||||
int offsetY = compoundTag.getInt("OY");
|
||||
StructurePlacementType type = StructurePlacementType.valueOf(compoundTag.getString("T"));
|
||||
this.structure = new StructureWorldNBT(location, offsetY, type);
|
||||
|
||||
this.rot = Rotation.valueOf(compoundTag.getString("Rot"));
|
||||
this.mir = Mirror.valueOf(compoundTag.getString("Mir"));
|
||||
this.pos = new BlockPos(
|
||||
compoundTag.getInt("PX"),
|
||||
compoundTag.getInt("PY"),
|
||||
compoundTag.getInt("PZ")
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addAdditionalSaveData(StructurePieceSerializationContext structurePieceSerializationContext,
|
||||
CompoundTag tag) {
|
||||
|
||||
tag.putString("L", structure.location.toString());
|
||||
tag.putInt("OY", structure.offsetY);
|
||||
tag.putString("T", structure.type.getSerializedName());
|
||||
tag.putString("Rot", this.rot.name());
|
||||
tag.putString("Mir", this.mir.name());
|
||||
tag.putInt("PX", this.pos.getX());
|
||||
tag.putInt("PY", this.pos.getY());
|
||||
tag.putInt("PZ", this.pos.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcess(WorldGenLevel worldGenLevel,
|
||||
StructureManager structureManager,
|
||||
ChunkGenerator chunkGenerator,
|
||||
RandomSource randomSource,
|
||||
BoundingBox boundingBox,
|
||||
ChunkPos chunkPos,
|
||||
BlockPos blockPos) {
|
||||
structure.generateInRandomOrientation(worldGenLevel, blockPos, randomSource);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package org.betterx.bclib.world.structures;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.block.Mirror;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder;
|
||||
|
||||
import com.mojang.datafixers.util.Function4;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public abstract class TemplateStructure extends Structure {
|
||||
public static <T extends TemplateStructure> Codec<T> simpleCodec(Function4 instancer) {
|
||||
return RecordCodecBuilder.create((instance) -> instance
|
||||
.group(
|
||||
Structure.settingsCodec(instance),
|
||||
ResourceLocation.CODEC
|
||||
.fieldOf("location")
|
||||
.forGetter((T cfg) -> cfg.structure.location),
|
||||
|
||||
Codec
|
||||
.INT
|
||||
.fieldOf("offset_y")
|
||||
.orElse(0)
|
||||
.forGetter((T cfg) -> cfg.structure.offsetY),
|
||||
|
||||
StructurePlacementType.CODEC
|
||||
.fieldOf("placement")
|
||||
.orElse(StructurePlacementType.FLOOR)
|
||||
.forGetter((T cfg) -> cfg.structure.type)
|
||||
)
|
||||
.apply(instance, instancer)
|
||||
);
|
||||
}
|
||||
|
||||
public final StructureWorldNBT structure;
|
||||
|
||||
protected TemplateStructure(StructureSettings structureSettings,
|
||||
ResourceLocation location,
|
||||
int offsetY,
|
||||
StructurePlacementType type) {
|
||||
super(structureSettings);
|
||||
structure = StructureWorldNBT.create(location, offsetY, type);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Optional<GenerationStub> findGenerationPoint(GenerationContext ctx) {
|
||||
ChunkPos chunkPos = ctx.chunkPos();
|
||||
final int x = chunkPos.getMiddleBlockX();
|
||||
final int z = chunkPos.getMiddleBlockZ();
|
||||
int y = ctx
|
||||
.chunkGenerator()
|
||||
.getFirstOccupiedHeight(x,
|
||||
z,
|
||||
Heightmap.Types.WORLD_SURFACE_WG,
|
||||
ctx.heightAccessor(),
|
||||
ctx.randomState());
|
||||
|
||||
BlockPos centerPos = new BlockPos(x, y, z);
|
||||
Rotation rotation = Rotation.getRandom(ctx.random());
|
||||
BoundingBox bb = structure.boundingBox(rotation, centerPos);
|
||||
// if (!structure.canGenerate(ctx.chunkGenerator()., centerPos))
|
||||
return Optional.of(new GenerationStub(centerPos,
|
||||
structurePiecesBuilder -> this.generatePieces(structurePiecesBuilder, centerPos, rotation, ctx)));
|
||||
|
||||
}
|
||||
|
||||
private void generatePieces(StructurePiecesBuilder structurePiecesBuilder,
|
||||
BlockPos centerPos,
|
||||
Rotation rotation,
|
||||
Structure.GenerationContext generationContext) {
|
||||
WorldgenRandom worldgenRandom = generationContext.random();
|
||||
|
||||
Mirror mirror = Mirror.values()[worldgenRandom.nextInt(3)];
|
||||
|
||||
structurePiecesBuilder.addPiece(new TemplatePiece(structure, centerPos, rotation, mirror));
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue