Allow position and dimension editing

This commit is contained in:
Surya 2021-09-03 23:50:43 +05:30
parent 441dfb5ffb
commit 39ca71bc63
13 changed files with 265 additions and 69 deletions

View File

@ -0,0 +1,21 @@
package me.bionicbeanie.mods.savecoords;
import java.util.List;
import net.minecraft.util.Identifier;
public interface IDimensionAware {
List<IDimension> getDimensions();
IDimension getCurrentDimension();
IDimension getDimension(String dimensionKey);
public interface IDimension {
public String getName();
public Identifier getSpriteIdentifier();
}
}

View File

@ -2,6 +2,7 @@ package me.bionicbeanie.mods.savecoords.gui.impl;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import me.bionicbeanie.mods.savecoords.IDimensionAware;
import me.bionicbeanie.mods.savecoords.IFileStore;
import me.bionicbeanie.mods.savecoords.IKeyBinds;
import me.bionicbeanie.mods.savecoords.IModGui;
@ -21,6 +22,7 @@ public class DIContainer {
private static IKeyBinds keyBinds;
private static ConfigScreenFactory<Screen> modMenuScreenFactory;
private static PingPositionOperation pingPositionOperation;
private static IDimensionAware dimensionAware;
public static IModGui getModGui() {
initialize();
@ -72,7 +74,8 @@ public class DIContainer {
guiController = new GuiController(minecraftClient);
playerLocator = Factory.CreatePlayerLocator(minecraftClient);
keyBinds = Factory.CreateKeyBinds(fileStore);
modGui = new SaveCoordinatesGui(fileStore, playerLocator, keyBinds, guiController);
dimensionAware = Factory.CreateDimensionAware(minecraftClient);
modGui = new SaveCoordinatesGui(fileStore, playerLocator, dimensionAware, keyBinds, guiController);
pingPositionOperation = new PingPositionOperation(fileStore, () -> playerLocator.locate());
}

View File

@ -4,10 +4,10 @@ import java.util.UUID;
import java.util.function.Supplier;
import io.github.cottonmc.cotton.gui.widget.WButton;
import io.github.cottonmc.cotton.gui.widget.WLabel;
import io.github.cottonmc.cotton.gui.widget.WSprite;
import io.github.cottonmc.cotton.gui.widget.WTextField;
import io.github.cottonmc.cotton.gui.widget.WWidget;
import me.bionicbeanie.mods.savecoords.IDimensionAware;
import me.bionicbeanie.mods.savecoords.IFileStore;
import me.bionicbeanie.mods.savecoords.IPlayerLocator;
import me.bionicbeanie.mods.savecoords.TranslationKeys;
@ -15,7 +15,6 @@ import me.bionicbeanie.mods.savecoords.gui.IRootPanel;
import me.bionicbeanie.mods.savecoords.model.PlayerPosition;
import me.bionicbeanie.mods.savecoords.model.PlayerRawPosition;
import me.bionicbeanie.mods.savecoords.model.PositionMetadata;
import me.bionicbeanie.mods.savecoords.util.DimensionKeys;
import me.bionicbeanie.mods.savecoords.util.ResourceUtils;
import net.minecraft.text.LiteralText;
import net.minecraft.text.TranslatableText;
@ -29,10 +28,12 @@ class DefaultViewHandler extends ViewHandlerBase<PlayerPosition> {
private WButton pingButton;
private WButton closeButton;
private WButton configButton;
private IDimensionAware dimensionAware;
public DefaultViewHandler(IFileStore fileStore, IPlayerLocator locator) {
public DefaultViewHandler(IFileStore fileStore, IPlayerLocator locator, IDimensionAware dimensionAware) {
this.fileStore = fileStore;
this.locator = locator;
this.dimensionAware = dimensionAware;
this.listButton = CreateButton(TranslationKeys.MENU_LIST);
this.saveButton = CreateButton(TranslationKeys.MENU_SAVE);
@ -62,21 +63,21 @@ class DefaultViewHandler extends ViewHandlerBase<PlayerPosition> {
root.add(yText, 1, 2, 6, 1);
root.add(zText, 1, 3, 6, 1);
WSprite worldIcon = ResourceUtils.createWorldIcon(getDimension(rawPosition));
root.add(worldIcon, 9, 1, 2, 2);
DimensionSprite dimensionSprite = new DimensionSprite();
root.add(dimensionSprite, 9, 0, 2, 2);
WWidget worldButton = CreateWorldButton(worldIcon);
root.add(worldButton, 8, 3, 4, 1);
DimensionButton dimensionButton = CreateDimensionButton(dimensionSprite, existingPosition);
root.add(dimensionButton, 8, 3, 4, 1);
String defaultWorldName = getDefaultWorldName(existingPosition);
WTextField world = CreateWorldField(defaultWorldName);
root.add(world, 0, 5, 4, 1);
WTextField worldNameField = CreateWorldField(defaultWorldName);
root.add(worldNameField, 0, 5, 4, 1);
WTextField location = CreateLocationField(existingPosition);
root.add(location, 5, 5, 7, 1);
WTextField locationField = CreateLocationField(existingPosition);
root.add(locationField, 5, 5, 7, 1);
WTextField notes = CreateNotesField(existingPosition);
root.add(notes, 0, 7, 12, 1);
WTextField notesField = CreateNotesField(existingPosition);
root.add(notesField, 0, 7, 12, 1);
root.add(saveButton, 13, 7, 2, 1);
root.add(listButton, 13, 9, 2, 1);
@ -84,35 +85,19 @@ class DefaultViewHandler extends ViewHandlerBase<PlayerPosition> {
root.add(closeButton, 0, 9, 2, 1);
root.add(configButton, 10, 9, 2, 1);
return createPlayerPositionSupplier(existingPosition, xText, yText, zText, world, location, notes);
return createPlayerPositionSupplier(
existingPosition,
xText,
yText,
zText,
dimensionButton,
worldNameField,
locationField,
notesField);
}
private WWidget CreateWorldButton(WSprite worldIcon) {
WButton button = new WButton(new LiteralText(DimensionKeys.OVERWORLD));
button.setOnClick(() -> button.setLabel(new LiteralText(DimensionKeys.NETHER)));
return button;
}
private String getDimension(PlayerRawPosition rawPosition) {
String dimensionIdentifier = rawPosition.getWorldDimension();
if(isDimension(DimensionKeys.OVERWORLD, dimensionIdentifier)) {
return DimensionKeys.OVERWORLD;
}
if(isDimension(DimensionKeys.NETHER, dimensionIdentifier)) {
return DimensionKeys.NETHER;
}
if(isDimension(DimensionKeys.END, dimensionIdentifier)) {
return DimensionKeys.END;
}
return DimensionKeys.UNKNOWN;
}
private boolean isDimension(String dimension, String dimensionIdentifier) {
return dimensionIdentifier != null && dimensionIdentifier.contains(dimension);
private DimensionButton CreateDimensionButton(WSprite worldIcon, PlayerRawPosition existingPosition) {
return new DimensionButton(worldIcon, dimensionAware, existingPosition);
}
public void onSaveButtonClick(Runnable runnable) {
@ -135,9 +120,9 @@ class DefaultViewHandler extends ViewHandlerBase<PlayerPosition> {
this.configButton.setOnClick(runnable);
}
private Supplier<PlayerPosition> createPlayerPositionSupplier(PlayerPosition existingPosition,
WTextField xText, WTextField yText, WTextField zText, WTextField world,
WTextField location, WTextField notes) {
private Supplier<PlayerPosition> createPlayerPositionSupplier(PlayerPosition existingPosition, WTextField xText,
WTextField yText, WTextField zText, DimensionButton dimensionButton, WTextField world, WTextField location,
WTextField notes) {
return () -> {
String id = CreateId(existingPosition);
@ -145,7 +130,7 @@ class DefaultViewHandler extends ViewHandlerBase<PlayerPosition> {
long y = parseLong(yText);
long z = parseLong(zText);
PlayerRawPosition rawPosition = new PlayerRawPosition(x, y, z, "overworld");
PlayerRawPosition rawPosition = new PlayerRawPosition(x, y, z, dimensionButton.getDimension().getName());
PositionMetadata metadata = CreateMetadata(existingPosition, world, notes);
return new PlayerPosition(id, rawPosition, location.getText(), metadata);
@ -188,7 +173,6 @@ class DefaultViewHandler extends ViewHandlerBase<PlayerPosition> {
}
private WWidget CreateLabelForCoordinate(String label) {
//return new WLabel(label, 0xb80000);
WButton labelButton = new WButton(new LiteralText(label));
labelButton.setEnabled(false);
return labelButton;

View File

@ -0,0 +1,91 @@
package me.bionicbeanie.mods.savecoords.gui.impl;
import io.github.cottonmc.cotton.gui.widget.WButton;
import io.github.cottonmc.cotton.gui.widget.WSprite;
import me.bionicbeanie.mods.savecoords.IDimensionAware;
import me.bionicbeanie.mods.savecoords.IDimensionAware.IDimension;
import me.bionicbeanie.mods.savecoords.model.PlayerRawPosition;
import net.minecraft.text.LiteralText;
public class DimensionButton extends WButton {
private CircularList<IDimension> allDimensions;
public DimensionButton(WSprite sprite, IDimensionAware dimensionAware, PlayerRawPosition existingPosition) {
allDimensions = new CircularList<IDimension>();
for (IDimension dimension : dimensionAware.getDimensions()) {
allDimensions.add(dimension);
}
IDimension existingDimension = dimensionAware.getCurrentDimension();
if(existingPosition != null) {
existingDimension = dimensionAware.getDimension(existingPosition.getWorldDimension());
}
while(allDimensions.next() != existingDimension);
IDimension currentDimension = allDimensions.current();
sprite.setImage(currentDimension.getSpriteIdentifier());
setLabel(new LiteralText(currentDimension.getName()));
setOnClick(() -> {
allDimensions.next();
IDimension current = getDimension();
sprite.setImage(current.getSpriteIdentifier());
setLabel(new LiteralText(current.getName()));
});
}
public IDimension getDimension() {
return allDimensions.current();
}
}
// TODO : Probably move ad-hoc circular list elsewhere
class Node<T> {
T value;
Node<T> next;
Node(T t) {
this.value = t;
}
}
class CircularList<T> {
Node<T> head = null;
Node<T> tail = null;
Node<T> current = null;
void add(T t) {
if (head == null) {
head = new Node<T>(t);
tail = head;
head.next = tail;
tail.next = head;
return;
}
Node<T> temp = new Node<T>(t);
temp.next = head;
tail.next = temp;
tail = temp;
}
T next() {
if (current == null) {
current = head;
} else {
current = current.next;
}
return current.value;
}
T current() {
if (current == null) {
return null;
}
return current.value;
}
}

View File

@ -0,0 +1,17 @@
package me.bionicbeanie.mods.savecoords.gui.impl;
import io.github.cottonmc.cotton.gui.widget.WSprite;
import me.bionicbeanie.mods.savecoords.util.ResourceUtils;
import net.minecraft.util.Identifier;
public class DimensionSprite extends WSprite {
public DimensionSprite() {
super(ResourceUtils.getIdentifier("unknown"));
}
public void setDimension(String dimensionKey) {
Identifier identifier = ResourceUtils.getIdentifier(dimensionKey);
this.setImage(identifier);
}
}

View File

@ -43,7 +43,7 @@ class ListViewHandler extends ViewHandlerBase<Void> {
public Supplier<Void> setupView(IRootPanel root, Void nullState) {
List<PlayerPosition> positions = getPositions(fileStore);
WListPanel<PlayerPosition, CoordinatesListItemPanel> listPanel = createListPane(positions);
WListPanel<PlayerPosition, CoordinatesListItemPanel> listPanel = createListPanel(positions);
root.add(listPanel, 0, 0, 15, 9);
root.add(backButton, 0, 9, 2, 1);
@ -59,7 +59,7 @@ class ListViewHandler extends ViewHandlerBase<Void> {
return new WButton(new TranslatableText(TranslationKeys.MENU_BACK));
}
private WListPanel<PlayerPosition, CoordinatesListItemPanel> createListPane(List<PlayerPosition> positions) {
private WListPanel<PlayerPosition, CoordinatesListItemPanel> createListPanel(List<PlayerPosition> positions) {
BiConsumer<PlayerPosition, CoordinatesListItemPanel> configurator = (pos, p) -> p.setPosition(pos, fileStore);
WListPanel<PlayerPosition, CoordinatesListItemPanel> panel = createListPanel(positions, configurator);

View File

@ -2,6 +2,7 @@ package me.bionicbeanie.mods.savecoords.gui.impl;
import java.util.List;
import me.bionicbeanie.mods.savecoords.IDimensionAware;
import me.bionicbeanie.mods.savecoords.IFileStore;
import me.bionicbeanie.mods.savecoords.IKeyBinds;
import me.bionicbeanie.mods.savecoords.IKeyBinds.IKeyBinding;
@ -21,13 +22,16 @@ public class SaveCoordinatesGui implements IModGui {
private IViewHandler<Void> listHandler;
private IViewHandler<List<IKeyBinding>> configHandler;
private IPlayerLocator locator;
private IDimensionAware dimensionAware;
private IKeyBinds keyBinds;
SaveCoordinatesGui(IFileStore fileStore, IPlayerLocator locator, IKeyBinds binds, IGuiController screenController) {
SaveCoordinatesGui(IFileStore fileStore, IPlayerLocator locator, IDimensionAware dimensionAware, IKeyBinds binds,
IGuiController screenController) {
this.screenController = screenController;
this.fileStore = fileStore;
this.keyBinds = binds;
this.locator = locator;
this.dimensionAware = dimensionAware;
this.defaultHandler = CreateDefaultViewHandler();
this.listHandler = CreateListViewHandler();
@ -40,7 +44,7 @@ public class SaveCoordinatesGui implements IModGui {
}
private IViewHandler<PlayerPosition> CreateDefaultViewHandler() {
DefaultViewHandler handler = new DefaultViewHandler(fileStore, locator);
DefaultViewHandler handler = new DefaultViewHandler(fileStore, locator, dimensionAware);
handler.onSaveButtonClick(this::savePosition);
handler.onListButtonClick(this::showListView);

View File

@ -0,0 +1,83 @@
package me.bionicbeanie.mods.savecoords.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import me.bionicbeanie.mods.savecoords.IDimensionAware;
import me.bionicbeanie.mods.savecoords.util.ResourceUtils;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.Identifier;
public class DimensionAware implements IDimensionAware {
private List<Dimension> allDimensions;
private List<IDimension> allDimensionsReadOnly;
private IDimension UNKNOWN = new Dimension("Unknown", ResourceUtils.getIdentifier("unknown"));
private MinecraftClient minecraftClient;
public DimensionAware(MinecraftClient minecraftClient) {
this.minecraftClient = minecraftClient;
allDimensions = new ArrayList<>();
initialize(allDimensions);
allDimensionsReadOnly = Collections.unmodifiableList(allDimensions);
}
// TODO: Provide a hook for other mods to add in their dimension info
private void initialize(List<Dimension> dimensions) {
dimensions.add(new Dimension("Overworld", ResourceUtils.getIdentifier("overworld")));
dimensions.add(new Dimension("Nether", ResourceUtils.getIdentifier("nether")));
dimensions.add(new Dimension("End", ResourceUtils.getIdentifier("end")));
}
@Override
public List<IDimension> getDimensions() {
return allDimensionsReadOnly;
}
@Override
public IDimension getCurrentDimension() {
String dimensionKey = minecraftClient.player.getEntityWorld().getRegistryKey().getValue().toString();
return getDimension(dimensionKey);
}
@Override
public IDimension getDimension(String dimensionKey) {
for (Dimension dimension : allDimensions) {
if (dimension.isDimension(dimensionKey)) {
return dimension;
}
}
return UNKNOWN;
}
static class Dimension implements IDimension {
private String name;
private Identifier spriteIdentifier;
Dimension(String name, Identifier spriteIdentifier) {
this.name = name;
this.spriteIdentifier = spriteIdentifier;
}
@Override
public String getName() {
return name;
}
@Override
public Identifier getSpriteIdentifier() {
return spriteIdentifier;
}
boolean isDimension(String registryKey) {
return (registryKey != null && registryKey.toLowerCase().contains(this.name.toLowerCase()));
}
}
}

View File

@ -1,5 +1,6 @@
package me.bionicbeanie.mods.savecoords.impl;
import me.bionicbeanie.mods.savecoords.IDimensionAware;
import me.bionicbeanie.mods.savecoords.IFileStore;
import me.bionicbeanie.mods.savecoords.IKeyBinds;
import me.bionicbeanie.mods.savecoords.IPlayerLocator;
@ -18,4 +19,8 @@ public class Factory {
public static IKeyBinds CreateKeyBinds(IFileStore fileStore) {
return new KeyBinds(fileStore);
}
public static IDimensionAware CreateDimensionAware(MinecraftClient client) {
return new DimensionAware(client);
}
}

View File

@ -18,6 +18,7 @@ class PlayerLocator implements IPlayerLocator {
long x = Math.round(pos.x);
long y = Math.round(pos.y);
long z = Math.round(pos.z);
String worldDimension = client.player.getEntityWorld().getRegistryKey().getValue().toString();
return new PlayerRawPosition(x, y, z, worldDimension);

View File

@ -1,9 +0,0 @@
package me.bionicbeanie.mods.savecoords.util;
public class DimensionKeys {
public static String OVERWORLD = "overworld";
public static String NETHER = "nether";
public static String END = "end";
public static String UNKNOWN = "unknown";
}

View File

@ -21,7 +21,8 @@ public class IdentifiersCache {
}
public Identifier get(String resourceName) {
return cache.getOrDefault(resourceName, cache.get(DEFAULT));
String key = resourceName.toLowerCase();
return cache.getOrDefault(key, cache.get(DEFAULT));
}
private static void add(String resourceName, Map<String, Identifier> cache) {

View File

@ -1,6 +1,5 @@
package me.bionicbeanie.mods.savecoords.util;
import io.github.cottonmc.cotton.gui.widget.WSprite;
import io.github.cottonmc.cotton.gui.widget.icon.Icon;
import io.github.cottonmc.cotton.gui.widget.icon.TextureIcon;
import net.minecraft.util.Identifier;
@ -9,10 +8,6 @@ public class ResourceUtils {
private static IdentifiersCache cache = new IdentifiersCache();
public static WSprite createWorldIcon(String dimension) {
return new WSprite(getIdentifier(dimension));
}
public static Identifier getIdentifier(String resourceName) {
return cache.get(resourceName);
}