com.yungnickyoung.minecraft.yungsapi.world.structure.condition.PieceInRangeCondition 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.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;
}
}