package com.hypixel.hytale.builtin.buildertools.scriptedbrushes;
import com.hypixel.hytale.builtin.buildertools.utils.FluidPatternHelper;
import com.hypixel.hytale.builtin.buildertools.utils.Material;
import com.hypixel.hytale.math.util.MathUtil;
import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.protocol.InteractionType;
import com.hypixel.hytale.protocol.packets.buildertools.BrushShape;
import com.hypixel.hytale.server.core.prefab.selection.mask.BlockMask;
import com.hypixel.hytale.server.core.prefab.selection.mask.BlockPattern;
import java.util.Random;
import java.util.function.BiConsumer;
import java.util.function.Function;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class BrushConfig {
private static final Random random = new Random();
@Nullable
private InteractionType interactionType;
private boolean isHoldDownInteraction;
private Vector3i origin;
private boolean isCurrentlyExecuting;
private boolean hasExecutionContextEncounteredError;
@Nullable
private String executionErrorMessage;
private Vector3i originOffset = new Vector3i(0, 0, 0);
@Nullable
private Vector3i originAfterOffset;
private BrushShape shape;
private int shapeWidth;
private int shapeHeight;
private int shapeThickness;
private boolean capped;
private BlockPattern pattern;
private int density;
private boolean enableBrushMask;
private BlockMask brushMask;
private boolean enableOperationMask;
private BlockMask operationMask;
private BlockMask combinedMasks;
private HistoryMask historyMask;
public BrushConfig() {
this.resetToDefaultValues();
}
public BrushConfig(@Nonnull BrushConfig other) {
this.interactionType = other.interactionType;
this.origin = other.origin;
this.isCurrentlyExecuting = other.isCurrentlyExecuting;
this.hasExecutionContextEncounteredError = other.hasExecutionContextEncounteredError;
this.executionErrorMessage = other.executionErrorMessage;
this.originOffset = other.originOffset.clone();
this.originAfterOffset = other.originAfterOffset.clone();
this.shape = other.shape;
this.shapeWidth = other.shapeWidth;
this.shapeHeight = other.shapeHeight;
this.shapeThickness = other.shapeThickness;
this.capped = other.capped;
this.pattern = other.pattern;
this.density = other.density;
this.enableBrushMask = other.enableBrushMask;
this.brushMask = other.brushMask;
this.enableOperationMask = other.enableOperationMask;
this.operationMask = other.operationMask;
this.combinedMasks = other.combinedMasks;
this.historyMask = other.historyMask;
this.isHoldDownInteraction = other.isHoldDownInteraction;
}
public void beginExecution(Vector3i origin, boolean isHoldDownInteraction, InteractionType interactionType) {
this.isCurrentlyExecuting = true;
this.origin = origin;
this.isHoldDownInteraction = isHoldDownInteraction;
this.interactionType = interactionType;
this.updateOriginWithOffsets();
}
public void endExecution() {
this.resetToDefaultValues();
}
public void resetToDefaultValues() {
this.interactionType = null;
this.origin = new Vector3i(0, 0, 0);
this.isCurrentlyExecuting = false;
this.hasExecutionContextEncounteredError = false;
this.executionErrorMessage = null;
this.originOffset = new Vector3i(0, 0, 0);
this.originAfterOffset = null;
this.shape = BrushShape.Cube;
this.shapeWidth = 5;
this.shapeHeight = 5;
this.shapeThickness = 0;
this.capped = false;
this.pattern = BlockPattern.parse("Rock_Stone");
this.density = 100;
this.enableBrushMask = true;
this.brushMask = BlockMask.EMPTY;
this.enableOperationMask = true;
this.operationMask = BlockMask.EMPTY;
this.combinedMasks = BlockMask.EMPTY;
this.historyMask = BrushConfig.HistoryMask.None;
}
public boolean isHoldDownInteraction() {
return this.isHoldDownInteraction;
}
public boolean isCurrentlyExecuting() {
return this.isCurrentlyExecuting;
}
@Nullable
public InteractionType getInteractionType() {
return this.interactionType;
}
@Nullable
public Vector3i getOrigin() {
return this.originAfterOffset;
}
@Nonnull
public Vector3i getOriginOffset() {
return this.originOffset.clone();
}
public void setOriginOffset(Vector3i originOffset) {
this.originOffset = originOffset;
this.updateOriginWithOffsets();
}
public void modifyOriginOffset(@Nonnull Vector3i originOffsetOffset) {
this.originOffset = this.originOffset.add(originOffsetOffset);
this.updateOriginWithOffsets();
}
public void updateOriginWithOffsets() {
if (this.origin != null) {
this.originAfterOffset = this.origin.clone().add(this.originOffset);
}
}
@Nonnull
public Random getRandom() {
return random;
}
public int getNextBlock() {
return this.pattern.nextBlock(random);
}
@Nonnull
public Material getNextMaterial() {
BlockPattern.BlockEntry blockEntry = this.pattern.nextBlockTypeKey(random);
if (blockEntry != null) {
FluidPatternHelper.FluidInfo fluidInfo = FluidPatternHelper.getFluidInfo(blockEntry.blockTypeKey());
if (fluidInfo != null) {
return Material.fluid(fluidInfo.fluidId(), fluidInfo.fluidLevel());
}
}
return Material.block(this.pattern.nextBlock(random));
}
public BlockMask getBlockMask() {
return this.combinedMasks;
}
public void setOperationMask(BlockMask mask) {
this.operationMask = mask;
this.refreshCombinedMasks();
}
public void appendOperationMask(BlockMask mask) {
this.operationMask = BlockMask.combine(mask, this.operationMask);
this.refreshCombinedMasks();
}
public void clearOperationMask() {
this.operationMask = BlockMask.EMPTY;
this.refreshCombinedMasks();
}
public void setUseBrushMask(boolean useBrushMask) {
this.enableBrushMask = useBrushMask;
this.refreshCombinedMasks();
}
public void setUseOperationMask(boolean useOperationMask) {
this.enableOperationMask = useOperationMask;
this.refreshCombinedMasks();
}
public void setBrushMask(BlockMask mask) {
this.brushMask = mask;
this.refreshCombinedMasks();
}
private void refreshCombinedMasks() {
if (this.enableBrushMask && this.enableOperationMask) {
this.combinedMasks = BlockMask.combine(this.brushMask, this.operationMask);
} else if (this.enableBrushMask) {
this.combinedMasks = this.brushMask;
} else if (this.enableOperationMask) {
this.combinedMasks = this.operationMask;
}
}
public int getDensity() {
return this.density;
}
public void setDensity(int density) {
this.density = MathUtil.clamp(density, 1, 100);
}
public HistoryMask getHistoryMask() {
return this.historyMask;
}
public void setHistoryMask(HistoryMask historyMask) {
this.historyMask = historyMask;
}
public int getShapeWidth() {
return this.shapeWidth;
}
public void setShapeWidth(int shapeWidth) {
if (shapeWidth <= 0) {
this.setErrorFlag("You cannot set shape width to be less than or equal to zero. Width: " + shapeWidth);
} else {
this.shapeWidth = shapeWidth;
}
}
public int getShapeHeight() {
return this.shapeHeight;
}
public void setShapeHeight(int shapeHeight) {
if (shapeHeight <= 0) {
this.setErrorFlag("You cannot set shape height to be less than or equal to zero. Height: " + shapeHeight);
} else {
this.shapeHeight = shapeHeight;
}
}
public int getShapeThickness() {
return this.shapeThickness;
}
public void setShapeThickness(int shapeThickness) {
this.shapeThickness = shapeThickness;
}
public boolean isCapped() {
return this.capped;
}
public void setCapped(boolean capped) {
this.capped = capped;
}
public BrushShape getShape() {
return this.shape;
}
public void setShape(BrushShape shape) {
this.shape = shape;
}
public BlockPattern getPattern() {
return this.pattern;
}
public void setPattern(BlockPattern pattern) {
this.pattern = pattern;
}
public void setErrorFlag(String errorMessage) {
this.hasExecutionContextEncounteredError = true;
this.executionErrorMessage = errorMessage;
}
public void clearError() {
this.hasExecutionContextEncounteredError = false;
this.executionErrorMessage = null;
}
public boolean isHasExecutionContextEncounteredError() {
return this.hasExecutionContextEncounteredError;
}
@Nullable
public String getExecutionErrorMessage() {
return this.executionErrorMessage;
}
@Nullable
public Vector3i getOriginAfterOffset() {
return this.originAfterOffset;
}
@Nonnull
public String toString() {
String var10000 = String.valueOf(this.interactionType);
return "BrushConfig{, interactionType=" + var10000 + ", origin=" + String.valueOf(this.origin) + ", originOffset=" + String.valueOf(this.originOffset) + ", originAfterOffset=" + String.valueOf(this.originAfterOffset) + ", shapeWidth=" + this.shapeWidth + ", shapeHeight=" + this.shapeHeight + ", shapeThickness=" + this.shapeThickness + ", capped=" + this.capped + ", density=" + this.density + ", shape=" + String.valueOf(this.shape) + ", pattern=" + String.valueOf(this.pattern) + ", historyMask=" + String.valueOf(this.historyMask) + ", brushMask=" + String.valueOf(this.brushMask) + ", operationMask=" + String.valueOf(this.operationMask) + ", combinedMasks=" + String.valueOf(this.combinedMasks) + ", enableOperationMask=" + this.enableOperationMask + ", enableBrushMask=" + this.enableBrushMask + ", random=" + String.valueOf(random) + ", isCurrentlyExecuting=" + this.isCurrentlyExecuting + "}";
}
@Nonnull
public String getInfo() {
StringBuilder builder = new StringBuilder("Brush Config Information:");
builder.append("\nOrigin with Offset: {");
if (this.originAfterOffset == null) {
builder.append("Not currently executing, so no origin");
} else {
builder.append(this.originAfterOffset.x).append(", ").append(this.originAfterOffset.y).append(", ").append(this.originAfterOffset.z);
}
builder.append("}");
builder.append("\nOffset: {").append(this.originOffset.x).append(", ").append(this.originOffset.y).append(", ").append(this.originOffset.z).append("}");
builder.append("\nDimensions: {Width: ").append(this.shapeWidth).append(", Height: ").append(this.shapeHeight).append("}");
builder.append("\nShape Properties: {Shape: ").append(this.shape.name()).append(", Thickness: ").append(this.shapeThickness).append(", Capped: ").append(this.capped).append("}");
builder.append("\nPattern: ").append(this.pattern.toString());
builder.append("\nMasks: {HistoryMask: ").append(this.historyMask.name()).append(", EnableOperationMask: ").append(this.enableOperationMask).append(", EnableBrushMask: ").append(this.enableBrushMask).append(", CombinedMasks: ").append(this.combinedMasks.informativeToString()).append("}");
builder.append("\nIs Currently Executing: ").append(this.isCurrentlyExecuting);
return builder.toString();
}
public static enum HistoryMask {
None,
Only,
Not;
private HistoryMask() {
}
}
public static enum BCExecutionStatus {
Continue,
Error,
Complete;
private BCExecutionStatus() {
}
}
public static enum DataSettingFlags {
Offset((copyTo, copyFrom) -> copyTo.setOriginOffset(copyFrom.getOriginOffset())),
Shape((copyTo, copyFrom) -> copyTo.setShape(copyFrom.getShape())),
Dimensions((copyTo, copyFrom) -> {
copyTo.setShapeWidth(copyFrom.getShapeWidth());
copyTo.setShapeHeight(copyFrom.getShapeHeight());
}),
Thickness((copyTo, copyFrom) -> copyTo.setShapeThickness(copyFrom.getShapeThickness())),
Capped((copyTo, copyFrom) -> copyTo.setCapped(copyFrom.isCapped())),
Pattern((copyTo, copyFrom) -> copyTo.setPattern(copyFrom.getPattern())),
Density((copyTo, copyFrom) -> copyTo.setDensity(copyFrom.getDensity())),
BrushMask((copyTo, copyFrom) -> {
copyTo.setBrushMask(copyFrom.brushMask);
copyTo.setUseBrushMask(copyFrom.enableBrushMask);
}),
OperationMask((copyTo, copyFrom) -> {
copyTo.setOperationMask(copyFrom.operationMask);
copyTo.setUseOperationMask(copyFrom.enableOperationMask);
}),
HistoryMask((copyTo, copyFrom) -> copyTo.setHistoryMask(copyFrom.getHistoryMask()));
private final BiConsumer<BrushConfig, BrushConfig> stateLoader;
private DataSettingFlags(BiConsumer<BrushConfig, BrushConfig> stateLoader) {
this.stateLoader = stateLoader;
}
public void loadData(BrushConfig copyTo, BrushConfig copyFrom) {
this.stateLoader.accept(copyTo, copyFrom);
}
}
public static enum DataGettingFlags {
OffsetX((brushConfig) -> brushConfig.getOriginOffset().x),
OffsetY((brushConfig) -> brushConfig.getOriginOffset().y),
OffsetZ((brushConfig) -> brushConfig.getOriginOffset().z),
Height((brushConfig) -> brushConfig.getShapeHeight()),
Width((brushConfig) -> brushConfig.getShapeWidth()),
Density((brushConfig) -> brushConfig.getDensity());
private final Function<BrushConfig, Integer> valueGetter;
private DataGettingFlags(Function<BrushConfig, Integer> valueGetter) {
this.valueGetter = valueGetter;
}
public int getValue(BrushConfig brushConfig) {
return (Integer)this.valueGetter.apply(brushConfig);
}
}
}