classpublicPriority 3
PondFillerProp
com.hypixel.hytale.builtin.hytalegenerator.props.filler.PondFillerProp
extends Prop
4
Methods
4
Public Methods
8
Fields
1
Constructors
Constants
intLEAKS= 16
intSOLID= 256
intSTACKED= 4096
intTRAVERSED= 1
Constructors
public
PondFillerProp(Vector3i boundingMin, Vector3i boundingMax, MaterialSet solidSet, MaterialProvider<Material> filledMaterialProvider, Scanner scanner, Pattern pattern)Methods
Public Methods (4)
public
ContextDependency getContextDependency()@Override
public
Bounds3i getWriteBounds()@Nonnull@Override
public
void place(Prop.Context context)@Override
public
FillerPropScanResult scan(Vector3i position, VoxelSpace<Material> materialSpace, WorkerIndexer.Id id)Fields
Private/Package Fields (8)
private
Vector3i boundingMaxprivate
Vector3i boundingMinprivate
ContextDependency contextDependencyprivate
MaterialProvider<Material> filledMaterialProviderprivate
Pattern patternprivate
Scanner scannerprivate
MaterialSet solidSetprivate
Bounds3i writeBounds_voxelGridInheritance
Parent
Current
Interface
Child
Use mouse wheel to zoom, drag to pan. Click nodes to navigate.
Related Classes
Source Code
package com.hypixel.hytale.builtin.hytalegenerator.props.filler;
import com.hypixel.hytale.builtin.hytalegenerator.MaterialSet;
import com.hypixel.hytale.builtin.hytalegenerator.bounds.Bounds3i;
import com.hypixel.hytale.builtin.hytalegenerator.bounds.SpaceSize;
import com.hypixel.hytale.builtin.hytalegenerator.conveyor.stagedconveyor.ContextDependency;
import com.hypixel.hytale.builtin.hytalegenerator.datastructures.voxelspace.ArrayVoxelSpace;
import com.hypixel.hytale.builtin.hytalegenerator.datastructures.voxelspace.VoxelSpace;
import com.hypixel.hytale.builtin.hytalegenerator.material.Material;
import com.hypixel.hytale.builtin.hytalegenerator.materialproviders.MaterialProvider;
import com.hypixel.hytale.builtin.hytalegenerator.patterns.Pattern;
import com.hypixel.hytale.builtin.hytalegenerator.props.Prop;
import com.hypixel.hytale.builtin.hytalegenerator.scanners.Scanner;
import com.hypixel.hytale.builtin.hytalegenerator.threadindexer.WorkerIndexer;
import com.hypixel.hytale.math.vector.Vector3i;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
public class PondFillerProp extends Prop {
private static final int TRAVERSED = 1;
private static final int LEAKS = 16;
private static final int SOLID = 256;
private static final int STACKED = 4096;
private final Vector3i boundingMin;
private final Vector3i boundingMax;
private final MaterialProvider<Material> filledMaterialProvider;
private final MaterialSet solidSet;
private final Scanner scanner;
private final Pattern pattern;
private final ContextDependency contextDependency;
private final Bounds3i writeBounds_voxelGrid;
public PondFillerProp(
@Nonnull Vector3i boundingMin,
@Nonnull Vector3i boundingMax,
@Nonnull MaterialSet solidSet,
@Nonnull MaterialProvider<Material> filledMaterialProvider,
@Nonnull Scanner scanner,
@Nonnull Pattern pattern
) {
this.boundingMin = boundingMin.clone();
this.boundingMax = boundingMax.clone();
this.solidSet = solidSet;
this.filledMaterialProvider = filledMaterialProvider;
this.scanner = scanner;
this.pattern = pattern;
SpaceSize boundingSpace = new SpaceSize(boundingMin, boundingMax);
boundingSpace = SpaceSize.stack(boundingSpace, scanner.readSpaceWith(pattern));
SpaceSize.stack(scanner.readSpaceWith(pattern), boundingSpace);
Vector3i range = boundingSpace.getRange();
this.contextDependency = new ContextDependency(range, range);
this.writeBounds_voxelGrid = this.contextDependency.getTotalPropBounds_voxelGrid();
}
public FillerPropScanResult scan(@Nonnull Vector3i position, @Nonnull VoxelSpace<Material> materialSpace, @Nonnull WorkerIndexer.Id id) {
Scanner.Context scannerContext = new Scanner.Context(position, this.pattern, materialSpace, id);
List<Vector3i> scanResults = this.scanner.scan(scannerContext);
if (scanResults.size() == 1) {
List<Vector3i> resultList = this.renderFluidBlocks(scanResults.getFirst(), materialSpace);
return new FillerPropScanResult(resultList);
} else {
ArrayList<Vector3i> resultList = new ArrayList<>();
for (Vector3i scanPosition : scanResults) {
List<Vector3i> renderResult = this.renderFluidBlocks(scanPosition, materialSpace);
resultList.addAll(renderResult);
}
return new FillerPropScanResult(resultList);
}
}
private List<Vector3i> renderFluidBlocks(@Nonnull Vector3i origin, @Nonnull VoxelSpace<Material> materialSpace) {
Vector3i min = this.boundingMin.clone().add(origin);
Vector3i max = this.boundingMax.clone().add(origin);
min = Vector3i.max(min, new Vector3i(materialSpace.minX(), materialSpace.minY(), materialSpace.minZ()));
max = Vector3i.min(max, new Vector3i(materialSpace.maxX(), materialSpace.maxY(), materialSpace.maxZ()));
ArrayVoxelSpace<Integer> mask = new ArrayVoxelSpace<>(max.x - min.x, max.y - min.y, max.z - min.z);
mask.setOrigin(-min.x, -min.y, -min.z);
mask.set(0);
int y = min.y;
for (int x = min.x; x < max.x; x++) {
for (int z = min.z; z < max.z; z++) {
Material material = materialSpace.getContent(x, y, z);
int contextMaterialHash = material.hashMaterialIds();
int maskValue = 1;
if (this.solidSet.test(contextMaterialHash)) {
maskValue |= 256;
mask.set(maskValue, x, y, z);
} else {
maskValue |= 16;
mask.set(maskValue, x, y, z);
}
}
}
for (int var29 = min.y + 1; var29 < max.y; var29++) {
int underY = var29 - 1;
for (int x = min.x; x < max.x; x++) {
for (int zx = min.z; zx < max.z; zx++) {
if (!isTraversed(mask.getContent(x, var29, zx))) {
int maskValueUnder = mask.getContent(x, underY, zx);
Material material = materialSpace.getContent(x, var29, zx);
int contextMaterialHash = material.hashMaterialIds();
if (this.solidSet.test(contextMaterialHash)) {
int maskValue = 0;
maskValue |= 1;
maskValue |= 256;
mask.set(maskValue, x, var29, zx);
} else if (isLeaks(maskValueUnder) || x == min.x || x == max.x - 1 || zx == min.z || zx == max.z - 1) {
ArrayDeque<Vector3i> stack = new ArrayDeque<>();
stack.push(new Vector3i(x, var29, zx));
mask.set(4096, x, var29, zx);
while (!stack.isEmpty()) {
Vector3i poppedPos = stack.pop();
int maskValue = mask.getContent(poppedPos.x, poppedPos.y, poppedPos.z);
maskValue |= 16;
mask.set(maskValue, poppedPos.x, poppedPos.y, poppedPos.z);
poppedPos.x--;
if (mask.isInsideSpace(poppedPos.x, poppedPos.y, poppedPos.z)) {
int poppedMaskValue = mask.getContent(poppedPos.x, poppedPos.y, poppedPos.z);
if (!isStacked(poppedMaskValue)) {
material = materialSpace.getContent(poppedPos.x, poppedPos.y, poppedPos.z);
contextMaterialHash = material.hashMaterialIds();
if (!this.solidSet.test(contextMaterialHash)) {
stack.push(poppedPos.clone());
mask.set(4096 | poppedMaskValue, poppedPos.x, poppedPos.y, poppedPos.z);
}
}
}
poppedPos.x += 2;
if (mask.isInsideSpace(poppedPos.x, poppedPos.y, poppedPos.z)) {
int poppedMaskValue = mask.getContent(poppedPos.x, poppedPos.y, poppedPos.z);
if (!isStacked(poppedMaskValue)) {
material = materialSpace.getContent(poppedPos.x, poppedPos.y, poppedPos.z);
contextMaterialHash = material.hashMaterialIds();
if (!this.solidSet.test(contextMaterialHash)) {
stack.push(poppedPos.clone());
mask.set(4096 | poppedMaskValue, poppedPos.x, poppedPos.y, poppedPos.z);
}
}
}
poppedPos.x--;
poppedPos.z--;
if (mask.isInsideSpace(poppedPos.x, poppedPos.y, poppedPos.z)) {
int poppedMaskValue = mask.getContent(poppedPos.x, poppedPos.y, poppedPos.z);
if (!isStacked(poppedMaskValue)) {
material = materialSpace.getContent(poppedPos.x, var29, poppedPos.z);
contextMaterialHash = material.hashMaterialIds();
if (!this.solidSet.test(contextMaterialHash)) {
stack.push(poppedPos.clone());
mask.set(4096 | poppedMaskValue, poppedPos.x, poppedPos.y, poppedPos.z);
}
}
}
poppedPos.z += 2;
if (mask.isInsideSpace(poppedPos.x, poppedPos.y, poppedPos.z)) {
int poppedMaskValue = mask.getContent(poppedPos.x, poppedPos.y, poppedPos.z);
if (!isStacked(poppedMaskValue)) {
material = materialSpace.getContent(poppedPos.x, poppedPos.y, poppedPos.z);
contextMaterialHash = material.hashMaterialIds();
if (!this.solidSet.test(contextMaterialHash)) {
stack.push(poppedPos.clone());
mask.set(4096 | poppedMaskValue, poppedPos.x, poppedPos.y, poppedPos.z);
}
}
}
poppedPos.z--;
}
}
}
}
}
}
ArrayList<Vector3i> fluidBlocks = new ArrayList<>();
for (int var30 = mask.minY() + 1; var30 < mask.maxY(); var30++) {
for (int x = mask.minX() + 1; x < mask.maxX() - 1; x++) {
for (int zxx = mask.minZ() + 1; zxx < mask.maxZ() - 1; zxx++) {
int maskValuex = mask.getContent(x, var30, zxx);
if (!isSolid(maskValuex) && !isLeaks(maskValuex)) {
fluidBlocks.add(new Vector3i(x, var30, zxx));
}
}
}
}
return fluidBlocks;
}
@Override
public void place(@Nonnull Prop.Context context) {
List<Vector3i> fluidBlocks = FillerPropScanResult.cast(context.scanResult).getFluidBlocks();
if (fluidBlocks != null) {
for (Vector3i position : fluidBlocks) {
if (context.materialSpace.isInsideSpace(position.x, position.y, position.z)) {
MaterialProvider.Context materialsContext = new MaterialProvider.Context(
position, 0.0, 0, 0, 0, 0, context.workerId, null, context.distanceFromBiomeEdge
);
Material material = this.filledMaterialProvider.getVoxelTypeAt(materialsContext);
if (material != null) {
context.materialSpace.set(material, position.x, position.y, position.z);
}
}
}
}
}
@Override
public ContextDependency getContextDependency() {
return this.contextDependency.clone();
}
@Nonnull
@Override
public Bounds3i getWriteBounds() {
return this.writeBounds_voxelGrid;
}
private static boolean isTraversed(int maskValue) {
return (maskValue & 1) == 1;
}
private static boolean isLeaks(int maskValue) {
return (maskValue & 16) == 16;
}
private static boolean isSolid(int maskValue) {
return (maskValue & 256) == 256;
}
private static boolean isStacked(int maskValue) {
return (maskValue & 4096) == 4096;
}
}