com.yungnickyoung.minecraft.yungsapi.world.structure.YungJigsawStructure Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of YungsApi-1.21-Fabric Show documentation
Show all versions of YungsApi-1.21-Fabric Show documentation
A common API for YUNG's Minecraft mods
The newest version!
package com.yungnickyoung.minecraft.yungsapi.world.structure;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import com.yungnickyoung.minecraft.yungsapi.api.YungJigsawManager;
import com.yungnickyoung.minecraft.yungsapi.module.StructureTypeModule;
import com.yungnickyoung.minecraft.yungsapi.world.structure.terrainadaptation.EnhancedTerrainAdaptation;
import com.yungnickyoung.minecraft.yungsapi.world.structure.terrainadaptation.EnhancedTerrainAdaptationType;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
import net.minecraft.class_1923;
import net.minecraft.class_2338;
import net.minecraft.class_2902;
import net.minecraft.class_2960;
import net.minecraft.class_3195;
import net.minecraft.class_3341;
import net.minecraft.class_3785;
import net.minecraft.class_5819;
import net.minecraft.class_5847;
import net.minecraft.class_5868;
import net.minecraft.class_6016;
import net.minecraft.class_6017;
import net.minecraft.class_6122;
import net.minecraft.class_6880;
import net.minecraft.class_7151;
import net.minecraft.class_9778;
import net.minecraft.class_9822;
/**
* Enhanced jigsaw structure that uses the {@link YungJigsawManager} to assemble jigsaw structures.
*/
public class YungJigsawStructure extends class_3195 {
public static final int MAX_TOTAL_STRUCTURE_RADIUS = 128;
public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(builder -> builder
.group(
method_42697(builder),
class_3785.field_24954.fieldOf("start_pool").forGetter(structure -> structure.startPool),
class_2960.field_25139.optionalFieldOf("start_jigsaw_name").forGetter(structure -> structure.startJigsawName),
Codec.intRange(0, 128).fieldOf("size").forGetter(structure -> structure.maxDepth),
class_6122.field_31540.fieldOf("start_height").forGetter(structure -> structure.startHeight),
class_6017.method_35004(0, 15).optionalFieldOf("x_offset_in_chunk", class_6016.method_34998(0)).forGetter(structure -> structure.xOffsetInChunk),
class_6017.method_35004(0, 15).optionalFieldOf("z_offset_in_chunk", class_6016.method_34998(0)).forGetter(structure -> structure.zOffsetInChunk),
Codec.BOOL.optionalFieldOf("use_expansion_hack", false).forGetter(structure -> structure.useExpansionHack),
class_2902.class_2903.field_24772.optionalFieldOf("project_start_to_heightmap").forGetter(structure -> structure.projectStartToHeightmap),
Codec.intRange(1, MAX_TOTAL_STRUCTURE_RADIUS).fieldOf("max_distance_from_center").forGetter(structure -> structure.maxDistanceFromCenter),
Codec.INT.optionalFieldOf("max_y").forGetter(structure -> structure.maxY),
Codec.INT.optionalFieldOf("min_y").forGetter(structure -> structure.minY),
EnhancedTerrainAdaptationType.ADAPTATION_CODEC.optionalFieldOf("enhanced_terrain_adaptation", EnhancedTerrainAdaptation.NONE).forGetter(structure -> structure.enhancedTerrainAdaptation),
class_9778.field_51952.optionalFieldOf("dimension_padding", class_9778.field_51953).forGetter(structure -> structure.dimensionPadding),
class_9822.field_52239.optionalFieldOf("liquid_settings", class_9822.field_52238).forGetter(structure -> structure.liquidSettings))
.apply(builder, YungJigsawStructure::new))
.validate(YungJigsawStructure::validateRange);
/**
* The template pool to use for the starting piece.
*/
public final class_6880 startPool;
/**
* An optional resource location specifying the Name field of a jigsaw block in the starting pool.
* If specified, the position of a matching jigsaw block will be used as the structure's starting position
* when generating the structure. This will become the target position of the /locate command.
*/
private final Optional startJigsawName;
/**
* The max depth, in Jigsaw pieces, the structure can generate before stopping.
*/
public final int maxDepth;
/**
* Specifies the heights at which the structure can start generating.
*/
public final class_6122 startHeight;
/**
* The x offset, in blocks, from the chunk's starting corner position to the starting position of the structure.
*/
public final class_6017 xOffsetInChunk;
/**
* The z offset, in blocks, from the chunk's starting corner position to the starting position of the structure.
*/
public final class_6017 zOffsetInChunk;
/**
* Whether boundary adjustments should be performed on this structure.
* In vanilla, only villages and pillager outposts have this enabled.
* I recommend avoiding this, as it can cause weird issues if you don't know what you're doing.
*/
public final boolean useExpansionHack;
/**
* Heightmap to use for determining starting y-position. If provided, the startPos
* y-coordinate acts as an offset to this heightmap; otherwise, the startPos
* y-coordinate is an absolute world coordinate.
*/
public final Optional projectStartToHeightmap;
/**
* The radius of the maximum bounding box for the structure. Typical is 80,
* but can be increased if your structure is particularly large.
*/
public final int maxDistanceFromCenter;
/**
* Optional integer for specifying the max possible y-value of the structure.
* If provided, no pieces of the structure will generate above this value.
* If not provided, no max y-value will be enforced.
* This is useful for structures that should only generate underground, for example.
* Note that this is not the same as the max height of the structure.
* The max height of the structure is determined by the max height of the pieces in the structure's pool,
* and the ways in which they can be placed.
*/
public final Optional maxY;
/**
* Optional integer for specifying the min possible y-value of the structure.
* If provided, no pieces of the structure will generate below this value.
* If not provided, no min y-value will be enforced.
*/
public final Optional minY;
/**
* The enhanced terrain adaptation to use for this structure.
* This allows structures to guarantee that terrain is generated in a certain way around them.
* For example, ancient cities use this to ensure there is natural terrain below the city, and
* air carved out above the city's ground level.
* See {@link EnhancedTerrainAdaptation} and {@link EnhancedTerrainAdaptationType} for more information.
*/
public final EnhancedTerrainAdaptation enhancedTerrainAdaptation;
/**
* Dimension padding for the structure. Same as vanilla.
* Usually not necessary since we have the maxY and minY fields.
*/
private final class_9778 dimensionPadding;
/**
* Liquid settings for the structure. Same as vanilla.
* Can be overridden on a piece-by-piece basis.
*/
private final class_9822 liquidSettings;
public YungJigsawStructure(
class_7302 structureSettings,
class_6880 startPool,
Optional startJigsawName,
int maxDepth,
class_6122 startHeight,
class_6017 xOffsetInChunk,
class_6017 zOffsetInChunk,
boolean useExpansionHack,
Optional projectStartToHeightmap,
int maxBlockDistanceFromCenter,
Optional maxY,
Optional minY,
EnhancedTerrainAdaptation enhancedTerrainAdaptation,
class_9778 dimensionPadding,
class_9822 liquidSettings
) {
super(structureSettings);
this.startPool = startPool;
this.startJigsawName = startJigsawName;
this.maxDepth = maxDepth;
this.startHeight = startHeight;
this.xOffsetInChunk = xOffsetInChunk;
this.zOffsetInChunk = zOffsetInChunk;
this.useExpansionHack = useExpansionHack;
this.projectStartToHeightmap = projectStartToHeightmap;
this.maxDistanceFromCenter = maxBlockDistanceFromCenter;
this.maxY = maxY;
this.minY = minY;
this.enhancedTerrainAdaptation = enhancedTerrainAdaptation;
this.dimensionPadding = dimensionPadding;
this.liquidSettings = liquidSettings;
}
private static DataResult validateRange(YungJigsawStructure structure) {
if (structure.method_42701() != class_5847.field_28922 && structure.enhancedTerrainAdaptation != EnhancedTerrainAdaptation.NONE) {
return DataResult.error(() -> "YUNG Structure cannot use both vanilla terrain_adaptation and enhanced_terrain_adaptation");
}
// Vanilla boundary check
int vanillaEdgeBuffer = switch (structure.method_42701()) {
case field_28922 -> 0;
case field_28923, field_38431, field_38432, field_51413 -> 12;
};
if (structure.maxDistanceFromCenter + vanillaEdgeBuffer > 128) {
return DataResult.error(() -> "YUNG Structure size including terrain adaptation must not exceed 128");
}
// Enhanced boundary check.
// Note that it's still possible to have structure overflow issues if one of the structure's pieces
// has its own enhanced_terrain_adaptation with an even bigger kernel radius than that of the
// rest of the structure!
int enhancedEdgeBuffer = structure.enhancedTerrainAdaptation.getKernelRadius();
return structure.maxDistanceFromCenter + enhancedEdgeBuffer > 128
? DataResult.error(() -> "YUNG Structure size including enhanced terrain adaptation must not exceed 128")
: DataResult.success(structure);
}
@Override
public @NotNull Optional method_38676(class_7149 context) {
class_1923 chunkPos = context.comp_568();
class_5819 randomSource = context.comp_566();
int xOffset = this.xOffsetInChunk.method_35008(randomSource);
int zOffset = this.zOffsetInChunk.method_35008(randomSource);
int startY = this.startHeight.method_35391(context.comp_566(), new class_5868(context.comp_562(), context.comp_569()));
class_2338 startPos = new class_2338(chunkPos.method_33939(xOffset), startY, chunkPos.method_33941(zOffset));
return YungJigsawManager.assembleJigsawStructure(
context,
this.startPool,
this.startJigsawName,
this.maxDepth,
startPos,
this.useExpansionHack,
this.projectStartToHeightmap,
this.maxDistanceFromCenter,
this.maxY,
this.minY,
this.dimensionPadding,
this.liquidSettings
);
}
@Override
public @NotNull class_3341 method_41609(@NotNull class_3341 boundingBox) {
return super.method_41609(boundingBox)
.method_35410(this.enhancedTerrainAdaptation.getKernelRadius());
}
@Override
public @NotNull class_7151> method_41618() {
return StructureTypeModule.YUNG_JIGSAW;
}
}