Swap item instruction (for now) & freezin

This commit is contained in:
skippyall
2026-01-29 21:44:52 +01:00
parent 5bd7c08f83
commit 1e430ef506
17 changed files with 185 additions and 65 deletions
@@ -26,6 +26,7 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.server.network.ServerPlayNetworkHandler; import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
@@ -150,6 +151,11 @@ public class MinionTriggerBlock extends BlockWithEntity implements PolymerBlock,
return PolymerUtil.isOnClient(context) ? state : net.minecraft.block.Blocks.COMPARATOR.getDefaultState().with(AbstractRedstoneGateBlock.POWERED, state.get(POWERED)); return PolymerUtil.isOnClient(context) ? state : net.minecraft.block.Blocks.COMPARATOR.getDefaultState().with(AbstractRedstoneGateBlock.POWERED, state.get(POWERED));
} }
@Override
public boolean handleMiningOnServer(ItemStack tool, BlockState state, BlockPos pos, ServerPlayerEntity player) {
return false;
}
@Override @Override
public @Nullable ElementHolder createElementHolder(ServerWorld world, BlockPos pos, BlockState initialBlockState) { public @Nullable ElementHolder createElementHolder(ServerWorld world, BlockPos pos, BlockState initialBlockState) {
ElementHolder holder = new ElementHolder() { ElementHolder holder = new ElementHolder() {
@@ -105,9 +105,9 @@ public class ConfigureInstructionGui extends InstructionBoundSimpleGui {
} }
private void updateSuppliers() { private void updateSuppliers() {
int slot = 11; int slot = 12;
for(Parameter<?> parameter : instruction.getInstruction().getParameters().reversed()) { for(Parameter<?> parameter : instruction.getInstruction().getParameters().reversed()) {
setSlot(slot, InstructionGui.createParameterElement(parameter, player.getRegistryManager()) setSlot(slot, InstructionGui.createParameterElement(parameter, instruction.getArguments().getArgument(parameter), player.getRegistryManager())
.setCallback(() -> InstructionGui.configureArgumentMenu(name, instruction, parameter, minion, player)) .setCallback(() -> InstructionGui.configureArgumentMenu(name, instruction, parameter, minion, player))
); );
slot--; slot--;
@@ -221,19 +221,12 @@ public class InstructionGui {
return instructionBuilder; return instructionBuilder;
} }
public static GuiElementBuilder createParameterElement(Parameter<?> parameter, DynamicRegistryManager manager) { public static GuiElementBuilder createParameterElement(Parameter<?> parameter, @Nullable ValueSupplier<?,?> valueSupplier, DynamicRegistryManager manager) {
return new GuiElementBuilder(GuiDisplay.getDisplayStack(MinionRegistries.VALUE_TYPES, parameter.type(), manager)) GuiElementBuilder builder = new GuiElementBuilder(GuiDisplay.getDisplayStack(MinionRegistries.VALUE_TYPES, parameter.type(), manager))
.setName(Text.translatable("minions.gui.instruction.parameter", parameter.name(), Text.translatable(TranslationUtil.getTranslationKey(parameter.type(), MinionRegistries.VALUE_TYPES)))); .setName(Text.translatable("minions.gui.instruction.parameter", parameter.name(), Text.translatable(TranslationUtil.getTranslationKey(parameter.type(), MinionRegistries.VALUE_TYPES))));
if(valueSupplier != null) {
builder.addLoreLine(Text.translatable("minions.gui.instruction.argument", valueSupplier.getDisplayText()));
} }
return builder;
public static GuiElementBuilder createArgumentElement(ValueSupplier<?, MinionRuntime> valueSupplier, DynamicRegistryManager manager) {
GuiElementBuilder argumentBuilder;
if (valueSupplier != null) {
argumentBuilder = new GuiElementBuilder(GuiDisplay.getDisplayStack(MinionRegistries.VALUE_SUPPLIER_TYPES, valueSupplier.getType(), manager));
} else {
argumentBuilder = new GuiElementBuilder(Items.RED_WOOL)
.setName(Text.translatable("minions.gui.instruction.no_argument_set"));
}
return argumentBuilder;
} }
} }
@@ -71,4 +71,14 @@ public class ChoiceInput {
gui.open(); gui.open();
return future; return future;
} }
public static BiFunction<ServerPlayerEntity, Boolean, CompletableFuture<Boolean>> inputBoolean(Text title) {
return createDialogOpener(ScreenHandlerType.GENERIC_3X3, title, value -> {
if(value) {
return new GuiDisplay.ItemBased(Items.EMERALD_BLOCK);
} else {
return new GuiDisplay.ItemBased(Items.REDSTONE_BLOCK);
}
}, new Boolean[]{false, true}, false);
}
} }
@@ -28,6 +28,16 @@ public class ActionExecution implements ContinuousInstructionExecution<MinionRun
minion.getMinion().getMinionActionPack().stop(action); minion.getMinion().getMinionActionPack().stop(action);
} }
@Override
public void pause(MinionRuntime runtime) {
runtime.getMinion().getMinionActionPack().stop(action);
}
@Override
public void resume(MinionRuntime runtime) {
runtime.getMinion().getMinionActionPack().start(action, EntityPlayerActionPack.Action.continuous());
}
@Override @Override
public void readArguments(ValueSupplierList<MinionRuntime> parameters, MinionRuntime minion) {} public void readArguments(ValueSupplierList<MinionRuntime> parameters, MinionRuntime minion) {}
@@ -35,7 +45,7 @@ public class ActionExecution implements ContinuousInstructionExecution<MinionRun
public void save(WriteView view, MinionRuntime minion) {} public void save(WriteView view, MinionRuntime minion) {}
@Override @Override
public void load(ReadView view, MinionRuntime minion) { public void load(ReadView view, MinionRuntime runtime) {
minion.getMinion().getMinionActionPack().start(action, EntityPlayerActionPack.Action.continuous()); runtime.getMinion().getMinionActionPack().start(action, EntityPlayerActionPack.Action.continuous());
} }
} }
@@ -4,22 +4,29 @@ 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.consumer.ValueConsumerList; import io.github.skippyall.minions.program.consumer.ValueConsumerList;
import io.github.skippyall.minions.program.instruction.InstructionExecution; import io.github.skippyall.minions.program.instruction.InstructionExecution;
import io.github.skippyall.minions.program.supplier.Parameter;
import io.github.skippyall.minions.program.supplier.ValueSupplierList; import io.github.skippyall.minions.program.supplier.ValueSupplierList;
import net.minecraft.component.EnchantmentEffectComponentTypes; import io.github.skippyall.minions.registration.ValueTypes;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.Slot;
import net.minecraft.screen.slot.SlotActionType; import net.minecraft.screen.slot.SlotActionType;
import net.minecraft.storage.ReadView; import net.minecraft.storage.ReadView;
import net.minecraft.storage.WriteView; import net.minecraft.storage.WriteView;
public class SwapItemExecution implements InstructionExecution<MinionRuntime> { public class SwapItemExecution implements InstructionExecution<MinionRuntime> {
public static final Parameter<Long> FROM_SLOT = new Parameter<>("from_slot", ValueTypes.LONG);
public static final Parameter<Boolean> FROM_SCREEN = new Parameter<>("from_screen", ValueTypes.BOOLEAN);
public static final Parameter<Long> TO_SLOT = new Parameter<>("to_slot", ValueTypes.LONG);
public static final Parameter<Boolean> TO_SCREEN = new Parameter<>("to_screen", ValueTypes.BOOLEAN);
private int fromSlot; private int fromSlot;
private boolean fromScreen; private boolean fromScreen;
private int toSlot; private int toSlot;
private boolean toScreen; private boolean toScreen;
private ItemStack cursor = ItemStack.EMPTY;
@Override @Override
public void start(MinionRuntime runtime) { public void start(MinionRuntime runtime) {
MinionFakePlayer minion = runtime.getMinion(); MinionFakePlayer minion = runtime.getMinion();
@@ -38,35 +45,38 @@ public class SwapItemExecution implements InstructionExecution<MinionRuntime> {
return; return;
} }
simulateClick(minion, fromSlot, fromScreen);
simulateClick(minion, toSlot, toScreen);
simulateClick(minion, fromSlot, fromScreen);
minion.getInventory().offerOrDrop(cursor);
}
private ScreenHandler getScreen(MinionFakePlayer minion, boolean screen) {
if(screen) {
return minion.currentScreenHandler;
} else {
return minion.playerScreenHandler;
}
} }
private boolean checkBounds(MinionFakePlayer minion, int slot, boolean screen) { private boolean checkBounds(MinionFakePlayer minion, int slot, boolean screen) {
if(screen) { return slot >= 0 && slot < getScreen(minion, screen).slots.size();
return slot >= 0 && slot < minion.currentScreenHandler.slots.size();
} else {
return slot >= 0 && slot <= PlayerInventory.OFF_HAND_SLOT;
}
} }
private ItemStack getStack(MinionFakePlayer minion, int slot, boolean screen) { private ItemStack getStack(MinionFakePlayer minion, int slot, boolean screen) {
if(screen) { return getScreen(minion, screen).getSlot(slot).getStack();
return minion.currentScreenHandler.getSlot(slot).getStack();
} else {
return minion.getInventory().getStack(slot);
}
} }
private boolean canExchange(MinionFakePlayer minion, int slotIndex, boolean screen, ItemStack newStack) { private boolean canExchange(MinionFakePlayer minion, int slotIndex, boolean screen, ItemStack newStack) {
if(screen) { ScreenHandler screenHandler = getScreen(minion, screen);
Slot slot = minion.currentScreenHandler.getSlot(slotIndex); Slot slot = screenHandler.getSlot(slotIndex);
if(!slot.getStack().isEmpty() && !slot.canTakeItems(minion)) { if(!slot.getStack().isEmpty() && !slot.canTakeItems(minion)) {
return false; return false;
} }
if(!newStack.isEmpty() && !slot.canInsert(newStack)) { if(!newStack.isEmpty() && !slot.canInsert(newStack)) {
return false; return false;
} }
} else { /*else {
if(slotIndex >= PlayerInventory.MAIN_SIZE && slotIndex < PlayerInventory.OFF_HAND_SLOT) { if(slotIndex >= PlayerInventory.MAIN_SIZE && slotIndex < PlayerInventory.OFF_HAND_SLOT) {
if(!minion.canEquip(newStack, PlayerInventory.EQUIPMENT_SLOTS.get(slotIndex))) { if(!minion.canEquip(newStack, PlayerInventory.EQUIPMENT_SLOTS.get(slotIndex))) {
return false; return false;
@@ -75,15 +85,17 @@ public class SwapItemExecution implements InstructionExecution<MinionRuntime> {
return false; return false;
} }
} }
} }*/
return true; return true;
} }
private void simulateClick(MinionFakePlayer minion, int slotIndex, boolean screen) { private void simulateClick(MinionFakePlayer minion, int slotIndex, boolean screen) {
if(screen) { ScreenHandler screenHandler = getScreen(minion, screen);
minion.currentScreenHandler.onSlotClick(slotIndex, 0, SlotActionType.SWAP, minion); ItemStack previousCursor = screenHandler.getCursorStack();
} else { screenHandler.setCursorStack(cursor);
} screenHandler.onSlotClick(slotIndex, 0, SlotActionType.SWAP, minion);
cursor = screenHandler.getCursorStack();
screenHandler.setCursorStack(previousCursor);
} }
@Override @Override
@@ -93,7 +105,7 @@ public class SwapItemExecution implements InstructionExecution<MinionRuntime> {
@Override @Override
public boolean isDone(MinionRuntime runtime) { public boolean isDone(MinionRuntime runtime) {
return false; return true;
} }
@Override @Override
@@ -103,7 +115,10 @@ public class SwapItemExecution implements InstructionExecution<MinionRuntime> {
@Override @Override
public void readArguments(ValueSupplierList<MinionRuntime> arguments, MinionRuntime runtime) { public void readArguments(ValueSupplierList<MinionRuntime> arguments, MinionRuntime runtime) {
fromSlot = Math.clamp(arguments.getValue(FROM_SLOT, runtime), 0, Integer.MAX_VALUE);
fromScreen = arguments.getValue(FROM_SCREEN, runtime);
toSlot = Math.clamp(arguments.getValue(TO_SLOT, runtime), 0, Integer.MAX_VALUE);
toScreen = arguments.getValue(TO_SCREEN, runtime);
} }
@Override @Override
@@ -36,11 +36,24 @@ public class MinionRuntime implements InstructionRuntime<MinionRuntime> {
} }
public void disableInstructionType(InstructionType<MinionRuntime> instructionType) { public void disableInstructionType(InstructionType<MinionRuntime> instructionType) {
updatePausedStatus(instructionType);
} }
public void enableInstructionType(InstructionType<MinionRuntime> instructionType) { public void enableInstructionType(InstructionType<MinionRuntime> instructionType) {
updatePausedStatus(instructionType);
}
public void updatePausedStatus(InstructionType<MinionRuntime> instructionType) {
for(ConfiguredInstruction<MinionRuntime> instruction : configuredInstructions.values()) {
if(instruction.getInstruction() == instructionType) {
instruction.updatePauseStatus(this);
}
}
}
@Override
public boolean isInstructionEnabled(InstructionType<MinionRuntime> type) {
return minion.getModuleInventory().hasInstruction(type);
} }
public Set<String> getInstructionNames() { public Set<String> getInstructionNames() {
@@ -13,10 +13,8 @@ import net.minecraft.storage.ReadView;
import net.minecraft.storage.WriteView; import net.minecraft.storage.WriteView;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
public class ModuleInventory extends SimpleInventory { public class ModuleInventory extends SimpleInventory {
@@ -66,6 +64,12 @@ public class ModuleInventory extends SimpleInventory {
instructions.addAll(module.instructions()); instructions.addAll(module.instructions());
specialAbilities.addAll(module.specialAbilities()); specialAbilities.addAll(module.specialAbilities());
for(InstructionType<MinionRuntime> instructionType : module.instructions()) {
if(!oldInstructions.contains(instructionType)) {
minion.getInstructionManager().enableInstructionType(instructionType);
}
}
for(SpecialAbility ability : module.specialAbilities()) { for(SpecialAbility ability : module.specialAbilities()) {
if(!oldAbilities.contains(ability)) { if(!oldAbilities.contains(ability)) {
ability.onAdd(minion); ability.onAdd(minion);
@@ -104,11 +108,11 @@ public class ModuleInventory extends SimpleInventory {
return specialAbilities.contains(ability); return specialAbilities.contains(ability);
} }
public List<InstructionType<?>> getAllInstructions() { public boolean hasInstruction(InstructionType<MinionRuntime> instructionType) {
ArrayList<InstructionType<?>> instructionTypes = new ArrayList<>(); return instructions.contains(instructionType);
for(MinionModule module : modules) {
instructionTypes.addAll(module.instructions());
} }
return instructionTypes;
public Collection<InstructionType<MinionRuntime>> getAllInstructions() {
return instructions;
} }
} }
@@ -17,6 +17,8 @@ public interface InstructionRuntime<R extends InstructionRuntime<R>> {
Registry<ValueConsumerType<R>> getValueConsumerTypeRegistry(); Registry<ValueConsumerType<R>> getValueConsumerTypeRegistry();
boolean isInstructionEnabled(InstructionType<R> type);
default Codec<ValueSupplierType<R>> getArgumentTypeCodec() { default Codec<ValueSupplierType<R>> getArgumentTypeCodec() {
return getArgumentTypeRegistry().getCodec(); return getArgumentTypeRegistry().getCodec();
} }
@@ -16,12 +16,14 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
private final ValueSupplierList<R> arguments; private final ValueSupplierList<R> arguments;
private final ValueConsumerList<R> valueConsumers; private final ValueConsumerList<R> valueConsumers;
private @Nullable InstructionExecution<R> execution; private @Nullable InstructionExecution<R> execution;
private boolean paused = false;
private SerializableListenerManager<ConfiguredInstructionListener> listeners = new SerializableListenerManager<>(MinionRegistries.INSTRUCTION_LISTENER_CODECS); private SerializableListenerManager<ConfiguredInstructionListener> listeners = new SerializableListenerManager<>(MinionRegistries.INSTRUCTION_LISTENER_CODECS);
private ConfiguredInstruction(InstructionType<R> instruction, ValueSupplierList<R> arguments, ValueConsumerList<R> valueConsumers, @Nullable InstructionExecution<R> execution, SerializableListenerManager<ConfiguredInstructionListener> listeners) { private ConfiguredInstruction(InstructionType<R> instruction, ValueSupplierList<R> arguments, ValueConsumerList<R> valueConsumers, @Nullable InstructionExecution<R> execution, SerializableListenerManager<ConfiguredInstructionListener> listeners, boolean paused) {
this(instruction, arguments, valueConsumers, execution); this(instruction, arguments, valueConsumers, execution);
this.listeners = listeners; this.listeners = listeners;
this.paused = paused;
} }
private ConfiguredInstruction(InstructionType<R> instruction, ValueSupplierList<R> arguments, ValueConsumerList<R> valueConsumers, @Nullable InstructionExecution<R> execution) { private ConfiguredInstruction(InstructionType<R> instruction, ValueSupplierList<R> arguments, ValueConsumerList<R> valueConsumers, @Nullable InstructionExecution<R> execution) {
@@ -71,7 +73,7 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
} }
public void tick(R minion) { public void tick(R minion) {
if(execution != null) { if(execution != null && !paused) {
if(execution.isDone(minion)) { if(execution.isDone(minion)) {
stop(minion); stop(minion);
} else { } else {
@@ -91,6 +93,21 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
} }
} }
public void updatePauseStatus(R runtime) {
boolean typeEnabled = runtime.isInstructionEnabled(instruction);
if(typeEnabled && paused) {
paused = false;
if(execution != null) {
execution.resume(runtime);
}
} else if(!typeEnabled && !paused) {
paused = true;
if(execution != null) {
execution.pause(runtime);
}
}
}
private void onSupplierChange(Parameter<?> parameter) { private void onSupplierChange(Parameter<?> parameter) {
listeners.forEach(listener -> listener.onSupplierChange(this, parameter)); listeners.forEach(listener -> listener.onSupplierChange(this, parameter));
} }
@@ -116,6 +133,7 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
view.put("arguments", minion.getArgumentListCodec(), arguments); view.put("arguments", minion.getArgumentListCodec(), arguments);
view.put("valueConsumers", minion.getValueConsumerListCodec(), valueConsumers); view.put("valueConsumers", minion.getValueConsumerListCodec(), valueConsumers);
view.putBoolean("running", isRunning()); view.putBoolean("running", isRunning());
view.putBoolean("paused", paused);
if(execution != null) { if(execution != null) {
execution.save(view.get("execution"), minion); execution.save(view.get("execution"), minion);
} }
@@ -130,6 +148,7 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
ValueConsumerList<R> valueConsumers = view.read("valueConsumers", minion.getValueConsumerListCodec()).orElseGet(ValueConsumerList::new); ValueConsumerList<R> valueConsumers = view.read("valueConsumers", minion.getValueConsumerListCodec()).orElseGet(ValueConsumerList::new);
boolean running = view.getBoolean("running", false); boolean running = view.getBoolean("running", false);
boolean paused = view.getBoolean("paused", false);
SerializableListenerManager<ConfiguredInstructionListener> listeners = new SerializableListenerManager<>(MinionRegistries.INSTRUCTION_LISTENER_CODECS); SerializableListenerManager<ConfiguredInstructionListener> listeners = new SerializableListenerManager<>(MinionRegistries.INSTRUCTION_LISTENER_CODECS);
listeners.load(view); listeners.load(view);
@@ -138,12 +157,12 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
ReadView executionView = view.getReadView("execution"); ReadView executionView = view.getReadView("execution");
try { try {
InstructionExecution<R> execution = instructionType.loadExecution(executionView, minion); InstructionExecution<R> execution = instructionType.loadExecution(executionView, minion);
return new ConfiguredInstruction<>(instructionType, arguments, valueConsumers, execution, listeners); return new ConfiguredInstruction<>(instructionType, arguments, valueConsumers, execution, listeners, paused);
} catch (Exception e) { } catch (Exception e) {
Minions.LOGGER.error("Error while loading execution", e); Minions.LOGGER.error("Error while loading execution", e);
} }
} }
return new ConfiguredInstruction<>(instructionType, arguments, valueConsumers, null, listeners); return new ConfiguredInstruction<>(instructionType, arguments, valueConsumers, null, listeners, paused);
} }
} }
@@ -31,6 +31,10 @@ public interface InstructionExecution<R extends InstructionRuntime<R>> {
*/ */
boolean isDone(R runtime); boolean isDone(R runtime);
default void pause(R runtime) {}
default void resume(R runtime) {}
/** /**
* Stops this execution. Is called when isDone returns true, but it may also be called before that. * Stops this execution. Is called when isDone returns true, but it may also be called before that.
* This should undo changes to the minion unless they are supposed to be permanent. * This should undo changes to the minion unless they are supposed to be permanent.
@@ -2,6 +2,7 @@ package io.github.skippyall.minions.program.supplier;
import io.github.skippyall.minions.program.InstructionRuntime; import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.value.ValueType; import io.github.skippyall.minions.program.value.ValueType;
import net.minecraft.text.Text;
/** /**
* A supplier that always resolves to a fixed value * A supplier that always resolves to a fixed value
@@ -35,4 +36,9 @@ public class FixedValueSupplier<T, R extends InstructionRuntime<R>> implements V
public FixedValueSupplierType<R> getType() { public FixedValueSupplierType<R> getType() {
return type; return type;
} }
@Override
public Text getDisplayText() {
return Text.translatable("value_supplier_type.minions.fixed.display", valueType.getDisplayText(value));
}
} }
@@ -4,6 +4,7 @@ import com.mojang.serialization.Codec;
import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.registration.MinionRegistries;
import io.github.skippyall.minions.program.InstructionRuntime; import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.value.ValueType; import io.github.skippyall.minions.program.value.ValueType;
import net.minecraft.text.Text;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
/** /**
@@ -19,6 +20,8 @@ public interface ValueSupplier<T, R extends InstructionRuntime<R>> {
ValueSupplierType<R> getType(); ValueSupplierType<R> getType();
Text getDisplayText();
default <U,A extends ValueSupplier<U,R>> @Nullable A cast(ValueType<U> type) { default <U,A extends ValueSupplier<U,R>> @Nullable A cast(ValueType<U> type) {
if(getValueType() == type) { if(getValueType() == type) {
//noinspection unchecked //noinspection unchecked
@@ -2,12 +2,18 @@ package io.github.skippyall.minions.program.value;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Function;
public record ValueType<T>(Codec<T> codec, T defaultValue, BiFunction<ServerPlayerEntity, T, CompletableFuture<T>> valueDialogOpener) { public record ValueType<T>(Codec<T> codec, T defaultValue, BiFunction<ServerPlayerEntity, T, CompletableFuture<T>> valueDialogOpener, Function<T, Text> textDisplay) {
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);
} }
public Text getDisplayText(T value) {
return textDisplay.apply(value);
}
} }
@@ -1,5 +1,6 @@
package io.github.skippyall.minions.registration; package io.github.skippyall.minions.registration;
import io.github.skippyall.minions.instruction.inventory.SwapItemExecution;
import io.github.skippyall.minions.program.instruction.InstructionExecution; import io.github.skippyall.minions.program.instruction.InstructionExecution;
import io.github.skippyall.minions.program.instruction.InstructionType; import io.github.skippyall.minions.program.instruction.InstructionType;
import io.github.skippyall.minions.Minions; import io.github.skippyall.minions.Minions;
@@ -57,6 +58,12 @@ public class Instructions {
() -> new ActionExecution(EntityPlayerActionPack.ActionType.USE) () -> new ActionExecution(EntityPlayerActionPack.ActionType.USE)
); );
public static final InstructionType<MinionRuntime> SWAP_ITEM = register(
"swap_item",
SwapItemExecution::new,
List.of(SwapItemExecution.FROM_SLOT, SwapItemExecution.FROM_SCREEN, SwapItemExecution.TO_SLOT, SwapItemExecution.TO_SCREEN)
);
private static InstructionType<MinionRuntime> register(String id, Supplier<InstructionExecution<MinionRuntime>> factory, Collection<Parameter<?>> parameters, Collection<Parameter<?>> returnParameters) { private static InstructionType<MinionRuntime> register(String id, Supplier<InstructionExecution<MinionRuntime>> factory, Collection<Parameter<?>> parameters, Collection<Parameter<?>> returnParameters) {
Identifier identifier = Identifier.of(Minions.MOD_ID, id); Identifier identifier = Identifier.of(Minions.MOD_ID, id);
return Registry.register(MinionRegistries.INSTRUCTION_TYPES, identifier, new InstructionType<>(factory, parameters, returnParameters)); return Registry.register(MinionRegistries.INSTRUCTION_TYPES, identifier, new InstructionType<>(factory, parameters, returnParameters));
@@ -13,6 +13,7 @@ import net.minecraft.util.Identifier;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction; 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 = registerSimple(
@@ -23,7 +24,8 @@ public class ValueTypes {
player, player,
Text.literal("Integer"), Text.literal("Integer"),
String.valueOf(oldValue) String.valueOf(oldValue)
) ),
value -> Text.literal(value.toString())
); );
public static ValueType<Double> DOUBLE = registerSimple( public static ValueType<Double> DOUBLE = registerSimple(
@@ -34,7 +36,16 @@ public class ValueTypes {
player, player,
Text.literal("Number"), Text.literal("Number"),
String.valueOf(oldValue) String.valueOf(oldValue)
) ),
value -> Text.literal(value.toString())
);
public static ValueType<Boolean> BOOLEAN = registerSimple(
"boolean",
Codec.BOOL,
false,
ChoiceInput.inputBoolean(Text.literal("")),
value -> Text.literal(value.toString())
); );
public static ValueType<String> STRING = registerSimple( public static ValueType<String> STRING = registerSimple(
@@ -45,17 +56,25 @@ public class ValueTypes {
player, player,
Text.literal("Text"), Text.literal("Text"),
oldValue) oldValue)
) ),
value -> Text.literal("\"" + value + "\"")
); );
public static ValueType<TurnDirection> TURN_DIRECTION = registerSimple( public static ValueType<TurnDirection> TURN_DIRECTION = registerSimple(
"turn_direction", "turn_direction",
TurnDirection.CODEC, TurnDirection.CODEC,
TurnDirection.RIGHT, TurnDirection.RIGHT,
ChoiceInput.createDialogOpener(TurnDirection.values()) ChoiceInput.createDialogOpener(TurnDirection.values()),
value -> Text.literal(value.name)
); );
private static <T> ValueType<T> registerSimple(String id, Codec<T> codec, T defaultValue, BiFunction<ServerPlayerEntity, T, CompletableFuture<T>> valueDialogOpener) { private static <T> ValueType<T> registerSimple(
String id,
Codec<T> codec,
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( return Registry.register(
MinionRegistries.VALUE_TYPES, MinionRegistries.VALUE_TYPES,
@@ -63,7 +82,8 @@ public class ValueTypes {
new ValueType<>( new ValueType<>(
codec, codec,
defaultValue, defaultValue,
valueDialogOpener valueDialogOpener,
textDisplay
) )
); );
} }
@@ -37,6 +37,7 @@
"minions.gui.instruction.argument.configure.type": "Type: %s", "minions.gui.instruction.argument.configure.type": "Type: %s",
"minions.gui.instruction.argument.configure.type.unset": "Unset", "minions.gui.instruction.argument.configure.type.unset": "Unset",
"minions.gui.instruction.parameter": "%s: %s", "minions.gui.instruction.parameter": "%s: %s",
"minions.gui.instruction.argument": "Argument: %s",
"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",
@@ -70,6 +71,7 @@
"value_type.minions.turn_direction": "Turn Direction", "value_type.minions.turn_direction": "Turn Direction",
"value_supplier_type.minions.fixed": "Value", "value_supplier_type.minions.fixed": "Value",
"value_supplier_type.minions.fixed.display": "Fixed Value: %s",
"item.minions.attack_module": "Attack Module", "item.minions.attack_module": "Attack Module",
"item.minions.interact_module": "Interact Module", "item.minions.interact_module": "Interact Module",