Convert even more
This commit is contained in:
@@ -0,0 +1,54 @@
|
|||||||
|
package io.github.skippyall.minions.gui;
|
||||||
|
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public abstract class MinionsGui {
|
||||||
|
protected final @Nullable MinionsGui parent;
|
||||||
|
protected final ServerPlayerEntity viewer;
|
||||||
|
private @Nullable MinionsGui child = null;
|
||||||
|
private boolean open = true;
|
||||||
|
|
||||||
|
public MinionsGui(MinionsGui parent) {
|
||||||
|
this.viewer = parent.viewer;
|
||||||
|
this.parent = parent;
|
||||||
|
parent.child = this;
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MinionsGui(ServerPlayerEntity viewer) {
|
||||||
|
this.viewer = viewer;
|
||||||
|
this.parent = null;
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void open() {}
|
||||||
|
|
||||||
|
protected void reopen() {
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onBackingClosed() {
|
||||||
|
if(child != null && child.open) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
if(open) {
|
||||||
|
if(child != null) {
|
||||||
|
child.close();
|
||||||
|
}
|
||||||
|
if(parent != null) {
|
||||||
|
parent.child = null;
|
||||||
|
parent.reopen();
|
||||||
|
}
|
||||||
|
onClose();
|
||||||
|
open = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onClose() {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package io.github.skippyall.minions.gui;
|
||||||
|
|
||||||
|
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||||
|
import eu.pb4.sgui.api.gui.SlotGuiInterface;
|
||||||
|
import io.github.skippyall.minions.gui.minion.MinionGui;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.collection.IndexedIterable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class PaginatedList {
|
||||||
|
public static void createList(SlotGuiInterface gui, int size, Function<Integer, GuiElementBuilder> display, Runnable onBack) {
|
||||||
|
AtomicInteger page = new AtomicInteger(0);
|
||||||
|
addItems(page, gui, size, display);
|
||||||
|
|
||||||
|
gui.setSlot(27, MinionGui.backButton(onBack));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void createList(SlotGuiInterface gui, List<T> list, Function<T, GuiElementBuilder> display, Runnable onBack) {
|
||||||
|
createList(gui, list.size(), i -> display.apply(list.get(i)), onBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void createList(SlotGuiInterface gui, IndexedIterable<T> list, Function<T, GuiElementBuilder> display, Runnable onBack) {
|
||||||
|
createList(gui, list.size(), i -> display.apply(list.get(i)), onBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addItems(AtomicInteger page, SlotGuiInterface gui, int size, Function<Integer, GuiElementBuilder> display) {
|
||||||
|
for(int i = 27 * page.get(); i < Math.min(27 * (page.get() + 1), size); i++) {
|
||||||
|
gui.addSlot(display.apply(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(page.get() > 0) {
|
||||||
|
gui.setSlot(30, new GuiElementBuilder(Items.SPECTRAL_ARROW)
|
||||||
|
.setItemName(Text.translatable("book.page_button.previous"))
|
||||||
|
.setCallback(() -> {
|
||||||
|
page.decrementAndGet();
|
||||||
|
addItems(page, gui, size, display);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
gui.clearSlot(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(27 * (page.get() + 1) < size) {
|
||||||
|
gui.setSlot(32, new GuiElementBuilder(Items.ARROW)
|
||||||
|
.setItemName(Text.translatable("book.page_button.next"))
|
||||||
|
.setCallback(() -> {
|
||||||
|
page.incrementAndGet();
|
||||||
|
addItems(page, gui, size, display);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
gui.clearSlot(32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,11 +25,11 @@ public interface Result<T, E> {
|
|||||||
|
|
||||||
boolean isSuccess();
|
boolean isSuccess();
|
||||||
|
|
||||||
@NotNull T getOrDefault(@NotNull T defaultValue);
|
T getOrDefault(T defaultValue);
|
||||||
|
|
||||||
@NotNull T getOrThrow();
|
T getOrThrow();
|
||||||
|
|
||||||
@NotNull E getErrorOrThrow();
|
E getErrorOrThrow();
|
||||||
|
|
||||||
@NotNull Optional<T> getOptional();
|
@NotNull Optional<T> getOptional();
|
||||||
|
|
||||||
@@ -37,24 +37,24 @@ public interface Result<T, E> {
|
|||||||
|
|
||||||
void ifError(@NotNull Consumer<Error<T, E>> handler);
|
void ifError(@NotNull Consumer<Error<T, E>> handler);
|
||||||
|
|
||||||
record Success<T, E>(@NotNull T result) implements Result<T, E> {
|
record Success<T, E>(T result) implements Result<T, E> {
|
||||||
@Override
|
@Override
|
||||||
public boolean isSuccess() {
|
public boolean isSuccess() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull T getOrDefault(@NotNull T defaultValue) {
|
public T getOrDefault(T defaultValue) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull T getOrThrow() {
|
public T getOrThrow() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull E getErrorOrThrow() {
|
public E getErrorOrThrow() {
|
||||||
throw new RuntimeException("Result was not an Error");
|
throw new RuntimeException("Result was not an Error");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,24 +74,25 @@ public interface Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
record Error<T, E>(@NotNull E message) implements Result<T, E> {
|
record Error<T, E>(E message) implements Result<T, E> {
|
||||||
@Override
|
@Override
|
||||||
public boolean isSuccess() {
|
public boolean isSuccess() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull T getOrDefault(@NotNull T defaultValue) {
|
public T getOrDefault(
|
||||||
|
T defaultValue) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull T getOrThrow() {
|
public T getOrThrow() {
|
||||||
throw new RuntimeException("Result was an error: " + message);
|
throw new RuntimeException("Result was an error: " + message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull E getErrorOrThrow() {
|
public E getErrorOrThrow() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package io.github.skippyall.minions.gui.instruction;
|
||||||
|
|
||||||
|
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||||
|
import eu.pb4.sgui.api.gui.SimpleGui;
|
||||||
|
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||||
|
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||||
|
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||||
|
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
|
||||||
|
import io.github.skippyall.minions.program.supplier.Parameter;
|
||||||
|
import io.github.skippyall.minions.program.supplier.ValueSupplier;
|
||||||
|
import io.github.skippyall.minions.program.supplier.ValueSupplierType;
|
||||||
|
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||||
|
import io.github.skippyall.minions.util.TranslationUtil;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.screen.ScreenHandlerType;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class ArgumentGui {
|
||||||
|
public static <T, A extends ValueSupplier<T, MinionRuntime>> void configureArgumentMenu(String instructionName, ConfiguredInstruction<MinionRuntime> instruction, Parameter<?> parameter, MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||||
|
if (!InstructionGui.checkInstructionExists(instructionName, instruction, minion, player)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable ValueSupplier<?, MinionRuntime> argument = instruction.getArguments().getArgument(parameter);
|
||||||
|
|
||||||
|
if(argument == null) {
|
||||||
|
configureTypeAndValue(instructionName, instruction, parameter, minion, player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
configureArgumentHelper(instructionName, instruction, parameter, argument, minion, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <F, T> void configureArgumentHelper(String instructionName, ConfiguredInstruction<MinionRuntime> instruction, Parameter<T> parameter, ValueSupplier<F, MinionRuntime> argument, MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||||
|
SimpleGui gui = new InstructionBoundSimpleGui(ScreenHandlerType.GENERIC_3X3, player, minion, instruction);
|
||||||
|
|
||||||
|
ItemStack displayStack = GuiDisplay.getDisplayStack(MinionRegistries.VALUE_SUPPLIER_TYPES, argument.getType(), player.getRegistryManager());
|
||||||
|
|
||||||
|
gui.setSlot(3, new GuiElementBuilder(displayStack)
|
||||||
|
.setName(Text.translatable("minions.gui.instruction.argument.configure.type", Text.translatable(TranslationUtil.getTranslationKey(argument.getType(), MinionRegistries.VALUE_SUPPLIER_TYPES, "minions.gui.instruction.argument.configure.type.unset"))))
|
||||||
|
.setCallback(() -> configureTypeAndValue(instructionName, instruction, parameter, minion, player))
|
||||||
|
);
|
||||||
|
gui.setSlot(5, new GuiElementBuilder(Items.STRUCTURE_VOID)
|
||||||
|
.setName(Text.literal("Configure"))
|
||||||
|
.setCallback(() -> argument.getType().openConfiguration(player, argument.getValueType(), argument)
|
||||||
|
.thenAccept(newArgument -> {
|
||||||
|
instruction.getArguments().setArgument(parameter, newArgument);
|
||||||
|
configureArgumentMenu(instructionName, instruction, parameter, minion, player);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
gui.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CompletableFuture<ValueSupplierType<MinionRuntime>> selectArgumentType(ServerPlayerEntity player, MinionFakePlayer minion, ConfiguredInstruction<MinionRuntime> instruction) {
|
||||||
|
CompletableFuture<ValueSupplierType<MinionRuntime>> future = new CompletableFuture<>();
|
||||||
|
SimpleGui gui = new InstructionBoundSimpleGui(ScreenHandlerType.GENERIC_9X3, player, minion, instruction);
|
||||||
|
for (ValueSupplierType<MinionRuntime> type : MinionRegistries.VALUE_SUPPLIER_TYPES) {
|
||||||
|
gui.addSlot(new GuiElementBuilder(GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_SUPPLIER_TYPES, type, player.getRegistryManager()))
|
||||||
|
.setCallback(() -> future.complete(type))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
gui.open();
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void configureTypeAndValue(String name, ConfiguredInstruction<MinionRuntime> instruction, Parameter<T> parameter, MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||||
|
selectArgumentType(player, minion, instruction)
|
||||||
|
.thenApply(type -> type.openConfiguration(player, parameter.type(), null)
|
||||||
|
.thenAccept(v -> {
|
||||||
|
instruction.getArguments().setArgument(parameter, v);
|
||||||
|
configureArgumentMenu(name, instruction, parameter, minion, player);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
package io.github.skippyall.minions.gui;
|
package io.github.skippyall.minions.gui.instruction;
|
||||||
|
|
||||||
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||||
import io.github.skippyall.minions.gui.input.ChoiceInput;
|
import io.github.skippyall.minions.gui.input.ChoiceInput;
|
||||||
@@ -108,7 +108,7 @@ public class ConfigureInstructionGui extends InstructionBoundSimpleGui {
|
|||||||
int slot = 12;
|
int slot = 12;
|
||||||
for(Parameter<?> parameter : instruction.getInstruction().getParameters().reversed()) {
|
for(Parameter<?> parameter : instruction.getInstruction().getParameters().reversed()) {
|
||||||
setSlot(slot, InstructionGui.createParameterElement(parameter, instruction.getArguments().getArgument(parameter), player.getRegistryManager())
|
setSlot(slot, InstructionGui.createParameterElement(parameter, instruction.getArguments().getArgument(parameter), player.getRegistryManager())
|
||||||
.setCallback(() -> InstructionGui.configureArgumentMenu(name, instruction, parameter, minion, player))
|
.setCallback(() -> ArgumentGui.configureArgumentMenu(name, instruction, parameter, minion, player))
|
||||||
);
|
);
|
||||||
slot--;
|
slot--;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package io.github.skippyall.minions.gui.instruction;
|
||||||
|
|
||||||
|
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||||
|
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||||
|
import io.github.skippyall.minions.gui.PaginatedList;
|
||||||
|
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||||
|
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||||
|
import io.github.skippyall.minions.program.conversion.ValueConverter;
|
||||||
|
import io.github.skippyall.minions.program.conversion.ValueConverterType;
|
||||||
|
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
|
||||||
|
import io.github.skippyall.minions.program.supplier.Parameter;
|
||||||
|
import io.github.skippyall.minions.program.supplier.ValueSupplierList;
|
||||||
|
import io.github.skippyall.minions.program.value.ValueType;
|
||||||
|
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.registry.DynamicRegistryManager;
|
||||||
|
import net.minecraft.screen.ScreenHandlerType;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class ConverterGui {
|
||||||
|
public static void configureConvertersMenu(ServerPlayerEntity player, MinionFakePlayer minion, ConfiguredInstruction<MinionRuntime> instruction, Parameter<?> parameter, Runnable back) {
|
||||||
|
InstructionBoundSimpleGui gui = new InstructionBoundSimpleGui(ScreenHandlerType.GENERIC_9X4, player, minion, instruction);
|
||||||
|
|
||||||
|
ValueSupplierList.ValueSupplierEntry<?,?,MinionRuntime> entry = instruction.getArguments().getEntry(parameter);
|
||||||
|
PaginatedList.createList(
|
||||||
|
gui,
|
||||||
|
entry.getConverters(),
|
||||||
|
converter -> createConverterElement(converter, player.getRegistryManager())
|
||||||
|
.setCallback(() -> configureConverter(player, minion, instruction, parameter, entry, converter)),
|
||||||
|
back
|
||||||
|
);
|
||||||
|
gui.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GuiElementBuilder createConverterElement(ValueConverter<?,?> converter, DynamicRegistryManager manager) {
|
||||||
|
GuiElementBuilder builder = new GuiElementBuilder(GuiDisplay.getDisplayStack(MinionRegistries.VALUE_CONVERTER_TYPES, converter.getType(), manager));
|
||||||
|
builder.addLoreLine(converter.getDisplayText());
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void configureConverter(ServerPlayerEntity player, MinionFakePlayer minion, ConfiguredInstruction<MinionRuntime> instruction, Parameter<?> parameter, ValueSupplierList.ValueSupplierEntry<?,?,MinionRuntime> entry, @Nullable ValueConverter<?,?> converter) {
|
||||||
|
InstructionBoundSimpleGui gui = new InstructionBoundSimpleGui(ScreenHandlerType.GENERIC_3X3, player, minion, instruction);
|
||||||
|
gui.setSlot(3, new GuiElementBuilder(GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_CONVERTER_TYPES, converter.getType(), player.getRegistryManager()))
|
||||||
|
.setCallback(() -> {
|
||||||
|
InstructionBoundSimpleGui chooseTypeGui = new InstructionBoundSimpleGui(ScreenHandlerType.GENERIC_9X4, player, minion, instruction);
|
||||||
|
PaginatedList.createList(
|
||||||
|
chooseTypeGui,
|
||||||
|
MinionRegistries.VALUE_CONVERTER_TYPES,
|
||||||
|
type -> new GuiElementBuilder(GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_CONVERTER_TYPES, type, player.getRegistryManager()))
|
||||||
|
.setCallback(() -> {
|
||||||
|
entry.set
|
||||||
|
}),
|
||||||
|
() -> configureConverter(player, minion, instruction, parameter, entry, converter)
|
||||||
|
);
|
||||||
|
}));
|
||||||
|
|
||||||
|
gui.setSlot(5, new GuiElementBuilder(Items.STRUCTURE_VOID));
|
||||||
|
|
||||||
|
gui.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <F,T> void selectConverterMenu(ValueType<F> from, ValueType<T> to, ServerPlayerEntity player, MinionFakePlayer minion, ConfiguredInstruction<MinionRuntime> instruction) {
|
||||||
|
InstructionBoundSimpleGui gui = new InstructionBoundSimpleGui(ScreenHandlerType.GENERIC_9X3, player, minion, instruction);
|
||||||
|
for(ValueConverterType<?> valueConverterType : MinionRegistries.VALUE_CONVERTER_TYPES) {
|
||||||
|
gui.addSlot(new GuiElementBuilder(GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_CONVERTER_TYPES, valueConverterType, player.getRegistryManager()))
|
||||||
|
.setCallback(() -> valueConverterType.configure(player, from, to, null).thenAccept(c -> )));
|
||||||
|
}
|
||||||
|
gui.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
package io.github.skippyall.minions.gui;
|
package io.github.skippyall.minions.gui.instruction;
|
||||||
|
|
||||||
|
import io.github.skippyall.minions.gui.MinionBoundSimpleGui;
|
||||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||||
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
|
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
|
||||||
+3
-58
@@ -1,7 +1,9 @@
|
|||||||
package io.github.skippyall.minions.gui;
|
package io.github.skippyall.minions.gui.instruction;
|
||||||
|
|
||||||
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||||
import eu.pb4.sgui.api.gui.SimpleGui;
|
import eu.pb4.sgui.api.gui.SimpleGui;
|
||||||
|
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||||
|
import io.github.skippyall.minions.gui.MinionBoundSimpleGui;
|
||||||
import io.github.skippyall.minions.registration.MinionComponentTypes;
|
import io.github.skippyall.minions.registration.MinionComponentTypes;
|
||||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||||
import io.github.skippyall.minions.gui.input.Result;
|
import io.github.skippyall.minions.gui.input.Result;
|
||||||
@@ -10,7 +12,6 @@ import io.github.skippyall.minions.minion.MinionRuntime;
|
|||||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||||
import io.github.skippyall.minions.module.MinionModule;
|
import io.github.skippyall.minions.module.MinionModule;
|
||||||
import io.github.skippyall.minions.program.supplier.ValueSupplier;
|
import io.github.skippyall.minions.program.supplier.ValueSupplier;
|
||||||
import io.github.skippyall.minions.program.supplier.ValueSupplierType;
|
|
||||||
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
|
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
|
||||||
import io.github.skippyall.minions.program.instruction.InstructionType;
|
import io.github.skippyall.minions.program.instruction.InstructionType;
|
||||||
import io.github.skippyall.minions.program.supplier.Parameter;
|
import io.github.skippyall.minions.program.supplier.Parameter;
|
||||||
@@ -99,62 +100,6 @@ public class InstructionGui {
|
|||||||
return stillExists;
|
return stillExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static <T, A extends ValueSupplier<T, MinionRuntime>> void configureArgumentMenu(String instructionName, ConfiguredInstruction<MinionRuntime> instruction, Parameter<?> parameter, MinionFakePlayer minion, ServerPlayerEntity player) {
|
|
||||||
if (!checkInstructionExists(instructionName, instruction, minion, player)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable ValueSupplier<?, MinionRuntime> argument = instruction.getArguments().getArgument(parameter);
|
|
||||||
|
|
||||||
if(argument == null) {
|
|
||||||
configureTypeAndValue(instructionName, instruction, parameter, minion, player);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
configureArgumentHelper(instructionName, instruction, parameter, argument, minion, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T> void configureArgumentHelper(String instructionName, ConfiguredInstruction<MinionRuntime> instruction, Parameter<?> parameter, ValueSupplier<T, MinionRuntime> argument, MinionFakePlayer minion, ServerPlayerEntity player) {
|
|
||||||
SimpleGui gui = new InstructionBoundSimpleGui(ScreenHandlerType.GENERIC_3X3, player, minion, instruction);
|
|
||||||
|
|
||||||
ItemStack displayStack = GuiDisplay.getDisplayStack(MinionRegistries.VALUE_SUPPLIER_TYPES, argument.getType(), player.getRegistryManager());
|
|
||||||
|
|
||||||
gui.setSlot(3, new GuiElementBuilder(displayStack)
|
|
||||||
.setName(Text.translatable("minions.gui.instruction.argument.configure.type", Text.translatable(TranslationUtil.getTranslationKey(argument.getType(), MinionRegistries.VALUE_SUPPLIER_TYPES, "minions.gui.instruction.argument.configure.type.unset"))))
|
|
||||||
.setCallback(() -> configureTypeAndValue(instructionName, instruction, parameter, minion, player))
|
|
||||||
);
|
|
||||||
gui.setSlot(5, new GuiElementBuilder(Items.STRUCTURE_VOID)
|
|
||||||
.setName(Text.literal("Configure"))
|
|
||||||
.setCallback(() -> argument.getType().openConfiguration(player, argument.getValueType(), argument)
|
|
||||||
.thenAccept(newArgument -> instruction.getArguments().setArgument(parameter, newArgument))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
gui.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CompletableFuture<ValueSupplierType<MinionRuntime>> selectArgumentType(ServerPlayerEntity player, MinionFakePlayer minion, ConfiguredInstruction<MinionRuntime> instruction) {
|
|
||||||
CompletableFuture<ValueSupplierType<MinionRuntime>> future = new CompletableFuture<>();
|
|
||||||
SimpleGui gui = new InstructionBoundSimpleGui(ScreenHandlerType.GENERIC_9X3, player, minion, instruction);
|
|
||||||
for (ValueSupplierType<MinionRuntime> type : MinionRegistries.VALUE_SUPPLIER_TYPES) {
|
|
||||||
gui.addSlot(new GuiElementBuilder(GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_SUPPLIER_TYPES, type, player.getRegistryManager()))
|
|
||||||
.setCallback(() -> future.complete(type))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
gui.open();
|
|
||||||
return future;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> void configureTypeAndValue(String name, ConfiguredInstruction<MinionRuntime> instruction, Parameter<T> parameter, MinionFakePlayer minion, ServerPlayerEntity player) {
|
|
||||||
selectArgumentType(player, minion, instruction)
|
|
||||||
.thenApply(type -> type.openConfiguration(player, parameter.type(), null)
|
|
||||||
.thenAccept(newArgument -> {
|
|
||||||
instruction.getArguments().setArgument(parameter, newArgument);
|
|
||||||
configureArgumentMenu(name, instruction, parameter, minion, player);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CompletableFuture<InstructionType<MinionRuntime>> selectInstructionModuleMenu(MinionFakePlayer minion, ServerPlayerEntity player) {
|
public static CompletableFuture<InstructionType<MinionRuntime>> selectInstructionModuleMenu(MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||||
if (minion.getModuleInventory().getModules().isEmpty()) {
|
if (minion.getModuleInventory().getModules().isEmpty()) {
|
||||||
player.sendMessage(Text.translatable("minions.gui.instruction.no_modules"));
|
player.sendMessage(Text.translatable("minions.gui.instruction.no_modules"));
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package io.github.skippyall.minions.gui.minion;
|
||||||
|
|
||||||
|
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||||
|
import eu.pb4.sgui.api.gui.SimpleGui;
|
||||||
|
import io.github.skippyall.minions.gui.MinionsGui;
|
||||||
|
import io.github.skippyall.minions.gui.instruction.InstructionGui;
|
||||||
|
import io.github.skippyall.minions.minion.MinionListener;
|
||||||
|
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||||
|
import io.github.skippyall.minions.module.ModuleInventory;
|
||||||
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.screen.ScreenHandlerType;
|
||||||
|
import net.minecraft.screen.slot.ArmorSlot;
|
||||||
|
import net.minecraft.screen.slot.Slot;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
|
public class MinionGui extends MinionsGui implements MinionListener {
|
||||||
|
private final MinionFakePlayer minion;
|
||||||
|
private SimpleGui gui;
|
||||||
|
|
||||||
|
public MinionGui(ServerPlayerEntity viewer, MinionFakePlayer minion) {
|
||||||
|
super(viewer);
|
||||||
|
this.minion = minion;
|
||||||
|
minion.addMinionListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MinionFakePlayer getMinion() {
|
||||||
|
return minion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void open() {
|
||||||
|
gui = new SimpleGui(ScreenHandlerType.GENERIC_3X3, viewer, false) {
|
||||||
|
@Override
|
||||||
|
public void onClose() {
|
||||||
|
onBackingClosed();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
gui.setTitle(minion.getName());
|
||||||
|
|
||||||
|
gui.setSlot(1, new GuiElementBuilder()
|
||||||
|
.setItem(Items.COMMAND_BLOCK)
|
||||||
|
.setName(Text.translatable("minions.gui.main.instructions"))
|
||||||
|
.setCallback(() -> {
|
||||||
|
InstructionGui.openInstructionMainMenu(minion, viewer);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
gui.setSlot(3, new GuiElementBuilder()
|
||||||
|
.setItem(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE)
|
||||||
|
.setName(Text.translatable("minions.gui.main.modules"))
|
||||||
|
.setCallback(() -> {
|
||||||
|
ModuleInventory.openModuleInventory(viewer, minion);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
gui.setSlot(5, new GuiElementBuilder()
|
||||||
|
.setItem(Items.CHEST)
|
||||||
|
.setName(Text.translatable("minions.gui.main.inventory"))
|
||||||
|
.setCallback(() -> new MinionInventoryGui(this))
|
||||||
|
);
|
||||||
|
gui.setSlot(7, new GuiElementBuilder()
|
||||||
|
.setItem(Items.BARRIER)
|
||||||
|
.setName(Text.translatable("minions.gui.main.pickup"))
|
||||||
|
.setCallback(() -> minion.kill(minion.getWorld()))
|
||||||
|
);
|
||||||
|
gui.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void reopen() {
|
||||||
|
gui.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onClose() {
|
||||||
|
gui.close();
|
||||||
|
minion.removeMinionListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMinionRemove(MinionFakePlayer minion) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GuiElementBuilder backButton(Runnable onBack) {
|
||||||
|
return new GuiElementBuilder(Items.COMPASS)
|
||||||
|
.setItemName(Text.translatable("gui.back"))
|
||||||
|
.setCallback(onBack);
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
-44
@@ -1,9 +1,8 @@
|
|||||||
package io.github.skippyall.minions.gui;
|
package io.github.skippyall.minions.gui.minion;
|
||||||
|
|
||||||
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
|
||||||
import eu.pb4.sgui.api.gui.SimpleGui;
|
import eu.pb4.sgui.api.gui.SimpleGui;
|
||||||
|
import io.github.skippyall.minions.gui.MinionsGui;
|
||||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||||
import io.github.skippyall.minions.module.ModuleInventory;
|
|
||||||
import net.minecraft.entity.EquipmentSlot;
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
@@ -11,51 +10,28 @@ import net.minecraft.item.Items;
|
|||||||
import net.minecraft.screen.ScreenHandlerType;
|
import net.minecraft.screen.ScreenHandlerType;
|
||||||
import net.minecraft.screen.slot.ArmorSlot;
|
import net.minecraft.screen.slot.ArmorSlot;
|
||||||
import net.minecraft.screen.slot.Slot;
|
import net.minecraft.screen.slot.Slot;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
public class MinionGui {
|
public class MinionInventoryGui extends MinionsGui {
|
||||||
public static void openInventory(ServerPlayerEntity player, MinionFakePlayer minion) {
|
protected final MinionGui parent;
|
||||||
openServerSideInventory(player, minion);
|
private final MinionFakePlayer minion;
|
||||||
|
|
||||||
|
private SimpleGui gui;
|
||||||
|
|
||||||
|
public MinionInventoryGui(MinionGui parent) {
|
||||||
|
super(parent);
|
||||||
|
this.parent = parent;
|
||||||
|
this.minion = parent.getMinion();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void openServerSideInventory(ServerPlayerEntity player, MinionFakePlayer minion) {
|
@Override
|
||||||
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_3X3, player, false);
|
protected void open() {
|
||||||
gui.setTitle(minion.getName());
|
gui = new SimpleGui(ScreenHandlerType.GENERIC_9X6, viewer, false) {
|
||||||
|
@Override
|
||||||
gui.setSlot(1, new GuiElementBuilder()
|
public void onClose() {
|
||||||
.setItem(Items.COMMAND_BLOCK)
|
onBackingClosed();
|
||||||
.setName(Text.translatable("minions.gui.main.instructions"))
|
}
|
||||||
.setCallback((i, clickType, slotActionType) -> {
|
};
|
||||||
InstructionGui.openInstructionMainMenu(minion, player);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
gui.setSlot(3, new GuiElementBuilder()
|
|
||||||
.setItem(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE)
|
|
||||||
.setName(Text.translatable("minions.gui.main.modules"))
|
|
||||||
.setCallback(() -> {
|
|
||||||
ModuleInventory.openModuleInventory(player, minion);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
gui.setSlot(5, new GuiElementBuilder()
|
|
||||||
.setItem(Items.CHEST)
|
|
||||||
.setName(Text.translatable("minions.gui.main.inventory"))
|
|
||||||
.setCallback(() -> {
|
|
||||||
openMinionInventory(player, minion);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
gui.setSlot(7, new GuiElementBuilder()
|
|
||||||
.setItem(Items.BARRIER)
|
|
||||||
.setName(Text.translatable("minions.gui.main.pickup"))
|
|
||||||
.setCallback(() -> {
|
|
||||||
minion.kill(minion.getWorld());
|
|
||||||
})
|
|
||||||
);
|
|
||||||
gui.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void openMinionInventory(ServerPlayerEntity player, MinionFakePlayer minion) {
|
|
||||||
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_9X6, player, false);
|
|
||||||
gui.setTitle(Text.translatable("minions.gui.inventory.title"));
|
gui.setTitle(Text.translatable("minions.gui.inventory.title"));
|
||||||
|
|
||||||
for(int i = 0; i < 18; i++) {
|
for(int i = 0; i < 18; i++) {
|
||||||
@@ -83,4 +59,9 @@ public class MinionGui {
|
|||||||
}
|
}
|
||||||
gui.open();
|
gui.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onClose() {
|
||||||
|
gui.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ import io.github.skippyall.minions.registration.MinionConfigOptions;
|
|||||||
import io.github.skippyall.minions.registration.MinionItems;
|
import io.github.skippyall.minions.registration.MinionItems;
|
||||||
import io.github.skippyall.minions.minion.MinionListener;
|
import io.github.skippyall.minions.minion.MinionListener;
|
||||||
import io.github.skippyall.minions.minion.MinionData;
|
import io.github.skippyall.minions.minion.MinionData;
|
||||||
import io.github.skippyall.minions.gui.MinionGui;
|
import io.github.skippyall.minions.gui.minion.MinionGui;
|
||||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||||
import io.github.skippyall.minions.minion.MinionItem;
|
import io.github.skippyall.minions.minion.MinionItem;
|
||||||
import io.github.skippyall.minions.minion.MinionPersistentState;
|
import io.github.skippyall.minions.minion.MinionPersistentState;
|
||||||
@@ -24,7 +24,6 @@ import net.minecraft.entity.damage.DamageSource;
|
|||||||
import net.minecraft.entity.player.HungerManager;
|
import net.minecraft.entity.player.HungerManager;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.vehicle.AbstractBoatEntity;
|
import net.minecraft.entity.vehicle.AbstractBoatEntity;
|
||||||
import net.minecraft.entity.vehicle.BoatEntity;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.network.DisconnectionInfo;
|
import net.minecraft.network.DisconnectionInfo;
|
||||||
import net.minecraft.network.NetworkSide;
|
import net.minecraft.network.NetworkSide;
|
||||||
@@ -156,7 +155,7 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
|||||||
@Override
|
@Override
|
||||||
public ActionResult interact(PlayerEntity player, Hand hand) {
|
public ActionResult interact(PlayerEntity player, Hand hand) {
|
||||||
if(player instanceof ServerPlayerEntity spe) {
|
if(player instanceof ServerPlayerEntity spe) {
|
||||||
MinionGui.openInventory(spe, this);
|
new MinionGui(spe, this);
|
||||||
}
|
}
|
||||||
return ActionResult.CONSUME;
|
return ActionResult.CONSUME;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-8
@@ -62,7 +62,7 @@ public class AnalogInputSupplier implements ValueSupplier<Long, MinionRuntime> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Text getDisplayText() {
|
public Text getDisplayText() {
|
||||||
return Text.translatable("value_supplier_type.minions.analog_input.display", analogInputPos.toString(), analogInputWorld.getValue());
|
return Text.translatable("value_supplier_type.minions.analog_input.display", analogInputPos.toString(), analogInputWorld.getValue().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AnalogInputSupplierType extends ValueSupplierType<MinionRuntime> {
|
public static class AnalogInputSupplierType extends ValueSupplierType<MinionRuntime> {
|
||||||
@@ -75,12 +75,8 @@ public class AnalogInputSupplier implements ValueSupplier<Long, MinionRuntime> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> CompletableFuture<ValueSupplier<T, MinionRuntime>> openConfiguration(ServerPlayerEntity player, ValueType<T> valueType, @Nullable ValueSupplier<T, MinionRuntime> previous) {
|
public <T> CompletableFuture<ValueSupplier<?, MinionRuntime>> openConfiguration(ServerPlayerEntity player, ValueType<T> valueType, @Nullable ValueSupplier<T, MinionRuntime> previous) {
|
||||||
if(valueType != ValueTypes.LONG) {
|
CompletableFuture<ValueSupplier<?, MinionRuntime>> future = new CompletableFuture<>();
|
||||||
return CompletableFuture.failedFuture(new IllegalArgumentException("Value type " + valueType + " not allowed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
CompletableFuture<ValueSupplier<T, MinionRuntime>> future = new CompletableFuture<>();
|
|
||||||
|
|
||||||
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_3X3, player, false);
|
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_3X3, player, false);
|
||||||
gui.setTitle(Text.translatable("value_supplier_type.minions.analog_input"));
|
gui.setTitle(Text.translatable("value_supplier_type.minions.analog_input"));
|
||||||
@@ -89,11 +85,12 @@ public class AnalogInputSupplier implements ValueSupplier<Long, MinionRuntime> {
|
|||||||
.setCallback(() -> {
|
.setCallback(() -> {
|
||||||
ItemStack cursor = player.currentScreenHandler.getCursorStack();
|
ItemStack cursor = player.currentScreenHandler.getCursorStack();
|
||||||
if(cursor.isOf(MinionItems.REFERENCE_ITEM) && cursor.get(MinionComponentTypes.REFERENCE) instanceof BlockPosClipboard pos) {
|
if(cursor.isOf(MinionItems.REFERENCE_ITEM) && cursor.get(MinionComponentTypes.REFERENCE) instanceof BlockPosClipboard pos) {
|
||||||
future.complete(new AnalogInputSupplier(pos.world(), pos.pos()).cast(valueType));
|
future.complete(new AnalogInputSupplier(pos.world(), pos.pos()));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.setItemName(Text.translatable("value_supplier_type.minions.analog_input.config.click_with_reference"))
|
.setItemName(Text.translatable("value_supplier_type.minions.analog_input.config.click_with_reference"))
|
||||||
);
|
);
|
||||||
|
gui.open();
|
||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -1,4 +1,6 @@
|
|||||||
package io.github.skippyall.minions.program.value;
|
package io.github.skippyall.minions.program.conversion;
|
||||||
|
|
||||||
|
import io.github.skippyall.minions.program.value.ValueType;
|
||||||
|
|
||||||
public class Cast<F, T> {
|
public class Cast<F, T> {
|
||||||
private final ValueType<F> from;
|
private final ValueType<F> from;
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package io.github.skippyall.minions.program.conversion;
|
||||||
|
|
||||||
|
import com.mojang.serialization.MapCodec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import io.github.skippyall.minions.program.value.ValueType;
|
||||||
|
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||||
|
import io.github.skippyall.minions.registration.ValueConverters;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class CastConverter<F,T> implements ValueConverter<F,T> {
|
||||||
|
private static final MapCodec<CastConverter<?,?>> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
|
||||||
|
MinionRegistries.VALUE_TYPES.getCodec().fieldOf("from").forGetter(CastConverter::getFrom),
|
||||||
|
MinionRegistries.VALUE_TYPES.getCodec().fieldOf("to").forGetter(CastConverter::getTo)
|
||||||
|
).apply(instance, CastConverter::new)
|
||||||
|
);
|
||||||
|
|
||||||
|
private final ValueType<F> from;
|
||||||
|
private final ValueType<T> to;
|
||||||
|
|
||||||
|
public CastConverter(ValueType<F> from, ValueType<T> to) {
|
||||||
|
this.from = from;
|
||||||
|
this.to = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T convert(F fromValue) {
|
||||||
|
return Casts.getCast(from, to).cast(fromValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValueType<F> getFrom() {
|
||||||
|
return from;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValueType<T> getTo() {
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValueConverterType<?> getType() {
|
||||||
|
return ValueConverters.CAST_CONVERTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Type implements ValueConverterType<CastConverter<?,?>> {
|
||||||
|
@Override
|
||||||
|
public MapCodec<CastConverter<?, ?>> getCodec() {
|
||||||
|
return CastConverter.CODEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSupportedConversion(ValueType<?> from, ValueType<?> to) {
|
||||||
|
return Casts.getCast(from, to) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <F,T> CompletableFuture<CastConverter<?,?>> configure(ServerPlayerEntity player, ValueType<F> from, ValueType<T> to, @Nullable CastConverter<?, ?> old) {
|
||||||
|
return CompletableFuture.completedFuture(new CastConverter<>(from, to));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
package io.github.skippyall.minions.program.value;
|
package io.github.skippyall.minions.program.conversion;
|
||||||
|
|
||||||
|
import io.github.skippyall.minions.program.value.ValueType;
|
||||||
import io.github.skippyall.minions.registration.ValueTypes;
|
import io.github.skippyall.minions.registration.ValueTypes;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package io.github.skippyall.minions.program.conversion;
|
||||||
|
|
||||||
|
import com.mojang.serialization.MapCodec;
|
||||||
|
import io.github.skippyall.minions.program.value.ValueType;
|
||||||
|
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||||
|
import io.github.skippyall.minions.registration.ValueTypes;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class EqualityConverter<F> implements ValueConverter<F, Boolean> {
|
||||||
|
public static final MapCodec<EqualityConverter<?>> CODEC = MinionRegistries.VALUE_TYPES.getCodec().dispatchMap(
|
||||||
|
EqualityConverter::getFrom,
|
||||||
|
EqualityConverter::getCodec
|
||||||
|
);
|
||||||
|
|
||||||
|
private ValueType<F> fromType;
|
||||||
|
private F compareValue;
|
||||||
|
|
||||||
|
public EqualityConverter(ValueType<F> fromType, F compareValue) {
|
||||||
|
this.fromType = fromType;
|
||||||
|
this.compareValue = compareValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean convert(F from) {
|
||||||
|
return compareValue.equals(from);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValueType<F> getFrom() {
|
||||||
|
return fromType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValueType<Boolean> getTo() {
|
||||||
|
return ValueTypes.BOOLEAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValueConverterType<?> getType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <F> MapCodec<EqualityConverter<F>> getCodec(ValueType<F> fromType) {
|
||||||
|
return fromType.codec().fieldOf("compareValue")
|
||||||
|
.xmap(compareValue -> new EqualityConverter<>(fromType, compareValue), converter -> converter.compareValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class EqualityConverterType implements ValueConverterType<EqualityConverter<?>> {
|
||||||
|
@Override
|
||||||
|
public MapCodec<EqualityConverter<?>> getCodec() {
|
||||||
|
return CODEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSupportedConversion(ValueType<?> from, ValueType<?> to) {
|
||||||
|
return to == ValueTypes.BOOLEAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <F,T> CompletableFuture<EqualityConverter<?>> configure(ServerPlayerEntity player, ValueType<F> from, ValueType<T> to, @Nullable EqualityConverter<?> old) {
|
||||||
|
if(to == ValueTypes.BOOLEAN) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return from.openValueDialog(player, old != null && old.fromType == from ? (F) old.compareValue : null)
|
||||||
|
.thenApply(compareValue -> new EqualityConverter<>(from, compareValue));
|
||||||
|
} else {
|
||||||
|
return CompletableFuture.failedFuture(new IllegalArgumentException("EqualityConverter does not support converting to " + to));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package io.github.skippyall.minions.program.conversion;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import io.github.skippyall.minions.program.value.ValueType;
|
||||||
|
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
|
public interface ValueConverter<F,T> {
|
||||||
|
Codec<ValueConverter<?,?>> CODEC = MinionRegistries.VALUE_CONVERTER_TYPES.getCodec().dispatch(ValueConverter::getType, ValueConverterType::getCodec);
|
||||||
|
|
||||||
|
T convert(F from);
|
||||||
|
|
||||||
|
ValueType<F> getFrom();
|
||||||
|
|
||||||
|
ValueType<T> getTo();
|
||||||
|
|
||||||
|
ValueConverterType<?> getType();
|
||||||
|
|
||||||
|
Text getDisplayText();
|
||||||
|
|
||||||
|
default <F2,T2> ValueConverter<F2,T2> cast(ValueType<F2> from, ValueType<T2> to) {
|
||||||
|
if(from == getFrom() && to == getTo()) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return (ValueConverter<F2, T2>) this;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package io.github.skippyall.minions.program.conversion;
|
||||||
|
|
||||||
|
import com.mojang.serialization.MapCodec;
|
||||||
|
import io.github.skippyall.minions.program.value.ValueType;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public interface ValueConverterType<C extends ValueConverter<?,?>> {
|
||||||
|
MapCodec<C> getCodec();
|
||||||
|
|
||||||
|
boolean isSupportedConversion(ValueType<?> from, ValueType<?> to);
|
||||||
|
|
||||||
|
<F,T> CompletableFuture<C> configure(ServerPlayerEntity player, ValueType<F> from, ValueType<T> to, @Nullable C old);
|
||||||
|
}
|
||||||
+5
-1
@@ -11,6 +11,10 @@ import net.minecraft.storage.ReadView;
|
|||||||
import net.minecraft.storage.WriteView;
|
import net.minecraft.storage.WriteView;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds an instruction, its configuration and is responsible for executing the instruction
|
||||||
|
* @param <R> The runtime holding this object
|
||||||
|
*/
|
||||||
public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
|
public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
|
||||||
private final InstructionType<R> instruction;
|
private final InstructionType<R> instruction;
|
||||||
private final ValueSupplierList<R> arguments;
|
private final ValueSupplierList<R> arguments;
|
||||||
@@ -48,7 +52,7 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean canRun() {
|
public boolean canRun() {
|
||||||
return instruction != null && arguments != null && arguments.hasArgumentForAll(instruction.getParameters());
|
return instruction != null && arguments != null && arguments.checkRun(instruction).isSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRunning() {
|
public boolean isRunning() {
|
||||||
|
|||||||
@@ -9,6 +9,11 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the semantics of an instruction and creates {@link InstructionExecution}
|
||||||
|
* InstructionTypes for minions can be registered to {@link io.github.skippyall.minions.registration.MinionRegistries#INSTRUCTION_TYPES}
|
||||||
|
* @param <R> The runtime that this instruction can be executed in
|
||||||
|
*/
|
||||||
public class InstructionType<R extends InstructionRuntime<R>> {
|
public class InstructionType<R extends InstructionRuntime<R>> {
|
||||||
private final List<Parameter<?>> parameters;
|
private final List<Parameter<?>> parameters;
|
||||||
private final List<Parameter<?>> returnParameters;
|
private final List<Parameter<?>> returnParameters;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.github.skippyall.minions.program.supplier;
|
package io.github.skippyall.minions.program.supplier;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.MapCodec;
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import io.github.skippyall.minions.program.value.SimpleValueType;
|
import io.github.skippyall.minions.program.value.SimpleValueType;
|
||||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||||
@@ -8,11 +9,12 @@ import io.github.skippyall.minions.program.value.ValueType;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public record Parameter<T>(String name, ValueType<T> type) {
|
public record Parameter<T>(String name, ValueType<T> type) {
|
||||||
public static final Codec<Parameter<?>> CODEC = RecordCodecBuilder.create(instance ->
|
public static final MapCodec<Parameter<?>> MAP_CODEC = RecordCodecBuilder.mapCodec(instance ->
|
||||||
instance.group(
|
instance.group(
|
||||||
Codec.STRING.fieldOf("name").forGetter(Parameter::name),
|
Codec.STRING.fieldOf("name").forGetter(Parameter::name),
|
||||||
MinionRegistries.VALUE_TYPES.getCodec().fieldOf("type").forGetter(Parameter::type)
|
MinionRegistries.VALUE_TYPES.getCodec().fieldOf("type").forGetter(Parameter::type)
|
||||||
).apply(instance, Parameter::new));
|
).apply(instance, Parameter::new));
|
||||||
|
public static final Codec<Parameter<?>> CODEC = MAP_CODEC.codec();
|
||||||
|
|
||||||
public <U> @Nullable Parameter<U> cast(ValueType<U> type) {
|
public <U> @Nullable Parameter<U> cast(ValueType<U> type) {
|
||||||
if(this.type == type) {
|
if(this.type == type) {
|
||||||
|
|||||||
+152
-30
@@ -1,69 +1,100 @@
|
|||||||
package io.github.skippyall.minions.program.supplier;
|
package io.github.skippyall.minions.program.supplier;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.MapCodec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import io.github.skippyall.minions.gui.input.Result;
|
||||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||||
import io.github.skippyall.minions.program.value.Cast;
|
import io.github.skippyall.minions.program.conversion.Cast;
|
||||||
import io.github.skippyall.minions.program.value.Casts;
|
import io.github.skippyall.minions.program.conversion.Casts;
|
||||||
|
import io.github.skippyall.minions.program.conversion.ValueConverter;
|
||||||
|
import io.github.skippyall.minions.program.instruction.InstructionType;
|
||||||
|
import io.github.skippyall.minions.program.value.ValueType;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class ValueSupplierList<R extends InstructionRuntime<R>> {
|
public class ValueSupplierList<R extends InstructionRuntime<R>> {
|
||||||
private final Map<String, ValueSupplier<?, R>> arguments;
|
private final Map<Parameter<?>, ValueSupplierEntry<?,?,R>> arguments = new HashMap<>();
|
||||||
private final List<Consumer<Parameter<?>>> changeListeners = new ArrayList<>();
|
private final List<Consumer<Parameter<?>>> changeListeners = new ArrayList<>();
|
||||||
|
|
||||||
public ValueSupplierList() {
|
public ValueSupplierList() {
|
||||||
arguments = new HashMap<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueSupplierList(Map<String, ValueSupplier<?,R>> arguments) {
|
private ValueSupplierList(List<ValueSupplierEntry<?,?,R>> arguments) {
|
||||||
this.arguments = new HashMap<>(arguments);
|
for(ValueSupplierEntry<?,?,R> argument : arguments) {
|
||||||
|
this.arguments.put(argument.parameter, argument);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public <F, T> T getValue(Parameter<T> parameter, R runtime) {
|
private List<ValueSupplierEntry<?,?,R>> toCodecList() {
|
||||||
//noinspection unchecked
|
return List.copyOf(arguments.values());
|
||||||
ValueSupplier<F,R> valueSupplier = (ValueSupplier<F, R>) getArgument(parameter);
|
}
|
||||||
if(valueSupplier == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(valueSupplier.getValueType() == parameter.type()) {
|
public <T> T getValue(Parameter<T> parameter, R runtime) {
|
||||||
return valueSupplier.cast(parameter.type()).resolve(runtime);
|
ValueSupplierEntry<?,?,R> entry = getEntry(parameter);
|
||||||
} else {
|
return parameter.type().checkedCast(entry.getValue(runtime));
|
||||||
Cast<F,T> cast = Casts.getCast(valueSupplier.getValueType(), parameter.type());
|
|
||||||
if(cast != null) {
|
|
||||||
return cast.cast(valueSupplier.resolve(runtime));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueSupplier<?,R> getArgument(Parameter<?> parameter) {
|
public ValueSupplier<?,R> getArgument(Parameter<?> parameter) {
|
||||||
return arguments.get(parameter.name());
|
if(arguments.containsKey(parameter)) {
|
||||||
|
return arguments.get(parameter).supplier;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> void setArgument(Parameter<T> parameter, ValueSupplier<?,R> valueSupplier) {
|
public <P> ValueSupplierEntry<P,?,R> getEntry(Parameter<P> parameter) {
|
||||||
arguments.put(parameter.name(), valueSupplier);
|
//noinspection unchecked
|
||||||
|
return (ValueSupplierEntry<P, ?, R>) arguments.get(parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArgument(Parameter<?> parameter, ValueSupplier<?,R> valueSupplier) {
|
||||||
|
arguments.put(parameter, new ValueSupplierEntry<>(parameter, valueSupplier, List.of()));
|
||||||
|
onChange(parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArgument(Parameter<?> parameter, ValueSupplier<?,R> valueSupplier, List<ValueConverter<?, ?>> converter) {
|
||||||
|
arguments.put(parameter, new ValueSupplierEntry<>(parameter, valueSupplier, converter));
|
||||||
onChange(parameter);
|
onChange(parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasArgumentFor(Parameter<?> parameter) {
|
public boolean hasArgumentFor(Parameter<?> parameter) {
|
||||||
return arguments.containsKey(parameter.name());
|
return arguments.containsKey(parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasArgumentForAll(Collection<Parameter<?>> checkParameters) {
|
public Result<@Nullable Void, Text> checkHasArguments(Collection<Parameter<?>> checkParameters) {
|
||||||
for(Parameter<?> parameter : checkParameters) {
|
for(Parameter<?> parameter : checkParameters) {
|
||||||
if(!hasArgumentFor(parameter)) {
|
if(!hasArgumentFor(parameter)) {
|
||||||
return false;
|
return new Result.Error<>(Text.translatable("minions.gui.instruction.check.argument_not_set", parameter.name()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return new Result.Success<>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Result<@Nullable Void, Text> checkRun(InstructionType<R> instructionType) {
|
||||||
|
Result<@Nullable Void, Text> checkResult = checkHasArguments(instructionType.getParameters());
|
||||||
|
if(!checkResult.isSuccess()) {
|
||||||
|
return checkResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(ValueSupplierEntry<?,?,R> entry : arguments.values()) {
|
||||||
|
checkResult = entry.check();
|
||||||
|
if(!checkResult.isSuccess()) {
|
||||||
|
return checkResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Result.Success<>(null);
|
||||||
|
}
|
||||||
|
|
||||||
private void onChange(Parameter<?> parameter) {
|
private void onChange(Parameter<?> parameter) {
|
||||||
for (Consumer<Parameter<?>> listener : changeListeners) {
|
for (Consumer<Parameter<?>> listener : changeListeners) {
|
||||||
@@ -80,7 +111,98 @@ public class ValueSupplierList<R extends InstructionRuntime<R>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static <R extends InstructionRuntime<R>> Codec<ValueSupplierList<R>> getCodec(Codec<ValueSupplier<?,R>> argumentCodec) {
|
public static <R extends InstructionRuntime<R>> Codec<ValueSupplierList<R>> getCodec(Codec<ValueSupplier<?,R>> argumentCodec) {
|
||||||
return Codec.unboundedMap(Codec.STRING, argumentCodec)
|
return ValueSupplierEntry.getCodec(argumentCodec)
|
||||||
.xmap(ValueSupplierList::new, list -> list.arguments);
|
.codec()
|
||||||
|
.listOf()
|
||||||
|
.xmap(ValueSupplierList::new, ValueSupplierList::toCodecList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ValueSupplierEntry<S, P, R extends InstructionRuntime<R>> {
|
||||||
|
private Parameter<P> parameter;
|
||||||
|
private ValueSupplier<S,R> supplier;
|
||||||
|
private List<ValueConverter<?,?>> converters;
|
||||||
|
|
||||||
|
public ValueSupplierEntry(Parameter<P> parameter, ValueSupplier<S, R> supplier, Collection<ValueConverter<?, ?>> converters) {
|
||||||
|
this.parameter = parameter;
|
||||||
|
this.supplier = supplier;
|
||||||
|
this.converters = new LinkedList<>(converters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ValueConverter<?,?>> getConverters() {
|
||||||
|
return converters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Parameter<P> getParameter() {
|
||||||
|
return parameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueSupplier<S, R> getSupplier() {
|
||||||
|
return supplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParameter(Parameter<P> parameter) {
|
||||||
|
this.parameter = parameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSupplier(ValueSupplier<S, R> supplier) {
|
||||||
|
this.supplier = supplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConverters(List<ValueConverter<?, ?>> converters) {
|
||||||
|
this.converters = converters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable P getValue(R runtime) {
|
||||||
|
S value = supplier.resolve(runtime);
|
||||||
|
Iterator<ValueConverter<?,?>> iterator = converters.iterator();
|
||||||
|
Object convertedValue = convert(supplier.getValueType(), value, iterator.next(), iterator);
|
||||||
|
|
||||||
|
return finalCast(convertedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <F> @Nullable P finalCast(Object value) {
|
||||||
|
//noinspection unchecked
|
||||||
|
ValueType<F> lastConvertedType = (ValueType<F>) converters.getLast().getTo();
|
||||||
|
F convertedValue = lastConvertedType.checkedCast(value);
|
||||||
|
if(convertedValue == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cast<F,P> cast = Casts.getCast(lastConvertedType, parameter.type());
|
||||||
|
if(cast != null) {
|
||||||
|
return cast.cast(convertedValue);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <F,I,T> @Nullable Object convert(ValueType<F> fromType, F from, ValueConverter<I,T> converter, Iterator<ValueConverter<?,?>> iterator) {
|
||||||
|
Cast<F, I> cast = Casts.getCast(fromType, converter.getFrom());
|
||||||
|
if(cast == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
I inter = cast.cast(from);
|
||||||
|
if(inter == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
T to = converter.convert(inter);
|
||||||
|
|
||||||
|
if(iterator.hasNext() && to != null) {
|
||||||
|
return convert(converter.getTo(), to, iterator.next(), iterator);
|
||||||
|
} else {
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<@Nullable Void, Text> check() {
|
||||||
|
return new Result.Success<>(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <R extends InstructionRuntime<R>> MapCodec<ValueSupplierEntry<?,?,R>> getCodec(Codec<ValueSupplier<?,R>> argumentCodec) {
|
||||||
|
return RecordCodecBuilder.mapCodec(instance -> instance.group(
|
||||||
|
Parameter.CODEC.fieldOf("parameter").forGetter(e -> e.parameter),
|
||||||
|
argumentCodec.fieldOf("argument").forGetter(e -> e.supplier),
|
||||||
|
ValueConverter.CODEC.listOf().optionalFieldOf("converter", List.of()).forGetter(e -> e.converters)
|
||||||
|
).apply(instance, ValueSupplierEntry::new));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,5 +11,5 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
public abstract class ValueSupplierType<R extends InstructionRuntime<R>> {
|
public abstract class ValueSupplierType<R extends InstructionRuntime<R>> {
|
||||||
public abstract <T> Codec<? extends ValueSupplier<T,R>> getCodec(ValueType<T> type);
|
public abstract <T> Codec<? extends ValueSupplier<T,R>> getCodec(ValueType<T> type);
|
||||||
|
|
||||||
public abstract <T> CompletableFuture<? extends ValueSupplier<T,R>> openConfiguration(ServerPlayerEntity player, ValueType<T> valueType, @Nullable ValueSupplier<T,R> previous);
|
public abstract <T> CompletableFuture<? extends ValueSupplier<?,R>> openConfiguration(ServerPlayerEntity player, ValueType<T> valueType, @Nullable ValueSupplier<T,R> previous);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
package io.github.skippyall.minions.program.value;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
|
||||||
import net.minecraft.text.Text;
|
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
public class LongValueType implements ValueType<Long> {
|
|
||||||
@Override
|
|
||||||
public CompletableFuture<Long> openValueDialog(ServerPlayerEntity player, Long previousValue) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Text getDisplayText(Long value) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Codec<Long> codec() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long defaultValue() {
|
|
||||||
return 0L;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,7 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public record SimpleValueType<T>(Codec<T> codec, T defaultValue, BiFunction<ServerPlayerEntity, T, CompletableFuture<T>> valueDialogOpener, Function<T, Text> textDisplay) implements ValueType<T> {
|
public record SimpleValueType<T>(Codec<T> codec, T defaultValue, Function<Object, T> checkedCast, BiFunction<ServerPlayerEntity, T, CompletableFuture<T>> valueDialogOpener, Function<T, Text> textDisplay) implements ValueType<T> {
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<T> openValueDialog(ServerPlayerEntity player, T previousValue) {
|
public CompletableFuture<T> openValueDialog(ServerPlayerEntity player, T previousValue) {
|
||||||
return valueDialogOpener.apply(player, previousValue);
|
return valueDialogOpener.apply(player, previousValue);
|
||||||
@@ -19,4 +19,9 @@ public record SimpleValueType<T>(Codec<T> codec, T defaultValue, BiFunction<Serv
|
|||||||
public Text getDisplayText(T value) {
|
public Text getDisplayText(T value) {
|
||||||
return textDisplay.apply(value);
|
return textDisplay.apply(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T checkedCast(Object value) {
|
||||||
|
return checkedCast.apply(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,4 +17,10 @@ public interface ValueType<T> {
|
|||||||
Codec<T> codec();
|
Codec<T> codec();
|
||||||
|
|
||||||
T defaultValue();
|
T defaultValue();
|
||||||
|
|
||||||
|
@Nullable T checkedCast(Object value);
|
||||||
|
|
||||||
|
default boolean isOf(Object value) {
|
||||||
|
return checkedCast(value) != null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-13
@@ -1,13 +0,0 @@
|
|||||||
package io.github.skippyall.minions.program.value.conversion;
|
|
||||||
|
|
||||||
import io.github.skippyall.minions.program.value.ValueType;
|
|
||||||
|
|
||||||
public interface ValueConverter<F,T> {
|
|
||||||
T convert(F from);
|
|
||||||
|
|
||||||
ValueType<F> getFrom();
|
|
||||||
|
|
||||||
ValueType<T> getTo();
|
|
||||||
|
|
||||||
ValueConverterType<?> getType();
|
|
||||||
}
|
|
||||||
-18
@@ -1,18 +0,0 @@
|
|||||||
package io.github.skippyall.minions.program.value.conversion;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import io.github.skippyall.minions.program.value.ValueType;
|
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
public interface ValueConverterType<C extends ValueConverter<?,?>> {
|
|
||||||
Codec<C> getCodec(ValueType<?> from, ValueType<?> to);
|
|
||||||
|
|
||||||
boolean isSupportedFromType(ValueType<?> type);
|
|
||||||
|
|
||||||
boolean isSupportedToType(ValueType<?> type);
|
|
||||||
|
|
||||||
CompletableFuture<C> configure(ServerPlayerEntity player, ValueType<?> from, ValueType<?> to, @Nullable C old);
|
|
||||||
}
|
|
||||||
@@ -16,7 +16,7 @@ import java.util.UUID;
|
|||||||
public class MinionComponentTypes {
|
public class MinionComponentTypes {
|
||||||
public static final ComponentType<UUID> MINION_DATA = register("minion_data", ComponentType.<UUID>builder().codec(Uuids.CODEC).build());
|
public static final ComponentType<UUID> MINION_DATA = register("minion_data", ComponentType.<UUID>builder().codec(Uuids.CODEC).build());
|
||||||
public static final ComponentType<MinionModule> MODULE = register("minion_module", ComponentType.<MinionModule>builder().codec(MinionModule.CODEC).build());
|
public static final ComponentType<MinionModule> MODULE = register("minion_module", ComponentType.<MinionModule>builder().codec(MinionModule.CODEC).build());
|
||||||
public static final ComponentType<Clipboard> REFERENCE = ComponentType.<Clipboard>builder().codec(Clipboard.CODEC).build();
|
public static final ComponentType<Clipboard> REFERENCE = register("reference", ComponentType.<Clipboard>builder().codec(Clipboard.CODEC).build());
|
||||||
|
|
||||||
private static <T extends ComponentType<?>> T register(String name, T type) {
|
private static <T extends ComponentType<?>> T register(String name, T type) {
|
||||||
Registry.register(Registries.DATA_COMPONENT_TYPE, Identifier.of(Minions.MOD_ID, name), type);
|
Registry.register(Registries.DATA_COMPONENT_TYPE, Identifier.of(Minions.MOD_ID, name), type);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ public class MinionRegistration {
|
|||||||
MinionListeners.register();
|
MinionListeners.register();
|
||||||
SkinProviders.register();
|
SkinProviders.register();
|
||||||
SpecialAbilities.register();
|
SpecialAbilities.register();
|
||||||
|
ValueConverters.register();
|
||||||
ValueSuppliers.register();
|
ValueSuppliers.register();
|
||||||
ValueTypes.register();
|
ValueTypes.register();
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import io.github.skippyall.minions.program.instruction.InstructionType;
|
|||||||
import io.github.skippyall.minions.program.consumer.ValueConsumerType;
|
import io.github.skippyall.minions.program.consumer.ValueConsumerType;
|
||||||
import io.github.skippyall.minions.program.value.ValueType;
|
import io.github.skippyall.minions.program.value.ValueType;
|
||||||
import io.github.skippyall.minions.clipboard.Clipboard;
|
import io.github.skippyall.minions.clipboard.Clipboard;
|
||||||
|
import io.github.skippyall.minions.program.conversion.ValueConverterType;
|
||||||
import net.fabricmc.fabric.api.event.registry.DynamicRegistries;
|
import net.fabricmc.fabric.api.event.registry.DynamicRegistries;
|
||||||
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
|
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
|
||||||
import net.fabricmc.fabric.api.event.registry.RegistryAttribute;
|
import net.fabricmc.fabric.api.event.registry.RegistryAttribute;
|
||||||
@@ -29,6 +30,8 @@ public class MinionRegistries {
|
|||||||
public static final Registry<ValueSupplierType<MinionRuntime>> VALUE_SUPPLIER_TYPES = registry("value_supplier_type");
|
public static final Registry<ValueSupplierType<MinionRuntime>> VALUE_SUPPLIER_TYPES = registry("value_supplier_type");
|
||||||
public static final Registry<ValueConsumerType<MinionRuntime>> VALUE_CONSUMER_TYPES = registry("value_consumer_type");
|
public static final Registry<ValueConsumerType<MinionRuntime>> VALUE_CONSUMER_TYPES = registry("value_consumer_type");
|
||||||
public static final Registry<InstructionType<MinionRuntime>> INSTRUCTION_TYPES = registry("instruction_type");
|
public static final Registry<InstructionType<MinionRuntime>> INSTRUCTION_TYPES = registry("instruction_type");
|
||||||
|
public static final Registry<ValueConverterType<?>> VALUE_CONVERTER_TYPES = registry("value_converter_type");
|
||||||
|
|
||||||
public static final Registry<SkinProvider> SKIN_PROVIDERS = registry("skin_provider");
|
public static final Registry<SkinProvider> SKIN_PROVIDERS = registry("skin_provider");
|
||||||
public static final Registry<Codec<? extends GuiDisplay>> GUI_DISPLAY_TYPE = registry("gui_display_type");
|
public static final Registry<Codec<? extends GuiDisplay>> GUI_DISPLAY_TYPE = registry("gui_display_type");
|
||||||
public static final Registry<Codec<? extends ConfiguredInstructionListener>> INSTRUCTION_LISTENER_CODECS = registry("instruction_listener_codec");
|
public static final Registry<Codec<? extends ConfiguredInstructionListener>> INSTRUCTION_LISTENER_CODECS = registry("instruction_listener_codec");
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package io.github.skippyall.minions.registration;
|
||||||
|
|
||||||
|
import io.github.skippyall.minions.Minions;
|
||||||
|
import io.github.skippyall.minions.program.conversion.CastConverter;
|
||||||
|
import io.github.skippyall.minions.program.conversion.EqualityConverter;
|
||||||
|
import io.github.skippyall.minions.program.conversion.ValueConverterType;
|
||||||
|
import net.minecraft.registry.Registry;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class ValueConverters {
|
||||||
|
public static final EqualityConverter.EqualityConverterType EQUALITY_CONVERTER = register("equality_converter", new EqualityConverter.EqualityConverterType());
|
||||||
|
public static final CastConverter.Type CAST_CONVERTER = register("cast_converter", new CastConverter.Type());
|
||||||
|
|
||||||
|
private static <T extends ValueConverterType<?>> T register(String name, T type) {
|
||||||
|
return Registry.register(MinionRegistries.VALUE_CONVERTER_TYPES, Identifier.of(Minions.MOD_ID, name), type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void register() {}
|
||||||
|
}
|
||||||
@@ -8,85 +8,88 @@ import io.github.skippyall.minions.gui.input.ChoiceInput;
|
|||||||
import io.github.skippyall.minions.gui.input.TextInput;
|
import io.github.skippyall.minions.gui.input.TextInput;
|
||||||
import io.github.skippyall.minions.minion.program.instruction.move.TurnDirection;
|
import io.github.skippyall.minions.minion.program.instruction.move.TurnDirection;
|
||||||
import net.minecraft.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public class ValueTypes {
|
public class ValueTypes {
|
||||||
public static ValueType<Long> LONG = registerSimple(
|
public static ValueType<Long> LONG = register(
|
||||||
"long",
|
"long",
|
||||||
Codec.LONG,
|
new SimpleValueType<>(
|
||||||
0L,
|
Codec.LONG,
|
||||||
(player, oldValue) -> TextInput.inputLong(
|
0L,
|
||||||
player,
|
o -> o instanceof Long l ? l : null,
|
||||||
Text.literal("Integer"),
|
(player, oldValue) -> TextInput.inputLong(
|
||||||
String.valueOf(oldValue)
|
player,
|
||||||
),
|
Text.literal("Integer"),
|
||||||
value -> Text.literal(value.toString())
|
String.valueOf(oldValue)
|
||||||
|
),
|
||||||
|
value -> Text.literal(value.toString())
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
public static ValueType<Double> DOUBLE = registerSimple(
|
public static ValueType<Double> DOUBLE = register(
|
||||||
"double",
|
"double",
|
||||||
Codec.DOUBLE,
|
new SimpleValueType<>(
|
||||||
0D,
|
Codec.DOUBLE,
|
||||||
(player, oldValue) -> TextInput.inputDouble(
|
0D,
|
||||||
player,
|
o -> o instanceof Double d ? d : null,
|
||||||
Text.literal("Number"),
|
(player, oldValue) -> TextInput.inputDouble(
|
||||||
String.valueOf(oldValue)
|
player,
|
||||||
),
|
Text.literal("Number"),
|
||||||
value -> Text.literal(value.toString())
|
String.valueOf(oldValue)
|
||||||
|
),
|
||||||
|
value -> Text.literal(value.toString())
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
public static ValueType<Boolean> BOOLEAN = registerSimple(
|
public static ValueType<Boolean> BOOLEAN = register(
|
||||||
"boolean",
|
"boolean",
|
||||||
Codec.BOOL,
|
new SimpleValueType<>(
|
||||||
false,
|
Codec.BOOL,
|
||||||
ChoiceInput.inputBoolean(Text.literal("")),
|
false,
|
||||||
value -> Text.literal(value.toString())
|
o -> o instanceof Boolean b ? b : null,
|
||||||
|
ChoiceInput.inputBoolean(Text.literal("")),
|
||||||
|
value -> Text.literal(value.toString())
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
public static ValueType<String> STRING = registerSimple(
|
public static ValueType<String> STRING = register(
|
||||||
"string",
|
"string",
|
||||||
Codec.STRING,
|
new SimpleValueType<>(
|
||||||
"",
|
Codec.STRING,
|
||||||
((player, oldValue) -> TextInput.inputString(
|
"",
|
||||||
player,
|
o -> o instanceof String s ? s : null,
|
||||||
Text.literal("Text"),
|
((player, oldValue) -> TextInput.inputString(
|
||||||
oldValue)
|
player,
|
||||||
),
|
Text.literal("Text"),
|
||||||
value -> Text.literal("\"" + value + "\"")
|
oldValue)
|
||||||
|
),
|
||||||
|
value -> Text.literal("\"" + value + "\"")
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
public static ValueType<TurnDirection> TURN_DIRECTION = registerSimple(
|
public static ValueType<TurnDirection> TURN_DIRECTION = register(
|
||||||
"turn_direction",
|
"turn_direction",
|
||||||
TurnDirection.CODEC,
|
new SimpleValueType<>(
|
||||||
TurnDirection.RIGHT,
|
TurnDirection.CODEC,
|
||||||
ChoiceInput.createDialogOpener(TurnDirection.values()),
|
TurnDirection.RIGHT,
|
||||||
value -> Text.literal(value.name)
|
o -> o instanceof TurnDirection d ? d : null,
|
||||||
|
ChoiceInput.createDialogOpener(TurnDirection.values()),
|
||||||
|
value -> Text.literal(value.name)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
private static <T> ValueType<T> registerSimple(
|
private static <T extends ValueType<?>> T register(
|
||||||
String id,
|
String id,
|
||||||
Codec<T> codec,
|
T type
|
||||||
T defaultValue,
|
|
||||||
BiFunction<ServerPlayerEntity, T, CompletableFuture<T>> valueDialogOpener,
|
|
||||||
Function<T, Text> textDisplay
|
|
||||||
) {
|
) {
|
||||||
Identifier identifier = Identifier.of(Minions.MOD_ID, id);
|
Identifier identifier = Identifier.of(Minions.MOD_ID, id);
|
||||||
return Registry.register(
|
Registry.register(
|
||||||
MinionRegistries.VALUE_TYPES,
|
MinionRegistries.VALUE_TYPES,
|
||||||
identifier,
|
identifier,
|
||||||
new SimpleValueType<>(
|
type
|
||||||
codec,
|
|
||||||
defaultValue,
|
|
||||||
valueDialogOpener,
|
|
||||||
textDisplay
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void register() {}
|
public static void register() {}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
"minions.gui.ok": "OK",
|
"minions.gui.ok": "OK",
|
||||||
"minions.gui.confirm": "Confirm",
|
"minions.gui.confirm": "Confirm",
|
||||||
"minions.gui.abort": "Abort",
|
"minions.gui.abort": "Abort",
|
||||||
|
"minions.gui.back": "Back",
|
||||||
|
|
||||||
"minions.gui.look.skin.name": "Name",
|
"minions.gui.look.skin.name": "Name",
|
||||||
"minions.gui.look.skin.name.title": "Enter a player name",
|
"minions.gui.look.skin.name.title": "Enter a player name",
|
||||||
@@ -39,6 +40,8 @@
|
|||||||
"minions.gui.instruction.parameter": "%s: %s",
|
"minions.gui.instruction.parameter": "%s: %s",
|
||||||
"minions.gui.instruction.argument": "Argument: %s",
|
"minions.gui.instruction.argument": "Argument: %s",
|
||||||
|
|
||||||
|
"minions.gui.instruction.check.argument_not_set": "Argument %s is not set",
|
||||||
|
|
||||||
"minions.command.input.int.fail": "Not an integer",
|
"minions.command.input.int.fail": "Not an integer",
|
||||||
"minions.command.input.float.fail": "Not a number",
|
"minions.command.input.float.fail": "Not a number",
|
||||||
"minions.command.action.details": "Set how to %s",
|
"minions.command.action.details": "Set how to %s",
|
||||||
|
|||||||
Reference in New Issue
Block a user