Refactored BCLib Package Structure

This commit is contained in:
Frank 2022-06-07 16:44:14 +02:00
parent c658a24750
commit f6d5f85ec1
206 changed files with 974 additions and 945 deletions

View file

@ -7,9 +7,9 @@ import net.minecraft.resources.ResourceLocation;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.model.*;
import org.betterx.bclib.api.ModIntegrationAPI;
import org.betterx.bclib.api.PostInitAPI;
import org.betterx.bclib.api.dataexchange.DataExchangeAPI;
import org.betterx.bclib.api.v2.ModIntegrationAPI;
import org.betterx.bclib.api.v2.PostInitAPI;
import org.betterx.bclib.api.v2.dataexchange.DataExchangeAPI;
import org.betterx.bclib.client.models.CustomModelBakery;
import org.betterx.bclib.client.presets.WorldPresetsUI;
import org.betterx.bclib.registry.BaseBlockEntityRenders;

View file

@ -0,0 +1,32 @@
package org.betterx.bclib.client.gui.gridlayout;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import com.mojang.blaze3d.vertex.PoseStack;
import org.betterx.bclib.interfaces.TriConsumer;
import java.util.List;
import java.util.function.Function;
@Environment(EnvType.CLIENT)
class GridCell extends GridCellDefinition {
public final float height;
Function<GridTransform, Object> componentPlacer;
TriConsumer<PoseStack, GridTransform, Object> customRender;
GridCell(double width,
double height,
GridLayout.GridValueType widthType,
Function<GridTransform, Object> componentPlacer,
TriConsumer<PoseStack, GridTransform, Object> customRender) {
super(width, widthType);
this.height = (float) height;
this.componentPlacer = componentPlacer;
this.customRender = customRender;
}
protected GridElement buildElementAt(int left, int top, int width, final List<GridElement> collector) {
return new GridElement(left, top, width, (int) this.height, componentPlacer, customRender);
}
}

View file

@ -0,0 +1,95 @@
package org.betterx.bclib.client.gui.gridlayout;
import net.minecraft.client.gui.components.Checkbox;
import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import java.util.function.Consumer;
@Environment(EnvType.CLIENT)
class SignalingCheckBox extends Checkbox {
private final Consumer<Boolean> onChange;
public SignalingCheckBox(int left,
int top,
int width,
int height,
Component component,
boolean checked,
Consumer<Boolean> onChange) {
super(left, top, width, height, component, checked);
this.onChange = onChange;
if (onChange != null)
onChange.accept(checked);
}
@Override
public void onPress() {
super.onPress();
if (onChange != null)
onChange.accept(this.selected());
}
}
@Environment(EnvType.CLIENT)
public class GridCheckboxCell extends GridCell implements GridWidgetWithEnabledState {
private boolean checked;
private Checkbox lastCheckbox;
private boolean enabled;
private final float alpha;
GridCheckboxCell(Component text,
boolean checked,
float alpha,
double width,
GridLayout.GridValueType widthType,
double height) {
this(text, checked, alpha, width, widthType, height, null);
}
GridCheckboxCell(Component text,
boolean checked,
float alpha,
double width,
GridLayout.GridValueType widthType,
double height,
Consumer<Boolean> onChange) {
super(width, height, widthType, null, null);
lastCheckbox = null;
enabled = true;
this.alpha = alpha;
this.componentPlacer = (transform) -> {
Checkbox cb = new SignalingCheckBox(transform.left, transform.top, transform.width, transform.height,
text,
checked,
(state) -> {
this.checked = state;
if (onChange != null) onChange.accept(state);
}
);
cb.setAlpha(alpha);
lastCheckbox = cb;
setEnabled(enabled);
return cb;
};
}
public boolean isChecked() {
return checked;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
if (lastCheckbox != null) {
lastCheckbox.active = enabled;
lastCheckbox.setAlpha(enabled ? alpha : (alpha * 0.5f));
}
this.enabled = enabled;
}
}

View file

@ -0,0 +1,73 @@
package org.betterx.bclib.client.gui.gridlayout;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import java.util.List;
@Environment(EnvType.CLIENT)
public class GridColumn extends GridContainer {
GridColumn(double width) {
super(width);
}
GridColumn(double width, GridLayout.GridValueType widthType) {
super(width, widthType);
}
public GridRow addRow() {
return addRow(GridLayout.VerticalAlignment.TOP);
}
public GridRow addRow(GridLayout.VerticalAlignment align) {
GridRow row = new GridRow(1.0,
widthType == GridLayout.GridValueType.INHERIT
? GridLayout.GridValueType.INHERIT
: GridLayout.GridValueType.PERCENTAGE,
align);
this.cells.add(row);
return row;
}
public void addSpacerRow() {
this.addSpacerRow(4);
}
public void addSpacerRow(int height) {
GridCell cell = new GridCell(1.0, height, GridLayout.GridValueType.PERCENTAGE, null, null);
this.cells.add(cell);
}
@Override
public int calculateWidth(final int parentWidth) {
if (widthType == GridLayout.GridValueType.INHERIT) {
return cells.stream()
.filter(row -> row.widthType == GridLayout.GridValueType.INHERIT)
.map(row -> row.buildElement(0, 0, 1, 0, 0, null).width)
.reduce(0, (p, c) -> Math.max(p, c));
} else {
return super.calculateWidth(parentWidth);
}
}
@Override
protected GridElement buildElementAt(int left, int inTop, int width, final List<GridElement> collector) {
int height = 0;
int top = inTop;
if (widthType == GridLayout.GridValueType.INHERIT) {
width = calculateWidth(width);
}
for (GridCellDefinition row : cells) {
GridElement element = row.buildElement(width, 0, 1, left, top, collector);
top += element.height;
height += element.height;
}
return new GridElement(left, inTop, width, height);
}
}

View file

@ -0,0 +1,18 @@
package org.betterx.bclib.client.gui.gridlayout;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import com.mojang.blaze3d.vertex.PoseStack;
import org.betterx.bclib.client.gui.gridlayout.GridLayout.GridValueType;
@Environment(EnvType.CLIENT)
public abstract class GridCustomRenderCell extends GridCell {
protected GridCustomRenderCell(double width, GridValueType widthType, double height) {
super(width, height, widthType, null, null);
this.customRender = this::onRender;
}
public abstract void onRender(PoseStack poseStack, GridTransform transform, Object context);
}

View file

@ -0,0 +1,46 @@
package org.betterx.bclib.client.gui.gridlayout;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.resources.ResourceLocation;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
@Environment(EnvType.CLIENT)
public class GridImageCell extends GridCell {
GridImageCell(ResourceLocation location,
double width,
GridLayout.GridValueType widthType,
double height,
float alpha,
int uvLeft,
int uvTop,
int uvWidth,
int uvHeight,
int resourceWidth,
int resourceHeight) {
super(width, height, widthType, null, (poseStack, transform, context) -> {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderTexture(0, location);
RenderSystem.enableBlend();
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA,
GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, alpha);
GuiComponent.blit(poseStack,
transform.left,
transform.top,
transform.width,
transform.height,
uvLeft,
uvTop,
uvWidth,
uvHeight,
resourceWidth,
resourceHeight);
});
}
}

View file

