diff --git a/common/src/main/java/earth/terrarium/heracles/api/client/settings/base/OptionalRegistryKeySetting.java b/common/src/main/java/earth/terrarium/heracles/api/client/settings/base/OptionalRegistryKeySetting.java new file mode 100644 index 00000000..415728c8 --- /dev/null +++ b/common/src/main/java/earth/terrarium/heracles/api/client/settings/base/OptionalRegistryKeySetting.java @@ -0,0 +1,53 @@ +package earth.terrarium.heracles.api.client.settings.base; + +import earth.terrarium.heracles.Heracles; +import earth.terrarium.heracles.api.client.settings.Setting; +import earth.terrarium.heracles.client.widgets.boxes.OptionalAutocompleteEditBox; +import net.minecraft.Optionull; +import net.minecraft.client.Minecraft; +import net.minecraft.core.Registry; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; + +public record OptionalRegistryKeySetting( + ResourceKey> key +) implements Setting<@Nullable ResourceKey, OptionalAutocompleteEditBox> { + + public static final OptionalRegistryKeySetting DIMENSION = new OptionalRegistryKeySetting<>(Registries.DIMENSION); + + @Override + public OptionalAutocompleteEditBox createWidget(int width, ResourceKey value) { + OptionalAutocompleteEditBox box = new OptionalAutocompleteEditBox<>(Minecraft.getInstance().font, 0, 0, width, 11, + (text, item) -> item.contains(text) && !item.equals(text), Function.identity(), s -> {}); + box.setMaxLength(Short.MAX_VALUE); + List suggestions = new ArrayList<>(); + var registry = Heracles.getRegistryAccess().registry(key).orElse(null); + if (registry == null) { + return box; + } + registry.keySet().stream().map(ResourceLocation::toString).forEach(suggestions::add); + box.setSuggestions(suggestions); + + String id = Optionull.map(value, key -> key.location().toString()); + box.setValue(id); + return box; + } + + @Override + public ResourceKey getValue(OptionalAutocompleteEditBox widget) { + String value = widget.nullableValue(); + if (value == null) return null; + ResourceLocation id = ResourceLocation.tryParse(value); + return Optional.ofNullable(id) + .map(ignored -> ResourceKey.create(key, id)) + .orElse(null); + } +} diff --git a/common/src/main/java/earth/terrarium/heracles/api/client/settings/base/RegistryKeySetting.java b/common/src/main/java/earth/terrarium/heracles/api/client/settings/base/RegistryKeySetting.java index 38fce519..efced50d 100644 --- a/common/src/main/java/earth/terrarium/heracles/api/client/settings/base/RegistryKeySetting.java +++ b/common/src/main/java/earth/terrarium/heracles/api/client/settings/base/RegistryKeySetting.java @@ -20,6 +20,7 @@ public record RegistryKeySetting( ResourceKey> key ) implements Setting, AutocompleteEditBox> { + @Deprecated public static final RegistryKeySetting DIMENSION = new RegistryKeySetting<>(Registries.DIMENSION); @Override diff --git a/common/src/main/java/earth/terrarium/heracles/api/client/settings/tasks/DimensionTaskSettings.java b/common/src/main/java/earth/terrarium/heracles/api/client/settings/tasks/DimensionTaskSettings.java index 7eaa2c4c..ae1d3803 100644 --- a/common/src/main/java/earth/terrarium/heracles/api/client/settings/tasks/DimensionTaskSettings.java +++ b/common/src/main/java/earth/terrarium/heracles/api/client/settings/tasks/DimensionTaskSettings.java @@ -2,6 +2,7 @@ import earth.terrarium.heracles.api.client.settings.CustomizableQuestElementSettings; import earth.terrarium.heracles.api.client.settings.SettingInitializer; +import earth.terrarium.heracles.api.client.settings.base.OptionalRegistryKeySetting; import earth.terrarium.heracles.api.client.settings.base.RegistryKeySetting; import earth.terrarium.heracles.api.tasks.defaults.ChangedDimensionTask; import net.minecraft.Optionull; @@ -15,8 +16,8 @@ public class DimensionTaskSettings implements SettingInitializer responder) { } @Override - public void renderWidget(GuiGraphics graphics, int i, int j, float f) { - super.renderWidget(graphics, i, j, f); + public void renderWidget(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) { + super.renderWidget(graphics, mouseX, mouseY, partialTick); if (!isFocused()) return; int x = this.getX(); int y = this.getY() + this.getHeight() + 1; diff --git a/common/src/main/java/earth/terrarium/heracles/client/widgets/boxes/OptionalAutocompleteEditBox.java b/common/src/main/java/earth/terrarium/heracles/client/widgets/boxes/OptionalAutocompleteEditBox.java new file mode 100644 index 00000000..681daf9c --- /dev/null +++ b/common/src/main/java/earth/terrarium/heracles/client/widgets/boxes/OptionalAutocompleteEditBox.java @@ -0,0 +1,86 @@ +package earth.terrarium.heracles.client.widgets.boxes; + +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Checkbox; +import net.minecraft.network.chat.CommonComponents; +import org.jetbrains.annotations.Nullable; + +import java.util.function.BiPredicate; +import java.util.function.Consumer; +import java.util.function.Function; + +public class OptionalAutocompleteEditBox extends AutocompleteEditBox { + private static final int CHECKBOX_WIDTH = 24; + private final Checkbox checkbox; + + public OptionalAutocompleteEditBox(Font font, int x, int y, int width, int height, BiPredicate filter, Function mapper, Consumer onEnter) { + super(font, x + CHECKBOX_WIDTH, y, width - CHECKBOX_WIDTH, height, filter, mapper, onEnter); + this.checkbox = new Checkbox(x, y, CHECKBOX_WIDTH, height, CommonComponents.EMPTY, false, false); + } + + public @Nullable T nullableValue() { + return checkbox.selected() ? this.value() : null; + } + + public void setValue(@Nullable String value) { + if (value == null) { + if (checkbox.selected()) checkbox.onPress(); + } else { + if (!checkbox.selected()) checkbox.onPress(); + super.setValue(value); + } + this.updateEditBoxEditability(); + } + + private void updateEditBoxEditability() { + this.setEditable(checkbox.selected()); + } + + @Override + public void renderWidget(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) { + this.checkbox.render(graphics, mouseX, mouseY, partialTick); + super.renderWidget(graphics, mouseX, mouseY, partialTick); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + boolean value = this.checkbox.mouseClicked(mouseX, mouseY, button) | super.mouseClicked(mouseX, mouseY, button); + this.updateEditBoxEditability(); + return value; + } + + @Override + public boolean isMouseOver(double mouseX, double mouseY) { + return super.isMouseOver(mouseX, mouseY) || this.checkbox.isMouseOver(mouseX, mouseY); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + boolean value = this.checkbox.keyPressed(keyCode, scanCode, modifiers) | super.keyPressed(keyCode, scanCode, modifiers); + this.updateEditBoxEditability(); + return value; + } + + @Override + public boolean charTyped(char codePoint, int modifiers) { + return this.checkbox.charTyped(codePoint, modifiers) | super.charTyped(codePoint, modifiers); + } + + @Override + public void setX(int x) { + this.checkbox.setX(x); + super.setX(x + CHECKBOX_WIDTH); + } + + @Override + public void setY(int y) { + this.checkbox.setY(y); + super.setY(y); + } + + @Override + public void setWidth(int width) { + super.setWidth(width - CHECKBOX_WIDTH); + } +} diff --git a/common/src/main/resources/assets/heracles_tasks/lang/en_us.json b/common/src/main/resources/assets/heracles_tasks/lang/en_us.json index 951da41e..413e4033 100644 --- a/common/src/main/resources/assets/heracles_tasks/lang/en_us.json +++ b/common/src/main/resources/assets/heracles_tasks/lang/en_us.json @@ -104,6 +104,7 @@ "task.heracles.changed_dimension": "\uD83C\uDF0A Changed Dimension", "task.heracles.changed_dimension.title.singular": "Travel between dimensions", "task.heracles.changed_dimension.desc.singular": "From %s To %s", + "task.heracles.changed_dimension.desc.dim.any": "Any Dimension", "setting.heracles.changed_dimension.title": "Title Override:", "setting.heracles.changed_dimension.icon": "Icon Override:", "setting.heracles.changed_dimension.from": "From:",