All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yungnickyoung.minecraft.yungsapi.world.structure.YungJigsawStructure Maven / Gradle / Ivy

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;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy