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

com.yungnickyoung.minecraft.yungsapi.world.structure.condition.PieceInRangeCondition Maven / Gradle / Ivy

The newest version!
package com.yungnickyoung.minecraft.yungsapi.world.structure.condition;

import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import com.yungnickyoung.minecraft.yungsapi.YungsApiCommon;
import com.yungnickyoung.minecraft.yungsapi.mixin.accessor.SinglePoolElementAccessor;
import com.yungnickyoung.minecraft.yungsapi.world.structure.context.StructureContext;
import com.yungnickyoung.minecraft.yungsapi.world.structure.jigsaw.PieceEntry;
import com.yungnickyoung.minecraft.yungsapi.world.structure.jigsaw.element.YungJigsawSinglePoolElement;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.class_2960;
import net.minecraft.class_3341;
import net.minecraft.class_3485;
import net.minecraft.class_3499;
import net.minecraft.class_3781;
import net.minecraft.class_3790;

/**
 * Searches a specified number of blocks from a given position and checks for a structure piece.
 * Passes if a structure piece is found matching one of the entries from the given list.
 * Note that "yungsapi:all" is an acceptable entry for matching any piece.
 */
public class PieceInRangeCondition extends StructureCondition {
    private static final class_2960 ALL = class_2960.method_60655(YungsApiCommon.MOD_ID, "all");

    public static final MapCodec CODEC = RecordCodecBuilder.mapCodec((builder) -> builder
            .group(
                    class_2960.field_25139.listOf().optionalFieldOf("pieces", new ArrayList<>()).forGetter(conditon -> conditon.matchPieces),
                    Codec.INT.optionalFieldOf("above_range", 0).forGetter(conditon -> conditon.aboveRange),
                    Codec.INT.optionalFieldOf("horizontal_range", 0).forGetter(conditon -> conditon.horizontalRange),
                    Codec.INT.optionalFieldOf("below_range", 0).forGetter(conditon -> conditon.belowRange))
            .apply(builder, PieceInRangeCondition::new));

    private final List matchPieces;

    private final Integer aboveRange;
    private final Integer horizontalRange;
    private final Integer belowRange;

    public PieceInRangeCondition(List pieces, int aboveRange, int horizontalRange, int belowRange) {
        this.matchPieces = pieces;
        this.aboveRange = aboveRange;
        this.horizontalRange = horizontalRange;
        this.belowRange = belowRange;
        if (matchPieces.isEmpty()) {
            matchPieces.add(ALL); // No pieces specified -> match all pieces
        }
    }

    @Override
    public StructureConditionType type() {
        return StructureConditionType.PIECE_IN_RANGE;
    }

    @Override
    public boolean passes(StructureContext ctx) {
        // Extract args from context
        class_3485 templateManager = ctx.structureTemplateManager();
        List pieces = ctx.pieces();
        PieceEntry pieceEntry = ctx.pieceEntry();

        // Abort if missing any args
        if (templateManager == null) YungsApiCommon.LOGGER.error("Missing required field 'structureTemplateManager' for piece_in_range condition!");
        if (pieces == null) YungsApiCommon.LOGGER.error("Missing required field 'pieces' for piece_in_range condition!");
        if (pieceEntry == null) YungsApiCommon.LOGGER.error("Missing required field 'pieceEntry' for piece_in_horizontal_direction condition!");
        if (templateManager == null || pieces == null || pieceEntry == null) return false;

        class_3790 piece = pieceEntry.getPiece();
        class_3341 searchBox = new class_3341(
                piece.method_14935().method_35415() - this.horizontalRange,
                piece.method_14935().method_35416() - this.belowRange,
                piece.method_14935().method_35417() - this.horizontalRange,
                piece.method_14935().method_35418() + this.horizontalRange,
                piece.method_14935().method_35419() + this.aboveRange,
                piece.method_14935().method_35420() + this.horizontalRange);

        // Check for any matching pieces that satisfy the positional criteria
        for (PieceEntry otherPieceEntry : pieces) {
            class_3790 otherPiece = otherPieceEntry.getPiece();
            if (otherPiece.method_16644() instanceof class_3781 || otherPiece.method_16644() instanceof YungJigsawSinglePoolElement) {
                // If otherPiece has the same bounding box as our starting piece, skip over it, as
                // it is likely just the same piece.
                if (otherPiece.method_14935().equals(piece.method_14935())) {
                    continue;
                }

                class_3499 otherStructureTemplate = otherPiece.method_16644() instanceof class_3781
                        ? ((SinglePoolElementAccessor) otherPiece.method_16644()).callGetTemplate(templateManager)
                        : ((YungJigsawSinglePoolElement) otherPiece.method_16644()).getTemplate(templateManager);

                // Iterate our target pieces and check for a match with otherPiece
                for (class_2960 matchPieceId : matchPieces) {
                    class_3499 structureTemplate = templateManager.method_15091(matchPieceId);
                    if (otherStructureTemplate == structureTemplate || matchPieceId.equals(ALL)) {
                        // This is one of the pieces we're searching for, so we test its bounding box.
                        // It must intersect the search box, but not be within the current piece's bounding box.
                        if (otherPiece.method_14935().method_14657(searchBox) && !otherPiece.method_14935().method_14657(piece.method_14935())) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy