Converted Default Structures

This commit is contained in:
Frank 2022-05-31 16:24:50 +02:00
parent 38f337cd15
commit aede1b6f2b
5 changed files with 136 additions and 176 deletions

View file

@ -65,6 +65,10 @@ public class TagAPI {
return BIOMES.makeTag(new ResourceLocation(modID, name));
}
public static TagKey<Biome> makeStructureTag(String modID, String name) {
return TagAPI.makeBiomeTag(modID, "has_structure/" + name);
}
/**
* Get or create {@link Block} {@link TagKey} with mod namespace.

View file

@ -78,10 +78,28 @@ public class BCLStructure<S extends Structure> {
int spacing,
int separation,
boolean adaptNoise) {
this(id,
structureBuilder,
step,
spacing,
separation,
adaptNoise,
Structure.simpleCodec(structureBuilder),
null);
}
public BCLStructure(ResourceLocation id,
Function<Structure.StructureSettings, S> structureBuilder,
GenerationStep.Decoration step,
int spacing,
int separation,
boolean adaptNoise,
Codec<S> codec,
TagKey<Biome> biomeTag) {
this.id = id;
this.featureStep = step;
this.STRUCTURE_CODEC = Structure.simpleCodec(structureBuilder);
this.STRUCTURE_CODEC = codec;
//parts from vanilla for Structure generation
//public static final ResourceKey<ConfiguredStructure<?, ?>> JUNGLE_TEMPLE =
// BuiltinStructures.createKey("jungle_pyramid");
@ -101,7 +119,9 @@ public class BCLStructure<S extends Structure> {
this.structureSetKey = ResourceKey.create(Registry.STRUCTURE_SET_REGISTRY, id);
this.structureType = registerStructureType(id, STRUCTURE_CODEC);
this.biomeTag = TagAPI.makeBiomeTag(id.getNamespace(), "has_structure/" + id.getPath());
this.biomeTag = biomeTag == null
? TagAPI.makeStructureTag(id.getNamespace(), id.getPath())
: biomeTag;
this.baseStructure = structureBuilder.apply(structure(biomeTag, featureStep, TerrainAdjustment.NONE));
this.structure = StructuresAccessor.callRegister(structureKey, this.baseStructure);
StructureSets.register(structureSetKey, this.structure, spreadConfig);

View file

@ -39,7 +39,7 @@ public class StructureNBT {
}
public static Rotation getRandomRotation(RandomSource random) {
return Rotation.getRandom(random) == Rotation.NONE ? Rotation.CLOCKWISE_90 : Rotation.COUNTERCLOCKWISE_90;
return Rotation.getRandom(random);
}
public static Mirror getRandomMirror(RandomSource random) {
@ -73,7 +73,7 @@ public class StructureNBT {
data,
world.getRandom(),
Block.UPDATE_CLIENTS
);
);
return true;
}

View file

@ -5,29 +5,23 @@ 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.ServerLevelAccessor;
import net.minecraft.world.level.StructureManager;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.Blocks;
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.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.StructureTemplate;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
import org.betterx.bclib.BCLib;
import org.betterx.bclib.util.BlocksHelper;
public class TemplatePiece extends TemplateStructurePiece {
public static final StructurePieceType INSTANCE = setTemplatePieceId(TemplatePiece::new,
"template_piece");
"template_piece");
private static StructurePieceType setFullContextPieceId(StructurePieceType structurePieceType, String id) {
@ -51,52 +45,31 @@ public class TemplatePiece extends TemplateStructurePiece {
Mirror mirror,
BlockPos halfSize) {
super(INSTANCE,
0,
structureTemplateManager,
resourceLocation,
resourceLocation.toString(),
makeSettings(rotation, mirror, halfSize),
shiftPos(halfSize, centerPos));
0,
structureTemplateManager,
resourceLocation,
resourceLocation.toString(),
makeSettings(rotation, mirror, halfSize),
shiftPos(rotation, mirror, halfSize, centerPos));
System.out.println("Piece: " + resourceLocation);
System.out.println(" - " + centerPos);
System.out.println(" - " + boundingBox);
System.out.println(" - " + templatePosition);
}
public TemplatePiece(StructureTemplateManager structureTemplateManager, CompoundTag compoundTag) {
super(INSTANCE,
compoundTag,
structureTemplateManager,
(ResourceLocation resourceLocation) -> makeSettings(compoundTag));
compoundTag,
structureTemplateManager,
(ResourceLocation resourceLocation) -> makeSettings(compoundTag));
}
@Override
public void postProcess(WorldGenLevel level,
StructureManager structureManager,
ChunkGenerator chunkGenerator,
RandomSource randomSource,
BoundingBox boundingBox,
ChunkPos chunkPos,
BlockPos blockPos) {
super.postProcess(level,
structureManager,
chunkGenerator,
randomSource,
boundingBox,
chunkPos,
blockPos);
BlocksHelper.setWithoutUpdate(level, new BlockPos(boundingBox.minX(), boundingBox.minY(), boundingBox.minZ()),
Blocks.YELLOW_CONCRETE);
BlocksHelper.setWithoutUpdate(level, new BlockPos(boundingBox.maxX(), boundingBox.maxY(), boundingBox.maxZ()),
Blocks.LIGHT_BLUE_CONCRETE);
BlocksHelper.setWithoutUpdate(level, boundingBox.getCenter(),
Blocks.LIME_CONCRETE);
BlocksHelper.setWithoutUpdate(level, blockPos,
Blocks.ORANGE_CONCRETE);
}
private static BlockPos shiftPos(BlockPos halfSize,
private static BlockPos shiftPos(Rotation rotation,
Mirror mirror,
BlockPos halfSize,
BlockPos pos) {
return pos.offset(-(2 * halfSize.getX()), 0, -(2 * halfSize.getZ()));
//return pos;
halfSize = StructureTemplate.transform(halfSize, mirror, rotation, halfSize);
return pos.offset(-halfSize.getX(), 0, -halfSize.getZ());
}
private static StructurePlaceSettings makeSettings(CompoundTag compoundTag) {
@ -134,72 +107,3 @@ public class TemplatePiece extends TemplateStructurePiece {
}
}
class TemplatePiece2 extends StructurePiece {
public static final StructurePieceType INSTANCE = register("template_piece_bcl", TemplatePiece2::new);
private static StructurePieceType register(String id, StructurePieceType pieceType) {
return Registry.register(Registry.STRUCTURE_PIECE, BCLib.makeID(id), pieceType);
}
public static void ensureStaticInitialization() {
}
public final StructureWorldNBT structure;
public final BlockPos pos;
public final Rotation rot;
public final Mirror mir;
protected TemplatePiece2(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 TemplatePiece2(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.name());
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.generate(worldGenLevel, this.pos, this.rot, this.mir);
}
}

View file

@ -21,22 +21,24 @@ import com.mojang.serialization.codecs.RecordCodecBuilder;
import java.util.List;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
public abstract class TemplateStructure extends Structure {
protected final List<Config> configs;
public static <T extends TemplateStructure> Codec<T> simpleCodec(BiFunction instancer) {
public static <T extends TemplateStructure> Codec<T> simpleTemplateCodec(BiFunction<StructureSettings, List<Config>, T> instancer) {
return RecordCodecBuilder.create((instance) -> instance
.group(
Structure.settingsCodec(instance),
ExtraCodecs.nonEmptyList(Config.CODEC.listOf())
.fieldOf("configs")
.forGetter((T ruinedPortalStructure) -> ruinedPortalStructure.configs)
)
.apply(instance, instancer)
);
.group(
Structure.settingsCodec(instance),
ExtraCodecs.nonEmptyList(Config.CODEC.listOf())
.fieldOf("configs")
.forGetter((T ruinedPortalStructure) -> ruinedPortalStructure.configs)
)
.apply(instance, instancer)
);
}
protected TemplateStructure(StructureSettings structureSettings,
ResourceLocation location,
int offsetY,
@ -68,54 +70,84 @@ public abstract class TemplateStructure extends Structure {
return null;
}
protected boolean isLavaPlaceable(BlockState state, BlockState before) {
return state.is(Blocks.AIR) && before.is(Blocks.LAVA);
}
protected boolean isFloorPlaceable(BlockState state, BlockState before) {
return state.is(Blocks.AIR) && before.getMaterial().isSolid();
}
@Override
public Optional<GenerationStub> findGenerationPoint(GenerationContext ctx) {
WorldGenerationContext worldGenerationContext = new WorldGenerationContext(ctx.chunkGenerator(),
ctx.heightAccessor());
ctx.heightAccessor());
final Config config = randomConfig(ctx.random());
if (config == null) return Optional.empty();
ChunkPos chunkPos = ctx.chunkPos();
final int x = chunkPos.getMiddleBlockX();
final int z = chunkPos.getMiddleBlockZ();
NoiseColumn column = ctx.chunkGenerator().getBaseColumn(x, z, ctx.heightAccessor(), ctx.randomState());
final int seaLevel = ctx.chunkGenerator().getSeaLevel();
StructureTemplate structureTemplate = ctx.structureTemplateManager().getOrCreate(config.location);
final int maxHeight = worldGenerationContext.getGenDepth() - 4 - (structureTemplate.getSize(Rotation.NONE)
.getY() + config.offsetY);
int y = seaLevel;
BlockState state = column.getBlock(y - 1);
for (; y < maxHeight; y++) {
BlockState below = state;
state = column.getBlock(y);
if (state.is(Blocks.AIR) && below.is(Blocks.LAVA)) break;
BiPredicate<BlockState, BlockState> isCorrectBase;
int searchStep;
if (config.type == StructurePlacementType.LAVA) {
isCorrectBase = this::isLavaPlaceable;
searchStep = 1;
} else if (config.type == StructurePlacementType.CEIL) {
isCorrectBase = this::isFloorPlaceable;
searchStep = -1;
} else {
isCorrectBase = this::isFloorPlaceable;
searchStep = 1;
}
if (y >= maxHeight) return Optional.empty();
final int seaLevel =
ctx.chunkGenerator().getSeaLevel()
+ (searchStep > 0 ? 0 : (structureTemplate.getSize(Rotation.NONE).getY() + config.offsetY));
final int maxHeight =
worldGenerationContext.getGenDepth()
- 4
- (searchStep > 0 ? (structureTemplate.getSize(Rotation.NONE).getY() + config.offsetY) : 0);
int y = searchStep > 0 ? seaLevel : maxHeight - 1;
BlockState state = column.getBlock(y - searchStep);
for (; y < maxHeight && y >= seaLevel; y += searchStep) {
BlockState before = state;
state = column.getBlock(y);
if (isCorrectBase.test(state, before)) break;
}
if (y >= maxHeight || y < seaLevel) return Optional.empty();
BlockPos halfSize = new BlockPos(structureTemplate.getSize().getX() / 2,
0,
structureTemplate.getSize().getZ() / 2);
0,
structureTemplate.getSize().getZ() / 2);
Rotation rotation = StructureNBT.getRandomRotation(ctx.random());
Mirror mirror = StructureNBT.getRandomMirror(ctx.random());
BlockPos centerPos = new BlockPos(x, y, z);
BlockPos centerPos = new BlockPos(x,
y - (searchStep == 1 ? 0 : (structureTemplate.getSize(Rotation.NONE).getY())),
z);
BoundingBox boundingBox = structureTemplate.getBoundingBox(centerPos, rotation, halfSize, mirror);
// if (!structure.canGenerate(ctx.chunkGenerator()., centerPos))
return Optional.of(new GenerationStub(centerPos,
structurePiecesBuilder ->
structurePiecesBuilder.addPiece(
new TemplatePiece(ctx.structureTemplateManager(),
config.location,
centerPos.offset(
0,
config.offsetY,
0),
rotation,
mirror,
halfSize))
structurePiecesBuilder ->
structurePiecesBuilder.addPiece(
new TemplatePiece(ctx.structureTemplateManager(),
config.location,
centerPos.offset(
0,
config.offsetY,
0),
rotation,
mirror,
halfSize))
));
}
@ -123,28 +155,28 @@ public abstract class TemplateStructure extends Structure {
public record Config(ResourceLocation location, int offsetY, StructurePlacementType type, float chance) {
public static final Codec<Config> CODEC =
RecordCodecBuilder.create((instance) ->
instance.group(
ResourceLocation.CODEC
.fieldOf("location")
.forGetter((cfg) -> cfg.location),
instance.group(
ResourceLocation.CODEC
.fieldOf("location")
.forGetter((cfg) -> cfg.location),
Codec
.INT
.fieldOf("offset_y")
.orElse(0)
.forGetter((cfg) -> cfg.offsetY),
Codec
.INT
.fieldOf("offset_y")
.orElse(0)
.forGetter((cfg) -> cfg.offsetY),
StructurePlacementType.CODEC
.fieldOf("placement")
.orElse(StructurePlacementType.FLOOR)
.forGetter((cfg) -> cfg.type),
Codec
.FLOAT
.fieldOf("chance")
.orElse(1.0f)
.forGetter((cfg) -> cfg.chance)
)
.apply(instance, Config::new)
);
StructurePlacementType.CODEC
.fieldOf("placement")
.orElse(StructurePlacementType.FLOOR)
.forGetter((cfg) -> cfg.type),
Codec
.FLOAT
.fieldOf("chance")
.orElse(1.0f)
.forGetter((cfg) -> cfg.chance)
)
.apply(instance, Config::new)
);
}
}