classpublicPriority 3
ColumnRandomScanner
com.hypixel.hytale.builtin.hytalegenerator.scanners.ColumnRandomScanner
extends Scanner
2
Methods
2
Public Methods
8
Fields
1
Constructors
Constructors
public
ColumnRandomScanner(int minY, int maxY, int resultsCap, int seed, ColumnRandomScanner.Strategy strategy, boolean isRelativeToPosition, BiDouble2DoubleFunction bedFunction)Methods
Public Methods (2)
public
List<Vector3i> scan(Scanner.Context context)@Nonnull@Override
public
SpaceSize scanSpace()@Nonnull@Override
Fields
Private/Package Fields (8)
private
BiDouble2DoubleFunction bedFunctionprivate
boolean isRelativeToPositionprivate
int maxYprivate
int minYprivate
int resultsCapprivate
SpaceSize scanSpaceSizeprivate
SeedGenerator seedGeneratorprivate
ColumnRandomScanner.Strategy strategyInheritance
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.scanners;
import com.hypixel.hytale.builtin.hytalegenerator.bounds.SpaceSize;
import com.hypixel.hytale.builtin.hytalegenerator.framework.interfaces.functions.BiDouble2DoubleFunction;
import com.hypixel.hytale.builtin.hytalegenerator.framework.math.SeedGenerator;
import com.hypixel.hytale.builtin.hytalegenerator.patterns.Pattern;
import com.hypixel.hytale.math.util.FastRandom;
import com.hypixel.hytale.math.vector.Vector3i;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class ColumnRandomScanner extends Scanner {
private final int minY;
private final int maxY;
private final boolean isRelativeToPosition;
@Nullable
private final BiDouble2DoubleFunction bedFunction;
private final int resultsCap;
@Nonnull
private final SeedGenerator seedGenerator;
@Nonnull
private final ColumnRandomScanner.Strategy strategy;
@Nonnull
private final SpaceSize scanSpaceSize;
public ColumnRandomScanner(
int minY,
int maxY,
int resultsCap,
int seed,
@Nonnull ColumnRandomScanner.Strategy strategy,
boolean isRelativeToPosition,
@Nullable BiDouble2DoubleFunction bedFunction
) {
if (resultsCap < 0) {
throw new IllegalArgumentException();
} else {
this.bedFunction = bedFunction;
this.minY = minY;
this.maxY = maxY;
this.isRelativeToPosition = isRelativeToPosition;
this.resultsCap = resultsCap;
this.seedGenerator = new SeedGenerator((long)seed);
this.strategy = strategy;
this.scanSpaceSize = new SpaceSize(new Vector3i(0, 0, 0), new Vector3i(1, 0, 1));
}
}
@Nonnull
@Override
public List<Vector3i> scan(@Nonnull Scanner.Context context) {
return switch (this.strategy) {
case DART_THROW -> this.scanDartThrow(context);
case PICK_VALID -> this.scanPickValid(context);
};
}
@Nonnull
private List<Vector3i> scanPickValid(@Nonnull Scanner.Context context) {
if (this.resultsCap == 0) {
return Collections.emptyList();
} else {
int scanMinY;
int scanMaxY;
if (this.isRelativeToPosition) {
scanMinY = Math.max(context.position.y + this.minY, context.materialSpace.minY());
scanMaxY = Math.min(context.position.y + this.maxY, context.materialSpace.maxY());
} else if (this.bedFunction != null) {
int bedY = (int)this.bedFunction.apply((double)context.position.x, (double)context.position.z);
scanMinY = Math.max(bedY + this.minY, context.materialSpace.minY());
scanMaxY = Math.min(bedY + this.maxY, context.materialSpace.maxY());
} else {
scanMinY = Math.max(this.minY, context.materialSpace.minY());
scanMaxY = Math.min(this.maxY, context.materialSpace.maxY());
}
int numberOfPossiblePositions = Math.max(0, scanMaxY - scanMinY);
ArrayList<Vector3i> validPositions = new ArrayList<>(numberOfPossiblePositions);
Vector3i patternPosition = context.position.clone();
Pattern.Context patternContext = new Pattern.Context(patternPosition, context.materialSpace, context.workerId);
for (int y = scanMinY; y < scanMaxY; y++) {
patternPosition.y = y;
if (context.pattern.matches(patternContext)) {
Vector3i position = context.position.clone();
position.setY(y);
validPositions.add(position);
}
}
if (validPositions.isEmpty()) {
return validPositions;
} else if (validPositions.size() <= this.resultsCap) {
return validPositions;
} else {
ArrayList<Integer> usedIndices = new ArrayList<>(this.resultsCap);
ArrayList<Vector3i> outPositions = new ArrayList<>(this.resultsCap);
FastRandom random = new FastRandom(this.seedGenerator.seedAt((long)context.position.x, (long)context.position.y, (long)context.position.z));
for (int i = 0; i < this.resultsCap; i++) {
int pickedIndex = random.nextInt(validPositions.size());
if (!usedIndices.contains(pickedIndex)) {
usedIndices.add(pickedIndex);
outPositions.add(validPositions.get(pickedIndex));
}
}
return outPositions;
}
}
}
@Nonnull
private List<Vector3i> scanDartThrow(@Nonnull Scanner.Context context) {
if (this.resultsCap == 0) {
return Collections.emptyList();
} else {
int scanMinY = this.isRelativeToPosition
? Math.max(context.position.y + this.minY, context.materialSpace.minY())
: Math.max(this.minY, context.materialSpace.minY());
int scanMaxY = this.isRelativeToPosition
? Math.min(context.position.y + this.maxY, context.materialSpace.maxY())
: Math.min(this.maxY, context.materialSpace.maxY());
int range = scanMaxY - scanMinY;
if (range == 0) {
return Collections.emptyList();
} else {
int TRY_MULTIPLIER = 1;
int numberOfTries = range * 1;
ArrayList<Vector3i> validPositions = new ArrayList<>(this.resultsCap);
FastRandom random = new FastRandom(this.seedGenerator.seedAt((long)context.position.x, (long)context.position.y, (long)context.position.z));
ArrayList<Integer> usedYs = new ArrayList<>(this.resultsCap);
Vector3i patternPosition = context.position.clone();
Pattern.Context patternContext = new Pattern.Context(patternPosition, context.materialSpace, context.workerId);
for (int i = 0; i < numberOfTries; i++) {
patternPosition.y = random.nextInt(range) + scanMinY;
if (context.pattern.matches(patternContext) && !usedYs.contains(patternPosition.y)) {
usedYs.add(patternPosition.y);
Vector3i position = patternPosition.clone();
validPositions.add(position);
if (validPositions.size() == this.resultsCap) {
break;
}
}
}
return validPositions;
}
}
}
@Nonnull
@Override
public SpaceSize scanSpace() {
return this.scanSpaceSize.clone();
}
public static enum Strategy {
DART_THROW,
PICK_VALID;
private Strategy() {
}
}
}