Converted Default Structures
This commit is contained in:
parent
38f337cd15
commit
aede1b6f2b
5 changed files with 136 additions and 176 deletions
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue