diff --git a/src/main/java/io/github/skippyall/minions/block/miniontrigger/MinionTriggerBlock.java b/src/main/java/io/github/skippyall/minions/block/miniontrigger/MinionTriggerBlock.java index 5ce9f6f..d815a9a 100644 --- a/src/main/java/io/github/skippyall/minions/block/miniontrigger/MinionTriggerBlock.java +++ b/src/main/java/io/github/skippyall/minions/block/miniontrigger/MinionTriggerBlock.java @@ -26,6 +26,7 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.server.network.ServerPlayNetworkHandler; +import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.SoundCategory; 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)); } + @Override + public boolean handleMiningOnServer(ItemStack tool, BlockState state, BlockPos pos, ServerPlayerEntity player) { + return false; + } + @Override public @Nullable ElementHolder createElementHolder(ServerWorld world, BlockPos pos, BlockState initialBlockState) { ElementHolder holder = new ElementHolder() { diff --git a/src/main/java/io/github/skippyall/minions/gui/ConfigureInstructionGui.java b/src/main/java/io/github/skippyall/minions/gui/ConfigureInstructionGui.java index d6b94e1..79aef56 100644 --- a/src/main/java/io/github/skippyall/minions/gui/ConfigureInstructionGui.java +++ b/src/main/java/io/github/skippyall/minions/gui/ConfigureInstructionGui.java @@ -105,9 +105,9 @@ public class ConfigureInstructionGui extends InstructionBoundSimpleGui { } private void updateSuppliers() { - int slot = 11; + int slot = 12; 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)) ); slot--; diff --git a/src/main/java/io/github/skippyall/minions/gui/InstructionGui.java b/src/main/java/io/github/skippyall/minions/gui/InstructionGui.java index 34b3f79..d94da2f 100644 --- a/src/main/java/io/github/skippyall/minions/gui/InstructionGui.java +++ b/src/main/java/io/github/skippyall/minions/gui/InstructionGui.java @@ -221,19 +221,12 @@ public class InstructionGui { return instructionBuilder; } - public static GuiElementBuilder createParameterElement(Parameter parameter, DynamicRegistryManager manager) { - return new GuiElementBuilder(GuiDisplay.getDisplayStack(MinionRegistries.VALUE_TYPES, parameter.type(), manager)) + public static GuiElementBuilder createParameterElement(Parameter parameter, @Nullable ValueSupplier valueSupplier, DynamicRegistryManager 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)))); - } - - public static GuiElementBuilder createArgumentElement(ValueSupplier 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")); + if(valueSupplier != null) { + builder.addLoreLine(Text.translatable("minions.gui.instruction.argument", valueSupplier.getDisplayText())); } - return argumentBuilder; + return builder; } } \ No newline at end of file diff --git a/src/main/java/io/github/skippyall/minions/gui/input/ChoiceInput.java b/src/main/java/io/github/skippyall/minions/gui/input/ChoiceInput.java index 994cec4..0e6ba7d 100644 --- a/src/main/java/io/github/skippyall/minions/gui/input/ChoiceInput.java +++ b/src/main/java/io/github/skippyall/minions/gui/input/ChoiceInput.java @@ -71,4 +71,14 @@ public class ChoiceInput { gui.open(); return future; } + + public static BiFunction> 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); + } } diff --git a/src/main/java/io/github/skippyall/minions/instruction/ActionExecution.java b/src/main/java/io/github/skippyall/minions/instruction/ActionExecution.java index fe03bd3..2363df7 100644 --- a/src/main/java/io/github/skippyall/minions/instruction/ActionExecution.java +++ b/src/main/java/io/github/skippyall/minions/instruction/ActionExecution.java @@ -28,6 +28,16 @@ public class ActionExecution implements ContinuousInstructionExecution parameters, MinionRuntime minion) {} @@ -35,7 +45,7 @@ public class ActionExecution implements ContinuousInstructionExecution { + public static final Parameter FROM_SLOT = new Parameter<>("from_slot", ValueTypes.LONG); + public static final Parameter FROM_SCREEN = new Parameter<>("from_screen", ValueTypes.BOOLEAN); + public static final Parameter TO_SLOT = new Parameter<>("to_slot", ValueTypes.LONG); + public static final Parameter TO_SCREEN = new Parameter<>("to_screen", ValueTypes.BOOLEAN); + private int fromSlot; private boolean fromScreen; private int toSlot; private boolean toScreen; + private ItemStack cursor = ItemStack.EMPTY; + @Override public void start(MinionRuntime runtime) { MinionFakePlayer minion = runtime.getMinion(); @@ -38,35 +45,38 @@ public class SwapItemExecution implements InstructionExecution { 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) { - if(screen) { - return slot >= 0 && slot < minion.currentScreenHandler.slots.size(); - } else { - return slot >= 0 && slot <= PlayerInventory.OFF_HAND_SLOT; - } + return slot >= 0 && slot < getScreen(minion, screen).slots.size(); } private ItemStack getStack(MinionFakePlayer minion, int slot, boolean screen) { - if(screen) { - return minion.currentScreenHandler.getSlot(slot).getStack(); - } else { - return minion.getInventory().getStack(slot); - } + return getScreen(minion, screen).getSlot(slot).getStack(); } private boolean canExchange(MinionFakePlayer minion, int slotIndex, boolean screen, ItemStack newStack) { - if(screen) { - Slot slot = minion.currentScreenHandler.getSlot(slotIndex); - if(!slot.getStack().isEmpty() && !slot.canTakeItems(minion)) { - return false; - } - if(!newStack.isEmpty() && !slot.canInsert(newStack)) { - return false; - } - } else { + ScreenHandler screenHandler = getScreen(minion, screen); + Slot slot = screenHandler.getSlot(slotIndex); + if(!slot.getStack().isEmpty() && !slot.canTakeItems(minion)) { + return false; + } + if(!newStack.isEmpty() && !slot.canInsert(newStack)) { + return false; + } + /*else { if(slotIndex >= PlayerInventory.MAIN_SIZE && slotIndex < PlayerInventory.OFF_HAND_SLOT) { if(!minion.canEquip(newStack, PlayerInventory.EQUIPMENT_SLOTS.get(slotIndex))) { return false; @@ -75,15 +85,17 @@ public class SwapItemExecution implements InstructionExecution { return false; } } - } + }*/ return true; } private void simulateClick(MinionFakePlayer minion, int slotIndex, boolean screen) { - if(screen) { - minion.currentScreenHandler.onSlotClick(slotIndex, 0, SlotActionType.SWAP, minion); - } else { - } + ScreenHandler screenHandler = getScreen(minion, screen); + ItemStack previousCursor = screenHandler.getCursorStack(); + screenHandler.setCursorStack(cursor); + screenHandler.onSlotClick(slotIndex, 0, SlotActionType.SWAP, minion); + cursor = screenHandler.getCursorStack(); + screenHandler.setCursorStack(previousCursor); } @Override @@ -93,7 +105,7 @@ public class SwapItemExecution implements InstructionExecution { @Override public boolean isDone(MinionRuntime runtime) { - return false; + return true; } @Override @@ -103,7 +115,10 @@ public class SwapItemExecution implements InstructionExecution { @Override public void readArguments(ValueSupplierList 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 diff --git a/src/main/java/io/github/skippyall/minions/minion/MinionRuntime.java b/src/main/java/io/github/skippyall/minions/minion/MinionRuntime.java index 80971eb..70ed434 100644 --- a/src/main/java/io/github/skippyall/minions/minion/MinionRuntime.java +++ b/src/main/java/io/github/skippyall/minions/minion/MinionRuntime.java @@ -36,11 +36,24 @@ public class MinionRuntime implements InstructionRuntime { } public void disableInstructionType(InstructionType instructionType) { - + updatePausedStatus(instructionType); } public void enableInstructionType(InstructionType instructionType) { + updatePausedStatus(instructionType); + } + public void updatePausedStatus(InstructionType instructionType) { + for(ConfiguredInstruction instruction : configuredInstructions.values()) { + if(instruction.getInstruction() == instructionType) { + instruction.updatePauseStatus(this); + } + } + } + + @Override + public boolean isInstructionEnabled(InstructionType type) { + return minion.getModuleInventory().hasInstruction(type); } public Set getInstructionNames() { diff --git a/src/main/java/io/github/skippyall/minions/module/ModuleInventory.java b/src/main/java/io/github/skippyall/minions/module/ModuleInventory.java index fcf7b3c..06fd87c 100644 --- a/src/main/java/io/github/skippyall/minions/module/ModuleInventory.java +++ b/src/main/java/io/github/skippyall/minions/module/ModuleInventory.java @@ -13,10 +13,8 @@ import net.minecraft.storage.ReadView; import net.minecraft.storage.WriteView; import net.minecraft.text.Text; -import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; -import java.util.List; import java.util.Set; public class ModuleInventory extends SimpleInventory { @@ -66,6 +64,12 @@ public class ModuleInventory extends SimpleInventory { instructions.addAll(module.instructions()); specialAbilities.addAll(module.specialAbilities()); + for(InstructionType instructionType : module.instructions()) { + if(!oldInstructions.contains(instructionType)) { + minion.getInstructionManager().enableInstructionType(instructionType); + } + } + for(SpecialAbility ability : module.specialAbilities()) { if(!oldAbilities.contains(ability)) { ability.onAdd(minion); @@ -104,11 +108,11 @@ public class ModuleInventory extends SimpleInventory { return specialAbilities.contains(ability); } - public List> getAllInstructions() { - ArrayList> instructionTypes = new ArrayList<>(); - for(MinionModule module : modules) { - instructionTypes.addAll(module.instructions()); - } - return instructionTypes; + public boolean hasInstruction(InstructionType instructionType) { + return instructions.contains(instructionType); + } + + public Collection> getAllInstructions() { + return instructions; } } diff --git a/src/main/java/io/github/skippyall/minions/program/InstructionRuntime.java b/src/main/java/io/github/skippyall/minions/program/InstructionRuntime.java index 24f9a63..6765707 100644 --- a/src/main/java/io/github/skippyall/minions/program/InstructionRuntime.java +++ b/src/main/java/io/github/skippyall/minions/program/InstructionRuntime.java @@ -17,6 +17,8 @@ public interface InstructionRuntime> { Registry> getValueConsumerTypeRegistry(); + boolean isInstructionEnabled(InstructionType type); + default Codec> getArgumentTypeCodec() { return getArgumentTypeRegistry().getCodec(); } diff --git a/src/main/java/io/github/skippyall/minions/program/instruction/ConfiguredInstruction.java b/src/main/java/io/github/skippyall/minions/program/instruction/ConfiguredInstruction.java index 0e16e83..dd33b30 100644 --- a/src/main/java/io/github/skippyall/minions/program/instruction/ConfiguredInstruction.java +++ b/src/main/java/io/github/skippyall/minions/program/instruction/ConfiguredInstruction.java @@ -16,12 +16,14 @@ public class ConfiguredInstruction> { private final ValueSupplierList arguments; private final ValueConsumerList valueConsumers; private @Nullable InstructionExecution execution; + private boolean paused = false; private SerializableListenerManager listeners = new SerializableListenerManager<>(MinionRegistries.INSTRUCTION_LISTENER_CODECS); - private ConfiguredInstruction(InstructionType instruction, ValueSupplierList arguments, ValueConsumerList valueConsumers, @Nullable InstructionExecution execution, SerializableListenerManager listeners) { + private ConfiguredInstruction(InstructionType instruction, ValueSupplierList arguments, ValueConsumerList valueConsumers, @Nullable InstructionExecution execution, SerializableListenerManager listeners, boolean paused) { this(instruction, arguments, valueConsumers, execution); this.listeners = listeners; + this.paused = paused; } private ConfiguredInstruction(InstructionType instruction, ValueSupplierList arguments, ValueConsumerList valueConsumers, @Nullable InstructionExecution execution) { @@ -71,7 +73,7 @@ public class ConfiguredInstruction> { } public void tick(R minion) { - if(execution != null) { + if(execution != null && !paused) { if(execution.isDone(minion)) { stop(minion); } else { @@ -91,6 +93,21 @@ public class ConfiguredInstruction> { } } + 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) { listeners.forEach(listener -> listener.onSupplierChange(this, parameter)); } @@ -116,6 +133,7 @@ public class ConfiguredInstruction> { view.put("arguments", minion.getArgumentListCodec(), arguments); view.put("valueConsumers", minion.getValueConsumerListCodec(), valueConsumers); view.putBoolean("running", isRunning()); + view.putBoolean("paused", paused); if(execution != null) { execution.save(view.get("execution"), minion); } @@ -130,6 +148,7 @@ public class ConfiguredInstruction> { ValueConsumerList valueConsumers = view.read("valueConsumers", minion.getValueConsumerListCodec()).orElseGet(ValueConsumerList::new); boolean running = view.getBoolean("running", false); + boolean paused = view.getBoolean("paused", false); SerializableListenerManager listeners = new SerializableListenerManager<>(MinionRegistries.INSTRUCTION_LISTENER_CODECS); listeners.load(view); @@ -138,12 +157,12 @@ public class ConfiguredInstruction> { ReadView executionView = view.getReadView("execution"); try { InstructionExecution 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) { 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); } } diff --git a/src/main/java/io/github/skippyall/minions/program/instruction/InstructionExecution.java b/src/main/java/io/github/skippyall/minions/program/instruction/InstructionExecution.java index 5d6b567..c3ee90e 100644 --- a/src/main/java/io/github/skippyall/minions/program/instruction/InstructionExecution.java +++ b/src/main/java/io/github/skippyall/minions/program/instruction/InstructionExecution.java @@ -31,6 +31,10 @@ public interface InstructionExecution> { */ 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. * This should undo changes to the minion unless they are supposed to be permanent. diff --git a/src/main/java/io/github/skippyall/minions/program/supplier/FixedValueSupplier.java b/src/main/java/io/github/skippyall/minions/program/supplier/FixedValueSupplier.java index 9940a84..f827c6d 100644 --- a/src/main/java/io/github/skippyall/minions/program/supplier/FixedValueSupplier.java +++ b/src/main/java/io/github/skippyall/minions/program/supplier/FixedValueSupplier.java @@ -2,6 +2,7 @@ package io.github.skippyall.minions.program.supplier; import io.github.skippyall.minions.program.InstructionRuntime; import io.github.skippyall.minions.program.value.ValueType; +import net.minecraft.text.Text; /** * A supplier that always resolves to a fixed value @@ -35,4 +36,9 @@ public class FixedValueSupplier> implements V public FixedValueSupplierType getType() { return type; } + + @Override + public Text getDisplayText() { + return Text.translatable("value_supplier_type.minions.fixed.display", valueType.getDisplayText(value)); + } } diff --git a/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplier.java b/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplier.java index 4d7a77a..cad224c 100644 --- a/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplier.java +++ b/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplier.java @@ -4,6 +4,7 @@ import com.mojang.serialization.Codec; import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.program.InstructionRuntime; import io.github.skippyall.minions.program.value.ValueType; +import net.minecraft.text.Text; import org.jetbrains.annotations.Nullable; /** @@ -19,6 +20,8 @@ public interface ValueSupplier> { ValueSupplierType getType(); + Text getDisplayText(); + default > @Nullable A cast(ValueType type) { if(getValueType() == type) { //noinspection unchecked diff --git a/src/main/java/io/github/skippyall/minions/program/value/ValueType.java b/src/main/java/io/github/skippyall/minions/program/value/ValueType.java index d8e6cc8..6ae41e2 100644 --- a/src/main/java/io/github/skippyall/minions/program/value/ValueType.java +++ b/src/main/java/io/github/skippyall/minions/program/value/ValueType.java @@ -2,12 +2,18 @@ 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; import java.util.function.BiFunction; +import java.util.function.Function; -public record ValueType(Codec codec, T defaultValue, BiFunction> valueDialogOpener) { +public record ValueType(Codec codec, T defaultValue, BiFunction> valueDialogOpener, Function textDisplay) { public CompletableFuture openValueDialog(ServerPlayerEntity player, T previousValue) { return valueDialogOpener.apply(player, previousValue); } + + public Text getDisplayText(T value) { + return textDisplay.apply(value); + } } diff --git a/src/main/java/io/github/skippyall/minions/registration/Instructions.java b/src/main/java/io/github/skippyall/minions/registration/Instructions.java index 509dd2c..bb114d8 100644 --- a/src/main/java/io/github/skippyall/minions/registration/Instructions.java +++ b/src/main/java/io/github/skippyall/minions/registration/Instructions.java @@ -1,5 +1,6 @@ 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.InstructionType; import io.github.skippyall.minions.Minions; @@ -57,6 +58,12 @@ public class Instructions { () -> new ActionExecution(EntityPlayerActionPack.ActionType.USE) ); + public static final InstructionType SWAP_ITEM = register( + "swap_item", + SwapItemExecution::new, + List.of(SwapItemExecution.FROM_SLOT, SwapItemExecution.FROM_SCREEN, SwapItemExecution.TO_SLOT, SwapItemExecution.TO_SCREEN) + ); + private static InstructionType register(String id, Supplier> factory, Collection> parameters, Collection> returnParameters) { Identifier identifier = Identifier.of(Minions.MOD_ID, id); return Registry.register(MinionRegistries.INSTRUCTION_TYPES, identifier, new InstructionType<>(factory, parameters, returnParameters)); diff --git a/src/main/java/io/github/skippyall/minions/registration/ValueTypes.java b/src/main/java/io/github/skippyall/minions/registration/ValueTypes.java index 524c981..8e8fb34 100644 --- a/src/main/java/io/github/skippyall/minions/registration/ValueTypes.java +++ b/src/main/java/io/github/skippyall/minions/registration/ValueTypes.java @@ -13,6 +13,7 @@ import net.minecraft.util.Identifier; import java.util.concurrent.CompletableFuture; import java.util.function.BiFunction; +import java.util.function.Function; public class ValueTypes { public static ValueType LONG = registerSimple( @@ -23,7 +24,8 @@ public class ValueTypes { player, Text.literal("Integer"), String.valueOf(oldValue) - ) + ), + value -> Text.literal(value.toString()) ); public static ValueType DOUBLE = registerSimple( @@ -34,7 +36,16 @@ public class ValueTypes { player, Text.literal("Number"), String.valueOf(oldValue) - ) + ), + value -> Text.literal(value.toString()) + ); + + public static ValueType BOOLEAN = registerSimple( + "boolean", + Codec.BOOL, + false, + ChoiceInput.inputBoolean(Text.literal("")), + value -> Text.literal(value.toString()) ); public static ValueType STRING = registerSimple( @@ -45,17 +56,25 @@ public class ValueTypes { player, Text.literal("Text"), oldValue) - ) + ), + value -> Text.literal("\"" + value + "\"") ); public static ValueType TURN_DIRECTION = registerSimple( "turn_direction", TurnDirection.CODEC, TurnDirection.RIGHT, - ChoiceInput.createDialogOpener(TurnDirection.values()) + ChoiceInput.createDialogOpener(TurnDirection.values()), + value -> Text.literal(value.name) ); - private static ValueType registerSimple(String id, Codec codec, T defaultValue, BiFunction> valueDialogOpener) { + private static ValueType registerSimple( + String id, + Codec codec, + T defaultValue, + BiFunction> valueDialogOpener, + Function textDisplay + ) { Identifier identifier = Identifier.of(Minions.MOD_ID, id); return Registry.register( MinionRegistries.VALUE_TYPES, @@ -63,7 +82,8 @@ public class ValueTypes { new ValueType<>( codec, defaultValue, - valueDialogOpener + valueDialogOpener, + textDisplay ) ); } diff --git a/src/main/resources/data/minions/lang/en_us.json b/src/main/resources/data/minions/lang/en_us.json index ff13896..80aa310 100644 --- a/src/main/resources/data/minions/lang/en_us.json +++ b/src/main/resources/data/minions/lang/en_us.json @@ -37,6 +37,7 @@ "minions.gui.instruction.argument.configure.type": "Type: %s", "minions.gui.instruction.argument.configure.type.unset": "Unset", "minions.gui.instruction.parameter": "%s: %s", + "minions.gui.instruction.argument": "Argument: %s", "minions.command.input.int.fail": "Not an integer", "minions.command.input.float.fail": "Not a number", @@ -70,6 +71,7 @@ "value_type.minions.turn_direction": "Turn Direction", "value_supplier_type.minions.fixed": "Value", + "value_supplier_type.minions.fixed.display": "Fixed Value: %s", "item.minions.attack_module": "Attack Module", "item.minions.interact_module": "Interact Module",