@ -0,0 +1,220 @@
package org.betterx.bclib.client.gui.gridlayout;
import net.minecraft.client.gui.components.AbstractWidget;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import com.mojang.blaze3d.vertex.PoseStack;
import org.betterx.bclib.client.gui.gridlayout.GridLayout.GridValueType;
import org.betterx.bclib.interfaces.TriConsumer;
import org.betterx.bclib.util.Pair;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Function;
@Environment(EnvType.CLIENT)
abstract class GridCellDefinition {
public final float width;
public final GridLayout.GridValueType widthType;
public GridCellDefinition(double width, GridLayout.GridValueType widthType) {
this.width = (float) width;
this.widthType = widthType;
}
public int calculateWidth(final int parentWidth) {
if (widthType == GridLayout.GridValueType.CONSTANT) {
return (int) this.width;
} else if (widthType == GridValueType.PERCENTAGE) {
return (int) (this.width * parentWidth);
} else {
return 0;
}
}
final GridElement buildElement(final int parentWidth,
final int autoWidth,
final float autoWidthSum,
int left,
final int top,
final List<GridElement> collector) {
final int width = widthType == GridValueType.FILL
? (int) ((this.width / autoWidthSum) * autoWidth)
: calculateWidth(parentWidth);
final GridElement el = buildElementAt(left, top, width, collector);
if (collector != null) {
collector.add(el);
}
return el;
}
abstract protected GridElement buildElementAt(int left, int top, int width, final List<GridElement> collector);
}
@Environment(EnvType.CLIENT)
class GridElement extends GridTransform {
final Function<GridTransform, Object> componentPlacer;
final TriConsumer<PoseStack, GridTransform, Object> customRender;
Object renderContext;
GridElement(int left,
int top,
int width,
int height,
Function<GridTransform, Object> componentPlacer,
TriConsumer<PoseStack, GridTransform, Object> customRender) {
super(left, top, width, height);
this.componentPlacer = componentPlacer;
this.customRender = customRender;
}
GridElement(int left, int top, int width, int height) {
this(left, top, width, height, null, null);
}
GridTransform transformWithPadding(int leftPadding, int topPadding) {
return new GridTransform(left + leftPadding, top + topPadding, width, height);
}
}
@Environment(EnvType.CLIENT)
abstract class GridContainer extends GridCellDefinition {
protected List<GridCellDefinition> cells;
public GridContainer(double width) {
this(width, GridLayout.GridValueType.CONSTANT);
}
GridContainer(double width, GridLayout.GridValueType widthType) {
super(width, widthType);
cells = new LinkedList<>();
}
}
@Environment(EnvType.CLIENT)
public class GridLayout extends GridColumn {
public static final int COLOR_WHITE = 0xFFFFFFFF;
public static final int COLOR_RED = 0xFFDB1F48;
public static final int COLOR_CYAN = 0xFF01949A;
public static final int COLOR_GREEN = 0xFF00FF00;
public static final int COLOR_DARK_GREEN = 0xFF007F00;
public static final int COLOR_YELLOW = 0xFFFAD02C;
public static final int COLOR_BLUE = 0xFF0000FF;
public static final int COLOR_GRAY = 0xFF7F7F7F;
public final GridScreen screen;
public final int screenHeight;
public final int sidePadding;
public final int initialTopPadding;
public final boolean centerVertically;
private int height;
private int topPadding;
private List<GridElement> elements;
public GridLayout(GridScreen screen) {
this(screen, 0, true);
}
public GridLayout(GridScreen screen, int topPadding, boolean centerVertically) {
this(screen, topPadding, 20, centerVertically);
}
public GridLayout(GridScreen screen, int topPadding, int sidePadding, boolean centerVertically) {
super(screen.width - 2 * sidePadding, GridValueType.CONSTANT);
this.screen = screen;
this.screenHeight = screen.height;
height = 0;
this.topPadding = topPadding;
this.sidePadding = sidePadding;
this.initialTopPadding = topPadding;
this.centerVertically = centerVertically;
}
public int getHeight() {
return height;
}
public int getTopPadding() {
return topPadding;
}
void buildLayout() {
elements = new LinkedList<>();
GridElement el = this.buildElement((int) this.width, 0, 1, 0, 0, elements);
this.height = el.height;
if (centerVertically && el.height + initialTopPadding < screenHeight) {
topPadding = (screenHeight - el.height) >> 1;
} else {
topPadding = initialTopPadding;
}
}
public List<Pair<AbstractWidget, Integer>> movableWidgets = new LinkedList<>();
public void finalizeLayout() {
buildLayout();
elements
.stream()
.filter(element -> element.componentPlacer != null)
.forEach(element -> {
final GridTransform transform = element.transformWithPadding(sidePadding, topPadding);
final Object context = element.componentPlacer.apply(transform);
if (element.customRender != null) {
element.renderContext = context;
} else if (context instanceof AbstractWidget) {
final AbstractWidget widget = (AbstractWidget) context;
movableWidgets.add(new Pair(widget, widget.y));
screen.addRenderableWidget(widget);
}
});
}
public void render(PoseStack poseStack) {
if (elements == null) return;
elements
.stream()
.filter(element -> element.customRender != null)
.forEach(element -> element.customRender.accept(poseStack,
element.transformWithPadding(sidePadding, topPadding),
element.renderContext));
}
public enum VerticalAlignment {
TOP, CENTER, BOTTOM
}
public enum Alignment {
LEFT, CENTER, RIGHT
}
/**
* Determines how a measurement value is interpreted
*/
public enum GridValueType {
/**
* The value is a constant pixel size
*/
CONSTANT,
/**
* The Value is relative to the parent size
*/
PERCENTAGE,
/**
* The value will be set to fill up the remaining space (i.e. when this is applied to a width of a row element,
* a {@link #FILL}-type may be used to right align (FILL - CONSTANT) or center (FILL - CONSTANT - FILL) elements.
*/
FILL,
/**
* Calculate size based on child-elements
*/
INHERIT
}
}

View file

@ -0,0 +1,75 @@
package org.betterx.bclib.client.gui.gridlayout;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.components.MultiLineLabel;
import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import java.util.List;
@Environment(EnvType.CLIENT)
public class GridMessageCell extends GridCell {
private final Font font;
private Component text;
private MultiLineLabel lastLabel;
private GridTransform lastTransform;
GridMessageCell(double width,
GridLayout.GridValueType widthType,
GridLayout.Alignment contentAlignment,
Font font,
Component text) {
this(width, widthType, contentAlignment, font, text, GridLayout.COLOR_WHITE);
}
GridMessageCell(double width,
GridLayout.GridValueType widthType,
GridLayout.Alignment contentAlignment,
Font font,
Component text,
int color) {
super(width, -1, widthType, null, null);
this.font = font;
this.text = text;
customRender = (poseStack, transform, context) -> {
//MultiLineLabel label = (MultiLineLabel) context;
if (contentAlignment == GridLayout.Alignment.CENTER) {
lastLabel.renderCentered(poseStack,
transform.width / 2 + transform.left,
transform.top,
font.lineHeight,
color);
} else if (contentAlignment == GridLayout.Alignment.LEFT) {
lastLabel.renderLeftAligned(poseStack, transform.left, transform.top, font.lineHeight, color);
}
};
}
public void setText(Component text) {
this.text = text;
if (lastTransform != null) {
create(lastTransform);
}
}
private MultiLineLabel getLabel(GridTransform transform) {
return lastLabel;
}
protected void create(GridTransform transform) {
this.lastTransform = transform;
this.lastLabel = MultiLineLabel.create(font, text, transform.width);
}
@Override
protected GridElement buildElementAt(int left, int top, int width, List<GridElement> collector) {
create(new GridTransform(left, top, width, 0));
int promptLines = this.lastLabel.getLineCount() + 1;
int height = promptLines * 9;
return new GridElement(left, top, width, height, this::getLabel, customRender);
}
}

View file

@ -0,0 +1,407 @@
package org.betterx.bclib.client.gui.gridlayout;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.Button.OnPress;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
@Environment(EnvType.CLIENT)
public class GridRow extends GridContainer {
public final GridLayout.VerticalAlignment alignment;
GridRow(double width) {
this(width, GridLayout.VerticalAlignment.TOP);
}
GridRow(double width, GridLayout.GridValueType widthType) {
this(width, widthType, GridLayout.VerticalAlignment.CENTER);
}
GridRow(double width, GridLayout.VerticalAlignment alignment) {
super(width);
this.alignment = alignment;
}
GridRow(double width, GridLayout.GridValueType widthType, GridLayout.VerticalAlignment alignment) {
super(width, widthType);
this.alignment = alignment;
}
public GridColumn addColumn(double width, GridLayout.GridValueType widthType) {
GridColumn cell = new GridColumn(width, widthType);
this.cells.add(cell);
return cell;
}
public GridCell addComponent(double height, Function<GridTransform, Object> componentPlacer) {
return addComponent(1.0, GridLayout.GridValueType.PERCENTAGE, height, componentPlacer);
}
public GridCell addComponent(double width,
GridLayout.GridValueType widthType,
double height,
Function<GridTransform, Object> componentPlacer) {
GridCell cell = new GridCell(width, height, widthType, componentPlacer, null);
this.cells.add(cell);
return cell;
}
public GridCell addButton(Component text, double height, OnPress onPress) {
return addButton(text, 1.0, GridLayout.GridValueType.PERCENTAGE, height, onPress);
}
public GridCell addButton(Component text, float alpha, double height, OnPress onPress) {
return addButton(text, alpha, 1.0, GridLayout.GridValueType.PERCENTAGE, height, onPress);
}
public GridCell addButton(Component text, double height, Font font, OnPress onPress) {
return addButton(text, 1.0f, height, font, onPress);
}
public GridCell addButton(Component text, float alpha, double height, Font font, OnPress onPress) {
final int width = font.width(text.getVisualOrderText()) + 24;
return addButton(text, alpha, width, GridLayout.GridValueType.CONSTANT, height, onPress);
}
public GridCell addButton(Component text,
double width,
GridLayout.GridValueType widthType,
double height,
OnPress onPress) {
return addButton(text, 1.0f, width, widthType, height, onPress);
}
public GridCell addButton(Component text,
float alpha,
double width,
GridLayout.GridValueType widthType,
double height,
OnPress onPress) {
GridCell cell = new GridCell(width, height, widthType, (transform) -> {
Button customButton = new Button(transform.left,
transform.top,
transform.width,
transform.height,
text,
onPress);
customButton.setAlpha(alpha);
return customButton;
}, null);
this.cells.add(cell);
return cell;
}
public GridCheckboxCell addCheckbox(Component text, boolean checked, Font font, Consumer<Boolean> onChange) {
final int width = font.width(text.getVisualOrderText()) + 24 + 2 * 12;
return addCheckbox(text, checked, width, widthType, onChange);
}
public GridCheckboxCell addCheckbox(Component text, boolean checked, double width,
GridLayout.GridValueType widthType, Consumer<Boolean> onChange) {
GridCheckboxCell cell = new GridCheckboxCell(text, checked, 1.0f, width, widthType, 20, onChange);
this.cells.add(cell);
return cell;
}
public GridCheckboxCell addCheckbox(Component text, boolean checked, int height) {
return addCheckbox(text, checked, 1.0f, height);
}
public GridCheckboxCell addCheckbox(Component text, boolean checked, float alpha, int height) {
return addCheckbox(text, checked, alpha, 1.0, GridLayout.GridValueType.PERCENTAGE, height);
}
public GridCheckboxCell addCheckbox(Component text, boolean checked, int height, Font font) {
return addCheckbox(text, checked, 1.0f, height, font);
}
public GridCheckboxCell addCheckbox(Component text, boolean checked, float alpha, int height, Font font) {
final int width = font.width(text.getVisualOrderText()) + 24 + 2 * 12;
return addCheckbox(text, checked, alpha, width, GridLayout.GridValueType.CONSTANT, height);
}
public GridCheckboxCell addCheckbox(Component text,
boolean checked,
double width,
GridLayout.GridValueType widthType,
int height) {
return addCheckbox(text, checked, 1.0f, width, widthType, height);
}
public GridCheckboxCell addCheckbox(Component text,
boolean checked,
float alpha,
double width,
GridLayout.GridValueType widthType,
int height) {
GridCheckboxCell cell = new GridCheckboxCell(text, checked, alpha, width, widthType, height);
this.cells.add(cell);
return cell;
}
public GridCustomRenderCell addCustomRender(GridCustomRenderCell cell) {
this.cells.add(cell);
return cell;
}
public GridCell addImage(ResourceLocation location, int width, int height) {
return addImage(location, 1.0f, width, height);
}
public GridCell addImage(ResourceLocation location, float alpha, int width, int height) {
return addImage(location,
alpha,
width,
GridLayout.GridValueType.CONSTANT,
height,
0,
0,
width,
height,
width,
height);
}
public GridCell addImage(ResourceLocation location,
double width,
GridLayout.GridValueType widthType,
int height,
int resourceWidth,
int resourceHeight) {
return addImage(location, 1.0f, width, widthType, height, resourceWidth, resourceHeight);
}
public GridCell addImage(ResourceLocation location,
float alpha,
double width,
GridLayout.GridValueType widthType,
int height,
int resourceWidth,
int resourceHeight) {
return addImage(location,
alpha,
width,
widthType,
height,
0,
0,
resourceWidth,
resourceWidth,
resourceWidth,
resourceHeight);
}
public GridCell addImage(ResourceLocation location,
double width,
GridLayout.GridValueType widthType,
int height,
int uvLeft,
int uvTop,
int uvWidth,
int uvHeight,
int resourceWidth,
int resourceHeight) {
return addImage(location,
1.0f,
width,
widthType,
height,
uvLeft,
uvTop,
uvWidth,
uvHeight,
resourceWidth,
resourceHeight);
}
public GridCell addImage(ResourceLocation location,
float alpha,
double width,
GridLayout.GridValueType widthType,
int height,
int uvLeft,
int uvTop,
int uvWidth,
int uvHeight,
int resourceWidth,
int resourceHeight) {
GridCell cell = new GridImageCell(location,
width,
widthType,
height,
alpha,
uvLeft,
uvTop,
uvWidth,
uvHeight,
resourceWidth,
resourceHeight);
this.cells.add(cell);
return cell;
}
public GridColumn addFiller() {
return addFiller(1);
}
public GridColumn addFiller(float portion) {
GridColumn cell = new GridColumn(portion, GridLayout.GridValueType.FILL);
this.cells.add(cell);
return cell;
}
public void addSpacer() {
addSpacer(12);
}
public void addSpacer(int width) {
GridCell cell = new GridCell(width, 0, GridLayout.GridValueType.CONSTANT, null, null);
this.cells.add(cell);
}
public GridMessageCell addMessage(Component text, Font font, GridLayout.Alignment contentAlignment) {
return addMessage(text, font, GridLayout.COLOR_WHITE, contentAlignment);
}
public GridMessageCell addMessage(Component text, Font font, int color, GridLayout.Alignment contentAlignment) {
return addMessage(text, 1.0, GridLayout.GridValueType.PERCENTAGE, font, color, contentAlignment);
}
public GridMessageCell addMessage(Component text,
double width,
GridLayout.GridValueType widthType,
Font font,
GridLayout.Alignment contentAlignment) {
return addMessage(text, width, widthType, font, GridLayout.COLOR_WHITE, contentAlignment);
}
public GridMessageCell addMessage(Component text,
double width,
GridLayout.GridValueType widthType,
Font font,
int color,
GridLayout.Alignment contentAlignment) {
GridMessageCell cell = new GridMessageCell(width, widthType, contentAlignment, font, text, color);
this.cells.add(cell);
return cell;
}
public GridStringCell addString(Component text, GridScreen parent) {
return this.addString(text, GridLayout.COLOR_WHITE, parent);
}
public GridStringCell addString(Component text, int color, GridScreen parent) {
final int width = parent.getWidth(text);
return this.addString(text,
width,
GridLayout.GridValueType.CONSTANT,
color,
GridLayout.Alignment.CENTER,
parent);
}
public GridStringCell addString(Component text, GridLayout.Alignment contentAlignment, GridScreen parent) {
return this.addString(text, GridLayout.COLOR_WHITE, contentAlignment, parent);
}
public GridStringCell addString(Component text,
int color,
GridLayout.Alignment contentAlignment,
GridScreen parent) {
return this.addString(text, 1.0, GridLayout.GridValueType.PERCENTAGE, color, contentAlignment, parent);
}
public GridStringCell addString(Component text,
double width,
GridLayout.GridValueType widthType,
GridLayout.Alignment contentAlignment,
GridScreen parent) {
return addString(text, width, widthType, GridLayout.COLOR_WHITE, contentAlignment, parent);
}
public GridStringCell addString(Component text,
double width,
GridLayout.GridValueType widthType,
int color,
GridLayout.Alignment contentAlignment,
GridScreen parent) {
GridStringCell cell = new GridStringCell(width,
widthType,
parent.getFont().lineHeight,
contentAlignment,
parent,
text,
color);
this.cells.add(cell);
return cell;
}
@Override
protected GridElement buildElementAt(int inLeft, int top, int width, final List<GridElement> collector) {
int height = 0;
int left = inLeft;
if (widthType == GridLayout.GridValueType.INHERIT) {
final int originalWidth = width;
width = cells.stream()
.filter(row -> row.widthType == GridLayout.GridValueType.CONSTANT || row.widthType == GridLayout.GridValueType.INHERIT)
.map(row -> row.buildElement(0, 0, 1, 0, 0, null).width)
.reduce(0, (p, c) -> p + c);
}
final int inheritedWidth = width;
final int fixedWidth = cells.stream()
.filter(col -> col.widthType != GridLayout.GridValueType.FILL)
.map(col -> col.calculateWidth(inheritedWidth))
.reduce(0, (p, c) -> p + c);
final float autoWidthSum = cells.stream()
.filter(col -> col.widthType == GridLayout.GridValueType.FILL)
.map(col -> col.width)
.reduce(0.0f, (p, c) -> p + c);
final int autoWidth = width - fixedWidth;
if (alignment == GridLayout.VerticalAlignment.TOP) {
for (GridCellDefinition col : cells) {
GridElement element = col.buildElement(width, autoWidth, autoWidthSum, left, top, collector);
left += element.width;
height = Math.max(height, element.height);
}
} else {
//first iteration will collect heights, second one will transform top position for alignment
Map<GridCellDefinition, GridElement> cache = new HashMap<>();
for (GridCellDefinition col : cells) {
GridElement element = col.buildElement(width, autoWidth, autoWidthSum, left, top, null);
left += element.width;
height = Math.max(height, element.height);
cache.put(col, element);
}
left = inLeft;
for (GridCellDefinition col : cells) {
GridElement element = cache.get(col);
final int topOffset = (alignment == GridLayout.VerticalAlignment.BOTTOM)
? (height - element.height)
: (height - element.height) >> 1;
element = col.buildElement(width, autoWidth, autoWidthSum, left, top + topOffset, collector);
left += element.width;
}
}
return new GridElement(inLeft, top, width, height);
}
}

View file

@ -0,0 +1,265 @@
package org.betterx.bclib.client.gui.gridlayout;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.components.Widget;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.narration.NarratableEntry;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.util.Mth;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT)
public abstract class GridScreen extends Screen {
protected GridLayout grid = null;
public final int topPadding;
public final int sidePadding;
public final boolean centerVertically;
@Nullable
public final Screen parent;
protected int scrollPos = 0;
public GridScreen(Component title) {
this(null, title);
}
public GridScreen(@Nullable Screen parent, Component title) {
this(parent, title, 0, true);
}
public GridScreen(Component title, int topPadding, boolean centerVertically) {
this(null, title, topPadding, 20, centerVertically);
}
public GridScreen(@Nullable Screen parent, Component title, int topPadding, boolean centerVertically) {
this(parent, title, topPadding, 20, centerVertically);
}
public GridScreen(Component title, int topPadding, int sidePadding, boolean centerVertically) {
this(null, title, topPadding, sidePadding, centerVertically);
}
public GridScreen(@Nullable Screen parent,
Component title,
int topPadding,
int sidePadding,
boolean centerVertically) {
super(title);
this.parent = parent;
this.topPadding = topPadding;
this.sidePadding = sidePadding;
this.centerVertically = centerVertically;
}
@Override
public void onClose() {
this.minecraft.setScreen(parent);
}
public Font getFont() {
return this.font;
}
@Override
public boolean isPauseScreen() {
return true;
}
@Override
public <T extends GuiEventListener & Widget & NarratableEntry> T addRenderableWidget(T guiEventListener) {
return super.addRenderableWidget(guiEventListener);
}
protected void addTitle() {
grid.addRow().addString(this.title, GridLayout.Alignment.CENTER, this);
grid.addSpacerRow(15);
}
final protected void init() {
super.init();
this.grid = new GridLayout(this, this.topPadding, this.sidePadding, this.centerVertically);
addTitle();
initLayout();
grid.finalizeLayout();
}
protected abstract void initLayout();
protected void renderScreen(PoseStack poseStack, int i, int j, float f) {
super.render(poseStack, i, j, f);
}
public void render(PoseStack poseStack, int i, int j, float f) {
this.renderDirtBackground(i);
renderGrid(poseStack);
super.render(poseStack, i, j, f);
}
protected void renderGrid(PoseStack poseStack) {
if (grid != null) {
if (isScrollable()) {
for (var item : grid.movableWidgets) {
item.first.y = item.second + scrollPos;
}
renderScroll(poseStack);
poseStack.pushPose();
poseStack.translate(0, scrollPos, 0);
grid.render(poseStack);
poseStack.popPose();
} else {
grid.render(poseStack);
}
}
}
public static int getWidth(Component text, Font font) {
return font.width(text.getVisualOrderText());
}
public int getWidth(Component text) {
return getWidth(text, getFont());
}
public void setScrollPos(int sp) {
scrollPos = Math.max(getMaxScrollPos(), Math.min(0, sp));
}
public int getScrollPos() {
return scrollPos;
}
public int getScrollHeight() {
if (grid != null) return grid.getHeight() + topPadding;
return height;
}
public int getMaxScrollPos() {
return height - (getScrollHeight() + topPadding);
}
public boolean isScrollable() {
return height < getScrollHeight();
}
public boolean isMouseOverScroller(double x, double y) {
return y >= 0 && y <= height && x >= width - SCROLLER_WIDTH && x <= width;
}
private boolean scrolling = false;
protected void updateScrollingState(double x, double y, int i) {
this.scrolling = i == 0 && x >= width - SCROLLER_WIDTH && x < width;
}
private static final int SCROLLER_WIDTH = 6;
private void renderScroll(PoseStack poseStack) {
final int y1 = height;
final int y0 = 0;
final int yd = y1 - y0;
final int maxPosition = getScrollHeight() + topPadding;
final int x0 = width - SCROLLER_WIDTH;
final int x1 = width;
Tesselator tesselator = Tesselator.getInstance();
BufferBuilder bufferBuilder = tesselator.getBuilder();
RenderSystem.disableTexture();
RenderSystem.setShader(GameRenderer::getPositionColorShader);
int widgetHeight = (int) ((float) (yd * yd) / (float) maxPosition);
widgetHeight = Mth.clamp(widgetHeight, 32, yd - 8);
float relPos = (float) this.getScrollPos() / this.getMaxScrollPos();
int top = (int) (relPos * (yd - widgetHeight)) + y0;
if (top < y0) {
top = y0;
}
bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
//scroller background
bufferBuilder.vertex(x0, y1, 0.0D).color(0, 0, 0, 255).endVertex();
bufferBuilder.vertex(x1, y1, 0.0D).color(0, 0, 0, 255).endVertex();
bufferBuilder.vertex(x1, y0, 0.0D).color(0, 0, 0, 255).endVertex();
bufferBuilder.vertex(x0, y0, 0.0D).color(0, 0, 0, 255).endVertex();
//scroll widget shadow
bufferBuilder.vertex(x0, top + widgetHeight, 0.0D).color(128, 128, 128, 255).endVertex();
bufferBuilder.vertex(x1, top + widgetHeight, 0.0D).color(128, 128, 128, 255).endVertex();
bufferBuilder.vertex(x1, top, 0.0D).color(128, 128, 128, 255).endVertex();
bufferBuilder.vertex(x0, top, 0.0D).color(128, 128, 128, 255).endVertex();
//scroll widget
bufferBuilder.vertex(x0, top + widgetHeight - 1, 0.0D)
.color(192, 192, 192, 255)
.endVertex();
bufferBuilder.vertex(x1 - 1, top + widgetHeight - 1, 0.0D)
.color(192, 192, 192, 255)
.endVertex();
bufferBuilder.vertex(x1 - 1, top, 0.0D).color(192, 192, 192, 255).endVertex();
bufferBuilder.vertex(x0, top, 0.0D).color(192, 192, 192, 255).endVertex();
tesselator.end();
}
public boolean mouseClicked(double x, double y, int i) {
this.updateScrollingState(x, y, i);
if (this.scrolling) {
return true;
} else {
return super.mouseClicked(x, y, i);
}
}
public boolean mouseDragged(double xAbs, double yAbs, int i, double dX, double dY) {
if (super.mouseDragged(xAbs, yAbs, i, dX, dY)) {
return true;
} else if (i == 0 && this.scrolling) {
if (yAbs < 0) {
this.setScrollPos(0);
} else if (yAbs > height) {
this.setScrollPos(this.getMaxScrollPos());
} else {
this.setScrollPos((int) (this.getScrollPos() - dY * 2));
}
return true;
} else {
return false;
}
}
public boolean mouseScrolled(double d, double e, double f) {
if (isScrollable()) {
setScrollPos((int) (scrollPos + f * 10));
}
return true;
}
public boolean keyPressed(int keyCode, int j, int k) {
if (super.keyPressed(keyCode, j, k)) {
return true;
} else if (keyCode == 264) {
this.mouseScrolled(0, -1.0f, 0);
return true;
} else if (keyCode == 265) {
this.mouseScrolled(0, 1.0, 0);
return true;
} else {
return false;
}
}
}

View file

@ -0,0 +1,49 @@
package org.betterx.bclib.client.gui.gridlayout;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class GridStringCell extends GridCell {
private Component text;
GridStringCell(double width,
GridLayout.GridValueType widthType,
int height,
GridLayout.Alignment contentAlignment,
GridScreen parent,
Component text) {
this(width, widthType, height, contentAlignment, parent, text, GridLayout.COLOR_WHITE);
}
GridStringCell(double width,
GridLayout.GridValueType widthType,
int height,
GridLayout.Alignment contentAlignment,
GridScreen parent,
Component text,
int color) {
super(width, height, widthType, null, null);
this.text = text;
this.customRender = (poseStack, transform, context) -> {
if (contentAlignment == GridLayout.Alignment.CENTER) {
GuiComponent.drawCenteredString(poseStack,
parent.getFont(),
this.text,
transform.width / 2 + transform.left,
transform.top,
color);
} else if (contentAlignment == GridLayout.Alignment.LEFT) {
GuiComponent.drawString(poseStack, parent.getFont(), this.text, transform.left, transform.top, color);
}
};
}
public void setText(Component newText) {
this.text = newText;
}
}

View file

@ -0,0 +1,25 @@
package org.betterx.bclib.client.gui.gridlayout;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class GridTransform {
public final int left;
public final int top;
public final int width;
public final int height;
GridTransform(int left, int top, int width, int height) {
this.left = left;
this.top = top;
this.width = width;
this.height = height;
}
@Override
public String toString() {
return "{" + "left=" + left + ", top=" + top + ", width=" + width + ", height=" + height + '}';
}
}

View file

@ -0,0 +1,6 @@
package org.betterx.bclib.client.gui.gridlayout;
public interface GridWidgetWithEnabledState {
boolean isEnabled();
void setEnabled(boolean enabled);
}

View file

@ -0,0 +1,12 @@
package org.betterx.bclib.client.gui.modmenu;
import org.betterx.bclib.integration.modmenu.ModMenuIntegration;
@Deprecated()
public class EntryPoint extends ModMenuIntegration {
public static final Object entrypointObject = createEntrypoint(new EntryPoint());
public EntryPoint() {
super(MainScreen::new);
}
}

View file

@ -0,0 +1,102 @@
package org.betterx.bclib.client.gui.modmenu;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import org.betterx.bclib.client.gui.gridlayout.*;
import org.betterx.bclib.config.ConfigKeeper;
import org.betterx.bclib.config.Configs;
import org.betterx.bclib.config.NamedPathConfig;
import org.betterx.bclib.config.NamedPathConfig.ConfigTokenDescription;
import org.betterx.bclib.config.NamedPathConfig.DependendConfigToken;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;
import org.jetbrains.annotations.Nullable;
public class MainScreen extends GridScreen {
public MainScreen(@Nullable Screen parent) {
super(parent, Component.translatable("title.bclib.modmenu.main"), 10, false);
}
protected <T> Component getComponent(NamedPathConfig config, ConfigTokenDescription<T> option, String type) {
return Component.translatable(type + ".config." + config.configID + option.getPath());
}
Map<GridWidgetWithEnabledState, Supplier<Boolean>> dependentWidgets = new HashMap<>();
protected void updateEnabledState() {
dependentWidgets.forEach((cb, supl) -> cb.setEnabled(supl.get()));
}
@SuppressWarnings("unchecked")
protected <T> void addRow(GridColumn grid, NamedPathConfig config, ConfigTokenDescription<T> option) {
if (ConfigKeeper.BooleanEntry.class.isAssignableFrom(option.token.type)) {
addCheckbox(grid, config, (ConfigTokenDescription<Boolean>) option);
}
grid.addSpacerRow(2);
}
protected void addCheckbox(GridColumn grid, NamedPathConfig config, ConfigTokenDescription<Boolean> option) {
if (option.topPadding > 0) {
grid.addSpacerRow(option.topPadding);
}
GridRow row = grid.addRow();
if (option.leftPadding > 0) {
row.addSpacer(option.leftPadding);
}
GridCheckboxCell cb = row.addCheckbox(getComponent(config, option, "title"),
config.getRaw(option.token),
font,
(state) -> {
config.set(option.token, state);
updateEnabledState();
});
if (option.token instanceof DependendConfigToken) {
dependentWidgets.put(cb, () -> option.token.dependenciesTrue(config));
cb.setEnabled(option.token.dependenciesTrue(config));
}
}
@Override
public boolean shouldCloseOnEsc() {
return false;
}
@Override
protected void initLayout() {
final int BUTTON_HEIGHT = 20;
Configs.GENERATOR_CONFIG.getAllOptions()
.stream()
.filter(o -> !o.hidden)
.forEach(o -> addRow(grid, Configs.GENERATOR_CONFIG, o));
grid.addSpacerRow(12);
Configs.MAIN_CONFIG.getAllOptions()
.stream()
.filter(o -> !o.hidden)
.forEach(o -> addRow(grid, Configs.MAIN_CONFIG, o));
grid.addSpacerRow(12);
Configs.CLIENT_CONFIG.getAllOptions()
.stream()
.filter(o -> !o.hidden)
.forEach(o -> addRow(grid, Configs.CLIENT_CONFIG, o));
grid.addSpacerRow(15);
GridRow row = grid.addRow();
row.addFiller();
row.addButton(CommonComponents.GUI_DONE, BUTTON_HEIGHT, font, (button) -> {
Configs.CLIENT_CONFIG.saveChanges();
Configs.GENERATOR_CONFIG.saveChanges();
Configs.MAIN_CONFIG.saveChanges();
onClose();
});
grid.addSpacerRow(10);
}
}

View file

@ -0,0 +1,10 @@
package org.betterx.bclib.client.gui.screens;
import net.minecraft.network.chat.Component;
public interface AtomicProgressListener {
void incAtomic(int maxProgress);
void resetAtomic();
void stop();
void progressStage(Component component);
}

View file

@ -0,0 +1,59 @@
package org.betterx.bclib.client.gui.screens;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.betterx.bclib.BCLib;
import org.betterx.bclib.client.gui.gridlayout.GridLayout;
import org.betterx.bclib.client.gui.gridlayout.GridRow;
import org.betterx.bclib.client.gui.gridlayout.GridScreen;
import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT)
abstract class BCLibScreen extends GridScreen {
static final ResourceLocation BCLIB_LOGO_LOCATION = new ResourceLocation(BCLib.MOD_ID, "icon.png");
public BCLibScreen(Component title) {
super(title);
}
public BCLibScreen(@Nullable Screen parent, Component title) {
super(parent, title);
}
public BCLibScreen(Component title, int topPadding, boolean centerVertically) {
super(title, topPadding, 20, centerVertically);
}
public BCLibScreen(@Nullable Screen parent, Component title, int topPadding, boolean centerVertically) {
super(parent, title, topPadding, centerVertically);
}
public BCLibScreen(Component title, int topPadding, int sidePadding, boolean centerVertically) {
super(title, topPadding, sidePadding, centerVertically);
}
public BCLibScreen(@Nullable Screen parent,
Component title,
int topPadding,
int sidePadding,
boolean centerVertically) {
super(parent, title, topPadding, sidePadding, centerVertically);
}
protected void addTitle() {
GridRow row = grid.addRow(GridLayout.VerticalAlignment.CENTER);
row.addFiller();
row.addImage(BCLIB_LOGO_LOCATION, 24, GridLayout.GridValueType.CONSTANT, 24, 512, 512);
row.addSpacer(4);
row.addString(this.title, this);
row.addFiller();
grid.addSpacerRow(15);
}
}

View file

@ -0,0 +1,72 @@
package org.betterx.bclib.client.gui.screens;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.betterx.bclib.client.gui.gridlayout.GridCheckboxCell;
import org.betterx.bclib.client.gui.gridlayout.GridLayout;
import org.betterx.bclib.client.gui.gridlayout.GridRow;
import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT)
public class ConfirmFixScreen extends BCLibScreen {
protected final ConfirmFixScreen.Listener listener;
private final Component description;
protected int id;
public ConfirmFixScreen(@Nullable Screen parent, ConfirmFixScreen.Listener listener) {
super(parent, Component.translatable("bclib.datafixer.backupWarning.title"));
this.listener = listener;
this.description = Component.translatable("bclib.datafixer.backupWarning.message");
}
protected void initLayout() {
final int BUTTON_HEIGHT = 20;
grid.addRow().addMessage(this.description, this.font, GridLayout.Alignment.CENTER);
grid.addSpacerRow();
GridRow row = grid.addRow();
GridCheckboxCell backup = row.addCheckbox(Component.translatable("bclib.datafixer.backupWarning.backup"),
true,
BUTTON_HEIGHT,
this.font);
grid.addSpacerRow(10);
row = grid.addRow();
GridCheckboxCell fix = row.addCheckbox(Component.translatable("bclib.datafixer.backupWarning.fix"),
true,
BUTTON_HEIGHT,
this.font);
grid.addSpacerRow(20);
row = grid.addRow();
row.addFiller();
row.addButton(CommonComponents.GUI_CANCEL, BUTTON_HEIGHT, this.font, (button) -> {
onClose();
});
row.addSpacer();
row.addButton(CommonComponents.GUI_PROCEED, BUTTON_HEIGHT, this.font, (button) -> {
this.listener.proceed(backup.isChecked(), fix.isChecked());
});
row.addFiller();
}
public boolean shouldCloseOnEsc() {
return true;
}
@Environment(EnvType.CLIENT)
public interface Listener {
void proceed(boolean createBackup, boolean applyPatches);
}
}

View file

@ -0,0 +1,52 @@
package org.betterx.bclib.client.gui.screens;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.betterx.bclib.client.gui.gridlayout.GridLayout;
import org.betterx.bclib.client.gui.gridlayout.GridRow;
@Environment(EnvType.CLIENT)
public class ConfirmRestartScreen extends BCLibScreen {
private final Component description;
private final ConfirmRestartScreen.Listener listener;
public ConfirmRestartScreen(ConfirmRestartScreen.Listener listener) {
this(listener, null);
}
public ConfirmRestartScreen(ConfirmRestartScreen.Listener listener, Component message) {
super(Component.translatable("title.bclib.confirmrestart"));
this.description = message == null ? Component.translatable("message.bclib.confirmrestart") : message;
this.listener = listener;
}
protected void initLayout() {
final int BUTTON_HEIGHT = 20;
grid.addRow().addMessage(this.description, this.font, GridLayout.Alignment.CENTER);
grid.addSpacerRow();
GridRow row = grid.addRow();
row.addFiller();
row.addButton(CommonComponents.GUI_PROCEED, BUTTON_HEIGHT, font, (button) -> {
listener.proceed();
});
row.addFiller();
}
public boolean shouldCloseOnEsc() {
return false;
}
@Environment(EnvType.CLIENT)
public interface Listener {
void proceed();
}
}

View file

@ -0,0 +1,62 @@
package org.betterx.bclib.client.gui.screens;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.betterx.bclib.client.gui.gridlayout.GridColumn;
import org.betterx.bclib.client.gui.gridlayout.GridLayout;
import org.betterx.bclib.client.gui.gridlayout.GridRow;
@Environment(EnvType.CLIENT)
public class LevelFixErrorScreen extends BCLibScreen {
private final String[] errors;
final Listener onContinue;
public LevelFixErrorScreen(Screen parent, String[] errors, Listener onContinue) {
super(parent, Component.translatable("title.bclib.datafixer.error"), 10, true);
this.errors = errors;
this.onContinue = onContinue;
}
@Override
protected void initLayout() {
grid.addSpacerRow();
grid.addRow()
.addMessage(Component.translatable("message.bclib.datafixer.error"), font, GridLayout.Alignment.CENTER);
grid.addSpacerRow(8);
GridRow row = grid.addRow();
row.addSpacer(10);
GridColumn col = row.addColumn(300, GridLayout.GridValueType.CONSTANT);
for (String error : errors) {
Component dash = Component.literal("-");
row = col.addRow();
row.addString(dash, this);
row.addSpacer(4);
row.addString(Component.literal(error), this);
}
grid.addSpacerRow(8);
row = grid.addRow();
row.addFiller();
row.addButton(Component.translatable("title.bclib.datafixer.error.continue"), 0.5f, 20, font, (n) -> {
onClose();
onContinue.doContinue(true);
});
row.addSpacer();
row.addButton(CommonComponents.GUI_CANCEL, 20, font, (n) -> {
this.minecraft.setScreen(null);
});
row.addFiller();
}
@Environment(EnvType.CLIENT)
public interface Listener {
void doContinue(boolean markFixed);
}
}

View file

@ -0,0 +1,256 @@
package org.betterx.bclib.client.gui.screens;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.loader.api.metadata.ModEnvironment;
import org.betterx.bclib.api.v2.dataexchange.handler.autosync.HelloClient;
import org.betterx.bclib.client.gui.gridlayout.GridColumn;
import org.betterx.bclib.client.gui.gridlayout.GridLayout;
import org.betterx.bclib.client.gui.gridlayout.GridRow;
import org.betterx.bclib.client.gui.gridlayout.GridScreen;
import org.betterx.bclib.util.ModUtil;
import org.betterx.bclib.util.PathUtil;
import org.betterx.bclib.util.Triple;
import java.util.*;
import java.util.stream.Collectors;
@Environment(EnvType.CLIENT)
public class ModListScreen extends BCLibScreen {
private final List<ModUtil.ModInfo> mods;
private final HelloClient.IServerModMap serverInfo;
private final Component description;
private final Component buttonTitle;
private static List<ModUtil.ModInfo> extractModList(Map<String, ModUtil.ModInfo> mods) {
List<ModUtil.ModInfo> list = new LinkedList<ModUtil.ModInfo>();
ModUtil.getMods().forEach((id, info) -> list.add(info));
return list;
}
public ModListScreen(Screen parent,
Component title,
Component description,
Map<String, ModUtil.ModInfo> mods,
HelloClient.IServerModMap serverInfo) {
this(parent, title, description, CommonComponents.GUI_BACK, mods, serverInfo);
}
public ModListScreen(Screen parent,
Component title,
Component description,
List<ModUtil.ModInfo> mods,
HelloClient.IServerModMap serverInfo) {
this(parent, title, description, CommonComponents.GUI_BACK, mods, serverInfo);
}
public ModListScreen(Screen parent,
Component title,
Component description,
Component button,
Map<String, ModUtil.ModInfo> mods,
HelloClient.IServerModMap serverInfo) {
this(parent, title, description, button, extractModList(mods), serverInfo);
}
public ModListScreen(Screen parent,
Component title,
Component description,
Component button,
List<ModUtil.ModInfo> mods,
HelloClient.IServerModMap serverInfo) {
super(parent, title, 10, true);
this.mods = mods;
this.serverInfo = serverInfo;
this.description = description;
this.buttonTitle = button;
}
public static List<String> localMissing(HelloClient.IServerModMap serverInfo) {
return serverInfo.keySet()
.stream()
.filter(modid -> !ModUtil.getMods()
.keySet()
.stream()
.filter(mod -> mod.equals(modid))
.findFirst()
.isPresent()).collect(Collectors.toList());
}
public static List<String> serverMissing(HelloClient.IServerModMap serverInfo) {
return ModUtil.getMods().entrySet()
.stream()
.filter(entry -> entry.getValue().metadata.getEnvironment() != ModEnvironment.CLIENT)
.map(entry -> entry.getKey())
.filter(modid -> !serverInfo.keySet()
.stream()
.filter(mod -> mod.equals(modid))
.findFirst()
.isPresent()).collect(Collectors.toList());
}
public static void addModDesc(GridColumn grid,
java.util.List<ModUtil.ModInfo> mods,
HelloClient.IServerModMap serverInfo,
GridScreen parent) {
final int STATE_OK = 6;
final int STATE_SERVER_MISSING_CLIENT_MOD = 5;
final int STATE_MISSING_NOT_OFFERED = 4;
final int STATE_VERSION_CLIENT_ONLY = 7;
final int STATE_VERSION_NOT_OFFERED = 3;
final int STATE_VERSION = 2;
final int STATE_SERVER_MISSING = 1;
final int STATE_MISSING = 0;
List<Triple<String, Integer, String>> items = new LinkedList<>();
if (serverInfo != null) {
serverInfo.keySet()
.stream()
.filter(modid -> !mods.stream()
.filter(mod -> mod.metadata.getId().equals(modid))
.findFirst()
.isPresent())
.forEach(modid -> {
HelloClient.OfferedModInfo nfo = serverInfo.get(modid);
String stateString = nfo.version();
if (nfo.size() > 0) {
stateString = "Version: " + stateString + ", Size: " + PathUtil.humanReadableFileSize(nfo.size());
}
if (nfo.canDownload()) {
stateString += ", offered by server";
}
items.add(new Triple<>(modid,
nfo.canDownload() ? STATE_MISSING : STATE_MISSING_NOT_OFFERED,
stateString));
});
}
mods.forEach(mod -> {
String serverVersion = null;
int serverSize = 0;
int state = STATE_OK;
if (serverInfo != null) {
final String modID = mod.metadata.getId();
HelloClient.OfferedModInfo data = serverInfo.get(modID);
if (data != null) {
final String modVer = data.version();
final int size = data.size();
if (!modVer.equals(mod.getVersion())) {
if (mod.metadata.getEnvironment() == ModEnvironment.CLIENT)
state = STATE_VERSION_CLIENT_ONLY;
else
state = data.canDownload() ? STATE_VERSION : STATE_VERSION_NOT_OFFERED;
serverVersion = modVer;
serverSize = size;
}
} else if (mod.metadata.getEnvironment() == ModEnvironment.CLIENT) {
state = STATE_SERVER_MISSING_CLIENT_MOD;
} else {
state = STATE_SERVER_MISSING;
}
}
String stateString = mod.metadata.getVersion().toString();
if (serverVersion != null) {
stateString = "Client: " + stateString;
stateString += ", Server: " + serverVersion;
if (serverSize > 0) {
stateString += ", Size: " + PathUtil.humanReadableFileSize(serverSize);
}
}
if (mod.metadata.getEnvironment() == ModEnvironment.CLIENT) {
stateString += ", client-only";
} else if (mod.metadata.getEnvironment() == ModEnvironment.SERVER) {
stateString += ", server-only";
}
items.add(new Triple<>(mod.metadata.getName(), state, stateString));
});
items.stream()
.sorted(Comparator.comparing(a -> a.second + a.first.toLowerCase(Locale.ROOT)))
.forEach(t -> {
final String name = t.first;
final int state = t.second;
final String stateString = t.third;
int color = GridLayout.COLOR_RED;
final String typeText;
if (state == STATE_VERSION || state == STATE_VERSION_NOT_OFFERED || state == STATE_VERSION_CLIENT_ONLY) {
typeText = "[VERSION]";
if (state == STATE_VERSION_NOT_OFFERED) {
color = GridLayout.COLOR_YELLOW;
} else if (state == STATE_VERSION_CLIENT_ONLY) {
color = GridLayout.COLOR_DARK_GREEN;
}
} else if (state == STATE_MISSING || state == STATE_MISSING_NOT_OFFERED) {
typeText = "[MISSING]";
if (state == STATE_MISSING_NOT_OFFERED) {
color = GridLayout.COLOR_YELLOW;
}
} else if (state == STATE_SERVER_MISSING || state == STATE_SERVER_MISSING_CLIENT_MOD) {
if (state == STATE_SERVER_MISSING_CLIENT_MOD) {
color = GridLayout.COLOR_CYAN;
typeText = "[OK]";
} else {
typeText = "[NOT ON SERVER]";
}
} else {
color = GridLayout.COLOR_DARK_GREEN;
typeText = "[OK]";
}
Component dash = Component.literal("-");
Component typeTextComponent = Component.literal(typeText);
GridRow row = grid.addRow();
row.addString(dash, parent);
row.addSpacer(4);
row.addString(Component.literal(name), parent);
row.addSpacer(4);
row.addString(typeTextComponent, color, parent);
if (!stateString.isEmpty()) {
row = grid.addRow();
row.addSpacer(4 + parent.getWidth(dash));
row.addString(Component.literal(stateString), GridLayout.COLOR_GRAY, parent);
}
grid.addSpacerRow();
});
}
@Override
protected void initLayout() {
if (description != null) {
grid.addSpacerRow();
grid.addRow().addMessage(description, font, GridLayout.Alignment.CENTER);
grid.addSpacerRow(8);
}
GridRow row = grid.addRow();
row.addSpacer(10);
GridColumn col = row.addColumn(200, GridLayout.GridValueType.CONSTANT);
addModDesc(col, mods, serverInfo, this);
grid.addSpacerRow(8);
row = grid.addRow();
row.addFiller();
row.addButton(buttonTitle, 20, font, (n) -> {
onClose();
});
row.addFiller();
}
}

View file

@ -0,0 +1,193 @@
package org.betterx.bclib.client.gui.screens;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.ProgressListener;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import org.betterx.bclib.BCLib;
import org.betterx.bclib.client.gui.gridlayout.*;
import java.util.concurrent.atomic.AtomicInteger;
import org.jetbrains.annotations.Nullable;
class ProgressLogoRender extends GridCustomRenderCell {
public static final int SIZE = 64;
public static final int LOGO_SIZE = 512;
public static final int PIXELATED_SIZE = 512;
float percentage = 0;
double time = 0;
protected ProgressLogoRender() {
super(SIZE, GridLayout.GridValueType.CONSTANT, SIZE);
}
@Override
public void onRender(PoseStack poseStack, GridTransform transform, Object context) {
time += 0.03;
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.enableBlend();
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0f);
final int yBarLocal = (int) (transform.height * percentage);
final int yBar = transform.top + yBarLocal;
final float fScale = (float) (0.3 * ((Math.sin(time) + 1.0) * 0.5) + 0.7);
int height = (int) (transform.height * fScale);
int width = (int) (transform.width * fScale);
width -= ((transform.width - width) % 2);
height -= ((transform.height - height) % 2);
final int yOffset = (transform.height - height) / 2;
final int xOffset = (transform.width - width) / 2;
final int yBarImage = Math.max(0, Math.min(height, yBarLocal - yOffset));
final float relativeY = ((float) yBarImage / height);
if (yBarImage > 0) {
final int uvTopLogo = (int) (relativeY * LOGO_SIZE);
RenderSystem.setShaderTexture(0, BCLibScreen.BCLIB_LOGO_LOCATION);
GuiComponent.blit(poseStack,
xOffset + transform.left,
yOffset + transform.top,
width,
yBarImage,
0, 0, LOGO_SIZE, uvTopLogo,
LOGO_SIZE, LOGO_SIZE
);
}
if (yBarImage < height) {
final int uvTopPixelated = (int) (relativeY * PIXELATED_SIZE);
RenderSystem.setShaderTexture(0, ProgressScreen.BCLIB_LOGO_PIXELATED_LOCATION);
GuiComponent.blit(poseStack,
xOffset + transform.left,
yOffset + transform.top + yBarImage,
width,
height - yBarImage,
0, uvTopPixelated, PIXELATED_SIZE, PIXELATED_SIZE - uvTopPixelated,
PIXELATED_SIZE, PIXELATED_SIZE
);
}
if (percentage > 0 && percentage < 1.0) {
GuiComponent.fill(poseStack,
transform.left,
yBar,
transform.left + transform.width,
yBar + 1,
0x3FFFFFFF
);
}
}
}
public class ProgressScreen extends GridScreen implements ProgressListener, AtomicProgressListener {
static final ResourceLocation BCLIB_LOGO_PIXELATED_LOCATION = new ResourceLocation(BCLib.MOD_ID,
"iconpixelated.png");
public ProgressScreen(@Nullable Screen parent, Component title, Component description) {
super(parent, title, 20, true);
this.description = description;
}
Component description;
private Component stageComponent;
private GridMessageCell stage;
private GridStringCell progress;
private ProgressLogoRender progressImage;
private int currentProgress = 0;
private AtomicInteger atomicCounter;
@Override
public void incAtomic(int maxProgress) {
if (atomicCounter != null) {
progressStagePercentage((100 * atomicCounter.incrementAndGet()) / maxProgress);
}
}
@Override
public void resetAtomic() {
progressStagePercentage(0);
atomicCounter = new AtomicInteger(0);
}
public boolean shouldCloseOnEsc() {
return false;
}
public Component getProgressComponent() {
return getProgressComponent(currentProgress);
}
private Component getProgressComponent(int pg) {
return Component.translatable("title.bclib.progress").append(": " + pg + "%");
}
@Override
protected void initLayout() {
grid.addSpacerRow();
GridRow row = grid.addRow(GridLayout.VerticalAlignment.CENTER);
row.addFiller();
progressImage = new ProgressLogoRender();
progressImage.percentage = currentProgress / 100.0f;
row.addCustomRender(progressImage);
row.addSpacer();
int textWidth = Math.max(getWidth(description), getWidth(getProgressComponent(100)));
GridColumn textCol = row.addColumn(0, GridLayout.GridValueType.INHERIT);
textCol.addRow().addString(description, this);
textCol.addSpacerRow();
progress = textCol.addRow()
.addString(getProgressComponent(), GridLayout.COLOR_GRAY, GridLayout.Alignment.LEFT, this);
row.addFiller();
grid.addSpacerRow(20);
row = grid.addRow();
stage = row.addMessage(stageComponent != null ? stageComponent : Component.literal(""),
font,
GridLayout.Alignment.CENTER);
}
@Override
public void progressStartNoAbort(Component text) {
this.progressStage(text);
}
@Override
public void progressStart(Component text) {
this.progressStage(text);
this.progressStagePercentage(0);
}
@Override
public void progressStage(Component text) {
stageComponent = text;
if (stage != null) stage.setText(text);
}
@Override
public void progressStagePercentage(int progress) {
if (progress != currentProgress) {
currentProgress = progress;
if (progressImage != null) progressImage.percentage = currentProgress / 100.0f;
if (this.progress != null) this.progress.setText(getProgressComponent());
}
}
@Override
public void stop() {
}
}

View file

@ -0,0 +1,133 @@
package org.betterx.bclib.client.gui.screens;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.betterx.bclib.api.v2.dataexchange.handler.autosync.HelloClient;
import org.betterx.bclib.client.gui.gridlayout.GridCheckboxCell;
import org.betterx.bclib.client.gui.gridlayout.GridLayout;
import org.betterx.bclib.client.gui.gridlayout.GridRow;
import org.betterx.bclib.util.ModUtil;
@Environment(EnvType.CLIENT)
public class SyncFilesScreen extends BCLibScreen {
private final Component description;
private final SyncFilesScreen.Listener listener;
private final boolean hasConfigFiles;
private final boolean hasFiles;
private final boolean hasMods;
private final boolean shouldDelete;
private final HelloClient.IServerModMap serverInfo;
public SyncFilesScreen(int modFiles,
int configFiles,
int singleFiles,
int folderFiles,
int deleteFiles,
HelloClient.IServerModMap serverInfo,
Listener listener) {
super(Component.translatable("title.bclib.syncfiles"));
this.serverInfo = serverInfo;
this.description = Component.translatable("message.bclib.syncfiles");
this.listener = listener;
this.hasConfigFiles = configFiles > 0;
this.hasFiles = singleFiles + folderFiles > 0;
this.hasMods = modFiles > 0;
this.shouldDelete = deleteFiles > 0;
}
protected void initLayout() {
final int BUTTON_HEIGHT = 20;
grid.addRow()
.addMessage(this.description, this.font, GridLayout.Alignment.CENTER);
grid.addSpacerRow(10);
GridRow row;
final GridCheckboxCell mods;
row = grid.addRow();
mods = row.addCheckbox(Component.translatable("message.bclib.syncfiles.mods"),
hasMods,
BUTTON_HEIGHT,
this.font);
mods.setEnabled(hasMods);
row.addSpacer();
row.addButton(Component.translatable("title.bclib.syncfiles.modInfo"), 20, font, (button) -> {
ModListScreen scr = new ModListScreen(
this,
Component.translatable("title.bclib.syncfiles.modlist"),
Component.translatable("message.bclib.syncfiles.modlist"),
ModUtil.getMods(),
serverInfo
);
Minecraft.getInstance().setScreen(scr);
});
grid.addSpacerRow();
final GridCheckboxCell configs;
row = grid.addRow();
configs = row.addCheckbox(Component.translatable("message.bclib.syncfiles.configs"),
hasConfigFiles,
BUTTON_HEIGHT,
this.font);
configs.setEnabled(hasConfigFiles);
grid.addSpacerRow();
row = grid.addRow();
final GridCheckboxCell folder;
folder = row.addCheckbox(Component.translatable("message.bclib.syncfiles.folders"),
hasFiles,
BUTTON_HEIGHT,
this.font);
folder.setEnabled(hasFiles);
row.addSpacer();
GridCheckboxCell delete;
delete = row.addCheckbox(Component.translatable("message.bclib.syncfiles.delete"),
shouldDelete,
BUTTON_HEIGHT,
this.font);
delete.setEnabled(shouldDelete);
grid.addSpacerRow(30);
row = grid.addRow();
row.addFiller();
row.addButton(CommonComponents.GUI_NO, BUTTON_HEIGHT, this.font, (button) -> {
listener.proceed(false, false, false, false);
});
row.addSpacer();
row.addButton(CommonComponents.GUI_YES, BUTTON_HEIGHT, this.font, (button) -> {
listener.proceed(
mods.isChecked(),
configs.isChecked(),
folder.isChecked(),
delete.isChecked()
);
});
row.addFiller();
}
public boolean shouldCloseOnEsc() {
return false;
}
@Environment(EnvType.CLIENT)
public interface Listener {
void proceed(boolean downloadMods, boolean downloadConfigs, boolean downloadFiles, boolean removeFiles);
}
}

View file

@ -0,0 +1,49 @@
package org.betterx.bclib.client.gui.screens;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.betterx.bclib.client.gui.gridlayout.GridLayout;
import org.betterx.bclib.client.gui.gridlayout.GridRow;
@Environment(EnvType.CLIENT)
public class WarnBCLibVersionMismatch extends BCLibScreen {
private final Component description;
private final Listener listener;
public WarnBCLibVersionMismatch(Listener listener) {
super(Component.translatable("title.bclib.bclibmissmatch"));
this.description = Component.translatable("message.bclib.bclibmissmatch");
this.listener = listener;
}
protected void initLayout() {
final int BUTTON_HEIGHT = 20;
grid.addRow().addMessage(this.description, this.font, GridLayout.Alignment.CENTER);
grid.addSpacerRow(20);
GridRow row = grid.addRow();
row.addFiller();
row.addButton(CommonComponents.GUI_NO, BUTTON_HEIGHT, this.font, (button) -> {
listener.proceed(false);
});
row.addSpacer();
row.addButton(CommonComponents.GUI_YES, BUTTON_HEIGHT, this.font, (button) -> {
listener.proceed(true);
});
row.addFiller();
}
public boolean shouldCloseOnEsc() {
return false;
}
@Environment(EnvType.CLIENT)
public interface Listener {
void proceed(boolean download);
}
}

View file

@ -0,0 +1,163 @@
package org.betterx.bclib.client.gui.screens;
import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen;
import net.minecraft.client.gui.screens.worldselection.WorldCreationContext;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.dimension.BuiltinDimensionTypes;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.level.dimension.LevelStem;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.betterx.bclib.BCLib;
import org.betterx.bclib.api.v2.generator.BCLBiomeSource;
import org.betterx.bclib.api.v2.levelgen.LevelGenUtil;
import org.betterx.bclib.client.gui.gridlayout.GridCheckboxCell;
import org.betterx.bclib.client.gui.gridlayout.GridLayout;
import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT)
public class WorldSetupScreen extends BCLibScreen {
private final WorldCreationContext context;
private final CreateWorldScreen createWorldScreen;
public WorldSetupScreen(@Nullable CreateWorldScreen parent, WorldCreationContext context) {
super(parent, Component.translatable("title.screen.bclib.worldgen.main"), 10, false);
this.context = context;
this.createWorldScreen = parent;
}
private GridCheckboxCell bclibEnd;
private GridCheckboxCell bclibNether;
GridCheckboxCell endLegacy;
GridCheckboxCell netherLegacy;
@Override
protected void initLayout() {
final int netherVersion = LevelGenUtil.getBiomeVersionForGenerator(context
.worldGenSettings()
.dimensions()
.getOrCreateHolderOrThrow(
LevelStem.NETHER)
.value()
.generator());
final int endVersion = LevelGenUtil.getBiomeVersionForGenerator(context
.worldGenSettings()
.dimensions()
.getOrCreateHolderOrThrow(
LevelStem.END)
.value()
.generator());
final int BUTTON_HEIGHT = 20;
grid.addSpacerRow(20);
var row = grid.addRow();
var colNether = row.addColumn(0.5, GridLayout.GridValueType.PERCENTAGE);
var colEnd = row.addColumn(0.5, GridLayout.GridValueType.PERCENTAGE);
row = colNether.addRow();
row.addString(Component.translatable("title.bclib.the_nether"), GridLayout.Alignment.CENTER, this);
colNether.addSpacerRow(15);
var mainSettingsRow = colNether.addRow();
mainSettingsRow.addSpacer(16);
row = colNether.addRow();
row.addSpacer(32);
netherLegacy = row.addCheckbox(Component.translatable("title.screen.bclib.worldgen.legacy_square"),
endVersion == BCLBiomeSource.BIOME_SOURCE_VERSION_SQUARE,
1.0,
GridLayout.GridValueType.PERCENTAGE,
(state) -> {
});
bclibNether = mainSettingsRow.addCheckbox(Component.translatable(
"title.screen.bclib.worldgen.custom_biome_source"),
netherVersion != BCLBiomeSource.BIOME_SOURCE_VERSION_VANILLA,
1.0,
GridLayout.GridValueType.PERCENTAGE,
(state) -> {
netherLegacy.setEnabled(state);
});
row = colEnd.addRow(GridLayout.VerticalAlignment.CENTER);
row.addString(Component.translatable("title.bclib.the_end"), GridLayout.Alignment.CENTER, this);
colEnd.addSpacerRow(15);
mainSettingsRow = colEnd.addRow();
mainSettingsRow.addSpacer(16);
row = colEnd.addRow();
row.addSpacer(32);
endLegacy = row.addCheckbox(Component.translatable("title.screen.bclib.worldgen.legacy_square"),
endVersion == BCLBiomeSource.BIOME_SOURCE_VERSION_SQUARE,
1.0,
GridLayout.GridValueType.PERCENTAGE,
(state) -> {
});
bclibEnd = mainSettingsRow.addCheckbox(Component.translatable(
"title.screen.bclib.worldgen.custom_biome_source"),
endVersion != BCLBiomeSource.BIOME_SOURCE_VERSION_VANILLA,
1.0,
GridLayout.GridValueType.PERCENTAGE,
(state) -> {
endLegacy.setEnabled(state);
});
grid.addSpacerRow(15);
row = grid.addRow();
row.addFiller();
row.addButton(CommonComponents.GUI_DONE, BUTTON_HEIGHT, font, (button) -> {
updateSettings();
onClose();
});
grid.addSpacerRow(10);
}
private void updateSettings() {
int endVersion = BCLBiomeSource.DEFAULT_BIOME_SOURCE_VERSION;
if (bclibEnd.isChecked()) {
if (endLegacy.isChecked()) endVersion = BCLBiomeSource.BIOME_SOURCE_VERSION_SQUARE;
else endVersion = BCLBiomeSource.BIOME_SOURCE_VERSION_HEX;
} else {
endVersion = BCLBiomeSource.BIOME_SOURCE_VERSION_VANILLA;
}
int netherVersion = BCLBiomeSource.DEFAULT_BIOME_SOURCE_VERSION;
if (bclibNether.isChecked()) {
if (netherLegacy.isChecked()) netherVersion = BCLBiomeSource.BIOME_SOURCE_VERSION_SQUARE;
else netherVersion = BCLBiomeSource.BIOME_SOURCE_VERSION_HEX;
} else {
netherVersion = BCLBiomeSource.BIOME_SOURCE_VERSION_VANILLA;
}
BCLib.LOGGER.info("Custom World Versions: end=" + endVersion + ", nether=" + netherVersion);
updateConfiguration(LevelStem.END, BuiltinDimensionTypes.END, endVersion);
updateConfiguration(LevelStem.NETHER, BuiltinDimensionTypes.NETHER, netherVersion);
}
private void updateConfiguration(
ResourceKey<LevelStem> dimensionKey,
ResourceKey<DimensionType> dimensionTypeKey,
int biomeSourceVersion
) {
createWorldScreen.worldGenSettingsComponent.updateSettings(
(registryAccess, worldGenSettings) -> LevelGenUtil.replaceGenerator(
dimensionKey,
dimensionTypeKey,
biomeSourceVersion,
registryAccess,
worldGenSettings
)
);
}
}

View file

@ -16,7 +16,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.mojang.datafixers.util.Pair;
import org.betterx.bclib.api.ModIntegrationAPI;
import org.betterx.bclib.api.v2.ModIntegrationAPI;
import org.betterx.bclib.client.render.EmissiveTextureInfo;
import org.betterx.bclib.interfaces.BlockModelProvider;
import org.betterx.bclib.interfaces.ItemModelProvider;

View file

@ -7,7 +7,7 @@ import net.minecraft.world.level.levelgen.presets.WorldPreset;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.betterx.bclib.gui.screens.WorldSetupScreen;
import org.betterx.bclib.client.gui.screens.WorldSetupScreen;
import org.betterx.bclib.presets.worldgen.BCLWorldPresets;
import java.util.Optional;

View file

@ -12,8 +12,8 @@ import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.material.FogType;
import com.mojang.blaze3d.systems.RenderSystem;
import org.betterx.bclib.api.biomes.BCLBiome;
import org.betterx.bclib.api.biomes.BiomeAPI;
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome;
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
import org.betterx.bclib.config.Configs;
import org.betterx.bclib.util.BackgroundInfo;
import org.betterx.bclib.util.MHelper;