MinionTriggerBlock & More GUI
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
package io.github.skippyall.minions;
|
||||
|
||||
import net.fabricmc.fabric.api.attachment.v1.AttachmentRegistry;
|
||||
import net.fabricmc.fabric.api.attachment.v1.AttachmentType;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public record PlayerClipboardAttachment(UUID selectedMinion, String selectedInstruction) {
|
||||
public static final AttachmentType<PlayerClipboardAttachment> TYPE = AttachmentRegistry.create(Identifier.of(Minions.MOD_ID, "clipboard"));
|
||||
}
|
||||
@@ -3,32 +3,58 @@ package io.github.skippyall.minions.block;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import eu.pb4.polymer.core.api.block.PolymerBlock;
|
||||
import io.github.skippyall.minions.MinionRegistration;
|
||||
import io.github.skippyall.minions.PlayerClipboardAttachment;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.BlockWithEntity;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.block.entity.BlockEntityTicker;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.state.property.BooleanProperty;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.block.WireOrientation;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import xyz.nucleoid.packettweaker.PacketContext;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class MinionTriggerBlock extends BlockWithEntity implements PolymerBlock {
|
||||
public static final MapCodec<MinionTriggerBlock> CODEC = createCodec(MinionTriggerBlock::new);
|
||||
|
||||
public static final BooleanProperty POWERED = BooleanProperty.of("powered");
|
||||
public static final BooleanProperty RUNNING = BooleanProperty.of("running");
|
||||
|
||||
public MinionTriggerBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState().with(POWERED, false));
|
||||
setDefaultState(getDefaultState().with(POWERED, false).with(RUNNING, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
builder.add(POWERED);
|
||||
builder.add(POWERED, RUNNING);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) {
|
||||
PlayerClipboardAttachment clipboard = player.getAttached(PlayerClipboardAttachment.TYPE);
|
||||
if(clipboard != null) {
|
||||
Optional<MinionTriggerBlockEntity> be = world.getBlockEntity(pos, MinionRegistration.MINION_TRIGGER_BE_TYPE);
|
||||
if(be.isPresent()) {
|
||||
be.get().setInstruction(clipboard.selectedMinion(), clipboard.selectedInstruction());
|
||||
player.playSoundToPlayer(SoundEvents.BLOCK_NOTE_BLOCK_CHIME.value(), SoundCategory.BLOCKS, 1, 1);
|
||||
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,4 +90,13 @@ public class MinionTriggerBlock extends BlockWithEntity implements PolymerBlock
|
||||
public BlockState getPolymerBlockState(BlockState state, PacketContext context) {
|
||||
return state.get(POWERED) ? Blocks.REDSTONE_BLOCK.getDefaultState() : Blocks.GOLD_BLOCK.getDefaultState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) {
|
||||
if(type == MinionRegistration.MINION_TRIGGER_BE_TYPE) {
|
||||
return MinionTriggerBlockEntity::tick;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,62 +10,80 @@ import net.minecraft.storage.ReadView;
|
||||
import net.minecraft.storage.WriteView;
|
||||
import net.minecraft.util.Uuids;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MinionTriggerBlockEntity extends BlockEntity {
|
||||
private UUID minionUuid;
|
||||
private String instructionName = "";
|
||||
|
||||
private boolean first = true;
|
||||
private boolean runningCache = false;
|
||||
|
||||
public MinionTriggerBlockEntity(BlockPos pos, BlockState state) {
|
||||
super(MinionRegistration.MINION_TRIGGER_BE_TYPE, pos, state);
|
||||
}
|
||||
|
||||
public void updatePower() {
|
||||
boolean powered = getCachedState().get(MinionTriggerBlock.POWERED);
|
||||
ConfiguredInstruction<MinionRuntime> instruction = getInstruction();
|
||||
public void setInstruction(UUID minionUuid, String instructionName) {
|
||||
this.minionUuid = minionUuid;
|
||||
this.instructionName = instructionName;
|
||||
markDirty();
|
||||
}
|
||||
|
||||
if(instruction != null) {
|
||||
if(powered) {
|
||||
instruction.run(getMinion().getInstructionManager());
|
||||
} else {
|
||||
instruction.stop(getMinion().getInstructionManager());
|
||||
public static void tick(World world, BlockPos pos, BlockState state, BlockEntity blockEntity) {
|
||||
if(!(blockEntity instanceof MinionTriggerBlockEntity triggerBlockEntity)) {
|
||||
return;
|
||||
}
|
||||
if(triggerBlockEntity.first) {
|
||||
triggerBlockEntity.first = false;
|
||||
world.updateComparators(pos, MinionRegistration.MINION_TRIGGER_BLOCK);
|
||||
triggerBlockEntity.runningCache = triggerBlockEntity.getInstruction().map(ConfiguredInstruction::isRunning).orElse(false);
|
||||
} else {
|
||||
boolean isRunning = triggerBlockEntity.getInstruction().map(ConfiguredInstruction::isRunning).orElse(false);
|
||||
if (isRunning != triggerBlockEntity.runningCache) {
|
||||
world.updateComparators(pos, MinionRegistration.MINION_TRIGGER_BLOCK);
|
||||
triggerBlockEntity.runningCache = isRunning;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updatePower() {
|
||||
boolean powered = getCachedState().get(MinionTriggerBlock.POWERED);
|
||||
getMinion().ifPresent(minion -> {
|
||||
getInstruction().ifPresent(instruction -> {
|
||||
if(powered) {
|
||||
instruction.run(minion.getInstructionManager());
|
||||
} else {
|
||||
instruction.stop(minion.getInstructionManager());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public int getComparatorOutput() {
|
||||
ConfiguredInstruction<MinionRuntime> instruction = getInstruction();
|
||||
if(instruction != null && instruction.isRunning()) {
|
||||
Optional<ConfiguredInstruction<MinionRuntime>> instruction = getInstruction();
|
||||
if(instruction.isPresent() && instruction.get().isRunning()) {
|
||||
return 15;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public MinionFakePlayer getMinion() {
|
||||
public Optional<MinionFakePlayer> getMinion() {
|
||||
if(minionUuid != null && world != null && world.getPlayerByUuid(minionUuid) instanceof MinionFakePlayer minion) {
|
||||
return minion;
|
||||
return Optional.of(minion);
|
||||
}
|
||||
return null;
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public ConfiguredInstruction<MinionRuntime> getInstruction() {
|
||||
MinionFakePlayer minion = getMinion();
|
||||
if(minion == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return minion.getInstructionManager().getInstruction(instructionName);
|
||||
public Optional<ConfiguredInstruction<MinionRuntime>> getInstruction(MinionFakePlayer minion) {
|
||||
return Optional.ofNullable(minion.getInstructionManager().getInstruction(instructionName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockReplaced(BlockPos pos, BlockState oldState) {
|
||||
super.onBlockReplaced(pos, oldState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markRemoved() {
|
||||
super.markRemoved();
|
||||
public Optional<ConfiguredInstruction<MinionRuntime>> getInstruction() {
|
||||
return getMinion().flatMap(this::getInstruction);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
package io.github.skippyall.minions.gui;
|
||||
|
||||
public class CommandsGui {
|
||||
/*public static void openServerModuleCommandGui(ServerPlayerEntity player, MinionFakePlayer minion) {
|
||||
Collection<ModuleItem> modules = minion.getModuleInventory().getModules();
|
||||
|
||||
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_9X3, player, false);
|
||||
|
||||
gui.setTitle(Text.translatable("minions.gui.module_commands.title"));
|
||||
|
||||
for (ModuleItem module : modules) {
|
||||
gui.addSlot(new GuiElementBuilder()
|
||||
.setItem(module.asItem())
|
||||
.setCallback(() -> openServerCommandGui(player, minion, module))
|
||||
);
|
||||
}
|
||||
|
||||
gui.open();
|
||||
}
|
||||
|
||||
public static void openServerCommandGui(ServerPlayerEntity player, MinionFakePlayer minion, ModuleItem module) {
|
||||
List<Command> commands = module.getCommands();
|
||||
|
||||
SimpleGui commandGui = new SimpleGui(ScreenHandlerType.GENERIC_9X3, player, false);
|
||||
|
||||
commandGui.setTitle(Text.translatable("minions.gui.commands.title", module.asItem().getName()));
|
||||
|
||||
for(int j = 0; j < commands.size(); j++) {
|
||||
Command command = commands.get(j);
|
||||
commandGui.setSlot(j, new GuiElementBuilder()
|
||||
.setItem(command.getItemRepresentation())
|
||||
.setName(command.getName())
|
||||
.addLoreLine(command.getDescription())
|
||||
.setCallback(() -> command.execute(player, minion))
|
||||
);
|
||||
}
|
||||
|
||||
commandGui.open();
|
||||
}*/
|
||||
}
|
||||
@@ -1,11 +1,8 @@
|
||||
package io.github.skippyall.minions.gui;
|
||||
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||
import io.github.skippyall.minions.util.ModelIdUtil;
|
||||
import net.minecraft.block.SkullBlock;
|
||||
import net.minecraft.block.entity.SkullBlockEntity;
|
||||
import net.minecraft.component.DataComponentTypes;
|
||||
import net.minecraft.component.type.LoreComponent;
|
||||
import net.minecraft.component.type.ProfileComponent;
|
||||
@@ -30,6 +27,10 @@ public interface GuiDisplay {
|
||||
this(ModelIdUtil.getItemModelId(model), translationKeyBase, withLore);
|
||||
}
|
||||
|
||||
public ModelBased(Item model, String translationKeyBase) {
|
||||
this(ModelIdUtil.getItemModelId(model), translationKeyBase, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack createItemStack() {
|
||||
ItemStack stack = new ItemStack(Items.BARRIER);
|
||||
|
||||
@@ -3,7 +3,10 @@ package io.github.skippyall.minions.gui;
|
||||
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||
import eu.pb4.sgui.api.gui.SimpleGui;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.input.TextInput;
|
||||
import io.github.skippyall.minions.PlayerClipboardAttachment;
|
||||
import io.github.skippyall.minions.gui.input.ChoiceInput;
|
||||
import io.github.skippyall.minions.gui.input.Result;
|
||||
import io.github.skippyall.minions.gui.input.TextInput;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.module.MinionModule;
|
||||
@@ -17,7 +20,10 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.text.Text;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
@@ -28,12 +34,12 @@ public class InstructionGui {
|
||||
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_3X3, player, false);
|
||||
gui.setSlot(3, new GuiElementBuilder()
|
||||
.setItem(Items.BOOK)
|
||||
.setName(Text.literal("Instruction List"))
|
||||
.setName(Text.translatable("minions.gui.instruction.list"))
|
||||
.setCallback(() -> instructionList(minion, player))
|
||||
);
|
||||
gui.setSlot(5, new GuiElementBuilder()
|
||||
.setItem(Items.WRITABLE_BOOK)
|
||||
.setName(Text.literal("New Instruction"))
|
||||
.setName(Text.translatable("minions.gui.instruction.create"))
|
||||
.setCallback(() -> createNewInstruction(minion, player))
|
||||
);
|
||||
|
||||
@@ -55,13 +61,22 @@ public class InstructionGui {
|
||||
|
||||
public static void createNewInstruction(MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||
selectInstructionModuleMenu(minion, player).thenAccept(instructionType ->
|
||||
TextInput.inputString(player, Text.translatable("minions.gui.instruction.enter_name"), "Instruction").thenAccept(name -> {
|
||||
inputInstructionName(minion, player, "Instruction").thenAccept(name -> {
|
||||
ConfiguredInstruction<MinionRuntime> configuredInstruction = minion.getInstructionManager().createInstruction(name, instructionType);
|
||||
configureInstructionMenu(name, configuredInstruction, minion, player);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public static CompletableFuture<String> inputInstructionName(MinionFakePlayer minion, ServerPlayerEntity player, String defaultValue) {
|
||||
return TextInput.inputSync(player, Text.translatable("minions.gui.instruction.enter_name"), defaultValue, name -> {
|
||||
if(minion.getInstructionManager().hasInstruction(name)) {
|
||||
return new Result.Error<>(Text.translatable("minions.gui.instruction.name_already_used"));
|
||||
}
|
||||
return new Result.Success<>(name);
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean checkInstructionExists(String name, ConfiguredInstruction<?> instruction, MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||
boolean stillExists = minion.getInstructionManager().getInstruction(name) == instruction;
|
||||
if(!stillExists) {
|
||||
@@ -77,16 +92,44 @@ public class InstructionGui {
|
||||
}
|
||||
|
||||
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_9X3, player, false);
|
||||
gui.setTitle(Text.literal(name));
|
||||
|
||||
gui.setSlot(12, createInstructionElement(instruction.getInstruction()));
|
||||
gui.setSlot(7, new GuiElementBuilder(Items.ANVIL)
|
||||
.setName(Text.translatable("minions.gui.instruction.configure.rename"))
|
||||
.setCallback(() -> inputInstructionName(minion, player, name).thenAccept(newName -> {
|
||||
minion.getInstructionManager().setInstructionName(name, newName);
|
||||
configureInstructionMenu(newName, instruction, minion, player);
|
||||
}))
|
||||
);
|
||||
|
||||
int slot = 13;
|
||||
gui.setSlot(8, new GuiElementBuilder(Items.LAVA_BUCKET)
|
||||
.setName(Text.translatable("minions.gui.instruction.configure.delete"))
|
||||
.setCallback(() -> ChoiceInput.confirm(player, Text.translatable("minions.gui.instruction.configure.delete.confirm", name))
|
||||
.thenAccept(v -> {
|
||||
minion.getInstructionManager().removeInstruction(name);
|
||||
instructionList(minion, player);
|
||||
}))
|
||||
);
|
||||
|
||||
gui.setSlot(13, createInstructionElement(instruction.getInstruction()));
|
||||
|
||||
int slot = 14;
|
||||
for(Parameter<?> parameter : instruction.getInstruction().getParameters()) {
|
||||
gui.setSlot(slot, createArgumentElement(instruction.getArguments().getArgument(parameter))
|
||||
.setCallback(() -> configureArgumentMenu(name, instruction, parameter, minion, player))
|
||||
);
|
||||
slot++;
|
||||
}
|
||||
|
||||
gui.setSlot(25, new GuiElementBuilder(Items.FEATHER)
|
||||
.setName(Text.translatable("minions.gui.instruction.configure.copy"))
|
||||
.addLoreLine(Text.translatable("minions.gui.instruction.configure.copy.description"))
|
||||
.setCallback(() -> {
|
||||
player.setAttached(PlayerClipboardAttachment.TYPE, new PlayerClipboardAttachment(minion.getUuid(), name));
|
||||
player.playSoundToPlayer(SoundEvents.BLOCK_NOTE_BLOCK_CHIME.value(), SoundCategory.BLOCKS, 1, 1);
|
||||
})
|
||||
);
|
||||
|
||||
updateRunSlot(instruction, minion, gui);
|
||||
|
||||
gui.open();
|
||||
@@ -95,7 +138,7 @@ public class InstructionGui {
|
||||
private static void updateRunSlot(ConfiguredInstruction<MinionRuntime> instruction, MinionFakePlayer minion, SimpleGui gui) {
|
||||
if(!instruction.isRunning()) {
|
||||
gui.setSlot(26, new GuiElementBuilder(Items.ARROW)
|
||||
.setName(Text.literal("Run"))
|
||||
.setName(Text.translatable("minions.gui.instruction.run"))
|
||||
.setCallback(() -> {
|
||||
instruction.run(minion.getInstructionManager());
|
||||
updateRunSlot(instruction, minion, gui);
|
||||
@@ -103,7 +146,7 @@ public class InstructionGui {
|
||||
);
|
||||
} else {
|
||||
gui.setSlot(26, new GuiElementBuilder(Items.BARRIER)
|
||||
.setName(Text.literal("Stop"))
|
||||
.setName(Text.translatable("minions.gui.instruction.stop"))
|
||||
.setCallback(() -> {
|
||||
instruction.stop(minion.getInstructionManager());
|
||||
updateRunSlot(instruction, minion, gui);
|
||||
@@ -117,11 +160,11 @@ public class InstructionGui {
|
||||
return;
|
||||
}
|
||||
|
||||
A argument = instruction.getArguments().getArgument(parameter);
|
||||
@Nullable A argument = instruction.getArguments().getArgument(parameter);
|
||||
|
||||
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_3X3, player, false);
|
||||
gui.setSlot(3, new GuiElementBuilder(Items.STICK)
|
||||
.setName(Text.literal("Type: " + (argument == null ? "Unset" : MinionRegistries.ARGUMENT_TYPES.getId(argument.getType()).getPath())))
|
||||
.setName(Text.translatable("minions.gui.instruction.argument.configure.type", Text.translatable(TranslationUtil.getTranslationKey(argument != null ? argument.getType() : null, MinionRegistries.ARGUMENT_TYPES, "minions.gui.instruction.argument.configure.type.unset"))))
|
||||
.setCallback(() -> selectArgumentType(player)
|
||||
.thenApply(type -> type.openConfiguration(player, parameter.type(), null)
|
||||
.thenAccept(newArgument -> {
|
||||
|
||||
@@ -21,7 +21,7 @@ public class MinionGui {
|
||||
|
||||
gui.setSlot(1, new GuiElementBuilder()
|
||||
.setItem(Items.COMMAND_BLOCK)
|
||||
.setName(Text.translatable("minions.gui.main.commands"))
|
||||
.setName(Text.translatable("minions.gui.main.instructions"))
|
||||
.setCallback((i, clickType, slotActionType) -> {
|
||||
InstructionGui.openInstructionMainMenu(minion, player);
|
||||
})
|
||||
@@ -50,14 +50,6 @@ public class MinionGui {
|
||||
gui.open();
|
||||
}
|
||||
|
||||
public static void openCommandsGui(ServerPlayerEntity player, MinionFakePlayer minion) {
|
||||
//CommandsGui.openServerModuleCommandGui(player, minion);
|
||||
}
|
||||
|
||||
public static void openProgrammingInventory(ServerPlayerEntity player, MinionFakePlayer minion) {
|
||||
|
||||
}
|
||||
|
||||
public static void openMinionInventory(ServerPlayerEntity player, MinionFakePlayer minion) {
|
||||
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_9X5, player, false);
|
||||
gui.setTitle(Text.translatable("minions.gui.inventory.title", minion.getName()));
|
||||
|
||||
@@ -3,7 +3,7 @@ package io.github.skippyall.minions.gui;
|
||||
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||
import eu.pb4.sgui.api.gui.SimpleGui;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.input.TextInput;
|
||||
import io.github.skippyall.minions.gui.input.TextInput;
|
||||
import io.github.skippyall.minions.minion.MinionData;
|
||||
import io.github.skippyall.minions.minion.MinionItem;
|
||||
import io.github.skippyall.minions.minion.MinionProfileUtils;
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package io.github.skippyall.minions.gui.input;
|
||||
|
||||
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||
import eu.pb4.sgui.api.gui.SimpleGui;
|
||||
import io.github.skippyall.minions.gui.Displayable;
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
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;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ChoiceInput {
|
||||
public static <T> BiFunction<ServerPlayerEntity, T, CompletableFuture<T>> createDialogOpener(ScreenHandlerType<?> screen, Text title, Function<T, GuiDisplay> displayFunction, T[] values, @Nullable T fallback) {
|
||||
return (player, object) -> {
|
||||
CompletableFuture<T> future = new CompletableFuture<>();
|
||||
|
||||
SimpleGui gui = new SimpleGui(screen, player, false) {
|
||||
@Override
|
||||
public void onClose() {
|
||||
if(fallback == null) {
|
||||
future.cancel(false);
|
||||
} else {
|
||||
future.complete(fallback);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
gui.setTitle(title);
|
||||
|
||||
for(T value : values) {
|
||||
gui.addSlot(displayFunction.apply(value).createElement()
|
||||
.setCallback(() -> future.complete(value))
|
||||
);
|
||||
}
|
||||
gui.open();
|
||||
return future;
|
||||
};
|
||||
}
|
||||
|
||||
public static <T extends Displayable> BiFunction<ServerPlayerEntity, T, CompletableFuture<T>> createDialogOpener(T[] values) {
|
||||
return createDialogOpener(ScreenHandlerType.GENERIC_9X3, Text.empty(), Displayable::getDisplay, values, null);
|
||||
}
|
||||
|
||||
public static CompletableFuture<Void> confirm(ServerPlayerEntity player, Text title) {
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
|
||||
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_3X3, player, false) {
|
||||
@Override
|
||||
public void onClose() {
|
||||
future.cancel(false);
|
||||
}
|
||||
};
|
||||
|
||||
gui.setTitle(title);
|
||||
|
||||
gui.setSlot(3, new GuiElementBuilder(Items.REDSTONE_BLOCK)
|
||||
.setName(Text.translatable("minions.gui.abort"))
|
||||
.setCallback(() -> future.cancel(false))
|
||||
);
|
||||
|
||||
gui.setSlot(5, new GuiElementBuilder(Items.EMERALD_BLOCK)
|
||||
.setName(Text.translatable("minions.gui.confirm"))
|
||||
.setCallback(() -> future.complete(null))
|
||||
);
|
||||
|
||||
gui.open();
|
||||
return future;
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
package io.github.skippyall.minions.input;
|
||||
package io.github.skippyall.minions.gui.input;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -87,7 +87,7 @@ public interface Result<T, E> {
|
||||
|
||||
@Override
|
||||
public @NotNull T getOrThrow() {
|
||||
throw new RuntimeException("Result was an error: " + message.toString());
|
||||
throw new RuntimeException("Result was an error: " + message);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -106,7 +106,7 @@ public interface Result<T, E> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ifError(Consumer<Error<T, E>> handler) {
|
||||
public void ifError(@NotNull Consumer<Error<T, E>> handler) {
|
||||
handler.accept(this);
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -1,4 +1,4 @@
|
||||
package io.github.skippyall.minions.input;
|
||||
package io.github.skippyall.minions.gui.input;
|
||||
|
||||
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||
import eu.pb4.sgui.api.gui.AnvilInputGui;
|
||||
@@ -9,7 +9,6 @@ import net.minecraft.text.Text;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class TextInput<T> extends AnvilInputGui {
|
||||
private final GuiElementBuilder valid = new GuiElementBuilder()
|
||||
@@ -1,37 +0,0 @@
|
||||
package io.github.skippyall.minions.input;
|
||||
|
||||
import eu.pb4.sgui.api.gui.SimpleGui;
|
||||
import io.github.skippyall.minions.gui.Displayable;
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ChoiceInput {
|
||||
public static <T> BiFunction<ServerPlayerEntity, T, CompletableFuture<T>> createDialogOpener(Function<T, GuiDisplay> displayFunction, T[] values) {
|
||||
return (player, object) -> {
|
||||
CompletableFuture<T> future = new CompletableFuture<>();
|
||||
|
||||
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_9X3, player, false) {
|
||||
@Override
|
||||
public void onClose() {
|
||||
future.cancel(false);
|
||||
}
|
||||
};
|
||||
for(T value : values) {
|
||||
gui.addSlot(displayFunction.apply(value).createElement()
|
||||
.setCallback(() -> future.complete(value))
|
||||
);
|
||||
}
|
||||
gui.open();
|
||||
return future;
|
||||
};
|
||||
}
|
||||
|
||||
public static <T extends Displayable> BiFunction<ServerPlayerEntity, T, CompletableFuture<T>> createDialogOpener(T[] values) {
|
||||
return createDialogOpener(Displayable::getDisplay, values);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.github.skippyall.minions.minion;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.PersistentState;
|
||||
import net.minecraft.world.PersistentStateType;
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
package io.github.skippyall.minions.minion;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.ProfileLookupCallback;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import com.mojang.authlib.yggdrasil.ProfileResult;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import io.github.skippyall.minions.input.Result;
|
||||
import net.minecraft.block.entity.SkullBlockEntity;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import io.github.skippyall.minions.gui.input.Result;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.StringHelper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
|
||||
import static io.github.skippyall.minions.Minions.LOGGER;
|
||||
|
||||
|
||||
@@ -40,7 +40,11 @@ public class MinionRuntime implements InstructionRuntime<MinionRuntime> {
|
||||
}
|
||||
|
||||
public ConfiguredInstruction<MinionRuntime> createInstruction(String name, InstructionType<MinionRuntime> instructionType) {
|
||||
ConfiguredInstruction<MinionRuntime> instruction = new ConfiguredInstruction<>(instructionType, name);
|
||||
if(configuredInstructions.containsKey(name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ConfiguredInstruction<MinionRuntime> instruction = new ConfiguredInstruction<>(instructionType);
|
||||
configuredInstructions.put(name, instruction);
|
||||
return instruction;
|
||||
}
|
||||
@@ -59,6 +63,12 @@ public class MinionRuntime implements InstructionRuntime<MinionRuntime> {
|
||||
return configuredInstructions.containsKey(name);
|
||||
}
|
||||
|
||||
public void setInstructionName(String oldName, String newName) {
|
||||
if(!configuredInstructions.containsKey(newName)) {
|
||||
configuredInstructions.put(newName, configuredInstructions.remove(oldName));
|
||||
}
|
||||
}
|
||||
|
||||
public void save(WriteView view) {
|
||||
WriteView.ListView list = view.getList("configuredInstructions");
|
||||
for (Map.Entry<String, ConfiguredInstruction<MinionRuntime>> instruction : configuredInstructions.entrySet()) {
|
||||
@@ -78,7 +88,7 @@ public class MinionRuntime implements InstructionRuntime<MinionRuntime> {
|
||||
}
|
||||
|
||||
try {
|
||||
ConfiguredInstruction<MinionRuntime> instruction = ConfiguredInstruction.load(inner, this, name.get());
|
||||
ConfiguredInstruction<MinionRuntime> instruction = ConfiguredInstruction.load(inner, this);
|
||||
configuredInstructions.put(name.get(), instruction);
|
||||
} catch (Exception e) {
|
||||
Minions.LOGGER.error("Could not deserialize configured instruction \"{}\" of minion \"{}\":", name.get(), minion.getGameProfile().getName(), e);
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.github.skippyall.minions.minion.skin;
|
||||
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import io.github.skippyall.minions.input.TextInput;
|
||||
import io.github.skippyall.minions.gui.input.TextInput;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.github.skippyall.minions.minion.skin;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import io.github.skippyall.minions.input.TextInput;
|
||||
import io.github.skippyall.minions.gui.input.TextInput;
|
||||
import net.minecraft.block.entity.SkullBlockEntity;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
@@ -2,16 +2,10 @@ package io.github.skippyall.minions.minion.skin;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import io.github.skippyall.minions.input.TextInput;
|
||||
import io.github.skippyall.minions.minion.MinionProfileUtils;
|
||||
import io.github.skippyall.minions.gui.input.TextInput;
|
||||
import net.minecraft.block.entity.SkullBlockEntity;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Uuids;
|
||||
import net.minecraft.util.dynamic.Codecs;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
+7
-13
@@ -13,18 +13,16 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
|
||||
private final ValueSupplierList<R> arguments;
|
||||
private final ValueConsumerList<R> valueConsumers;
|
||||
private @Nullable InstructionExecution<R> execution;
|
||||
private final String name;
|
||||
|
||||
private ConfiguredInstruction(InstructionType<R> instruction, ValueSupplierList<R> arguments, ValueConsumerList<R> valueConsumers, @Nullable InstructionExecution<R> execution, String name) {
|
||||
private ConfiguredInstruction(InstructionType<R> instruction, ValueSupplierList<R> arguments, ValueConsumerList<R> valueConsumers, @Nullable InstructionExecution<R> execution) {
|
||||
this.instruction = instruction;
|
||||
this.arguments = arguments;
|
||||
this.valueConsumers = valueConsumers;
|
||||
this.execution = execution;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public ConfiguredInstruction(InstructionType<R> instruction, String name) {
|
||||
this(instruction, new ValueSupplierList<>(), new ValueConsumerList<>(), null, name);
|
||||
public ConfiguredInstruction(InstructionType<R> instruction) {
|
||||
this(instruction, new ValueSupplierList<>(), new ValueConsumerList<>(), null);
|
||||
}
|
||||
|
||||
public InstructionType<R> getInstruction() {
|
||||
@@ -35,10 +33,6 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean canRun() {
|
||||
return instruction != null && arguments != null && arguments.hasArgumentForAll(instruction.getParameters());
|
||||
}
|
||||
@@ -57,7 +51,7 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
|
||||
execution = instruction.createExecution(arguments, minion);
|
||||
execution.start(minion);
|
||||
} catch (Exception e) {
|
||||
Minions.LOGGER.error("An error occurred while executing configured Instruction {}", name, e);
|
||||
Minions.LOGGER.error("An error occurred while executing configured Instruction", e);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -93,7 +87,7 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
|
||||
}
|
||||
}
|
||||
|
||||
public static <R extends InstructionRuntime<R>> ConfiguredInstruction<R> load(ReadView view, R minion, String name) {
|
||||
public static <R extends InstructionRuntime<R>> ConfiguredInstruction<R> load(ReadView view, R minion) {
|
||||
InstructionType<R> instructionType = view.read("instruction", minion.getInstructionTypeRegistry().getCodec()).orElseThrow();
|
||||
|
||||
ValueSupplierList<R> arguments = view.read("arguments", minion.getArgumentListCodec()).orElseGet(ValueSupplierList::new);
|
||||
@@ -105,12 +99,12 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
|
||||
ReadView executionView = view.getReadView("execution");
|
||||
try {
|
||||
InstructionExecution<R> execution = instructionType.loadExecution(executionView, minion);
|
||||
return new ConfiguredInstruction<>(instructionType, arguments, valueConsumers, execution, name);
|
||||
return new ConfiguredInstruction<>(instructionType, arguments, valueConsumers, execution);
|
||||
} catch (Exception e) {
|
||||
Minions.LOGGER.error("Error while loading execution", e);
|
||||
}
|
||||
}
|
||||
|
||||
return new ConfiguredInstruction<>(instructionType, arguments, valueConsumers, null, name);
|
||||
return new ConfiguredInstruction<>(instructionType, arguments, valueConsumers, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import io.github.skippyall.minions.program.instruction.execution.ActionExecution
|
||||
import io.github.skippyall.minions.program.instruction.execution.TurnExecution;
|
||||
import io.github.skippyall.minions.program.instruction.execution.WalkExecution;
|
||||
import io.github.skippyall.minions.program.supplier.Parameter;
|
||||
import io.github.skippyall.minions.util.ModelIdUtil;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.util.Identifier;
|
||||
@@ -22,7 +21,7 @@ import java.util.function.Supplier;
|
||||
public class Instructions {
|
||||
public static final InstructionType<MinionRuntime> WALK = register(
|
||||
"walk",
|
||||
base -> new GuiDisplay.ModelBased(ModelIdUtil.getItemModelId(Items.IRON_BOOTS), base, true),
|
||||
base -> new GuiDisplay.ModelBased(Items.IRON_BOOTS, base, true),
|
||||
WalkExecution::new,
|
||||
List.of(WalkExecution.blocksToMoveParam)
|
||||
);
|
||||
@@ -36,13 +35,13 @@ public class Instructions {
|
||||
|
||||
public static final InstructionType<MinionRuntime> ATTACK = register(
|
||||
"attack",
|
||||
base -> new GuiDisplay.ModelBased(ModelIdUtil.getItemModelId(Items.IRON_BOOTS), base, true),
|
||||
base -> new GuiDisplay.ModelBased(Items.IRON_PICKAXE, base, true),
|
||||
() -> new ActionExecution(EntityPlayerActionPack.ActionType.ATTACK)
|
||||
);
|
||||
|
||||
public static final InstructionType<MinionRuntime> USE = register(
|
||||
"use",
|
||||
base -> new GuiDisplay.ModelBased(ModelIdUtil.getItemModelId(Items.LEVER), base, true),
|
||||
base -> new GuiDisplay.ModelBased(Items.LEVER, base, true),
|
||||
() -> new ActionExecution(EntityPlayerActionPack.ActionType.USE)
|
||||
);
|
||||
|
||||
|
||||
@@ -3,10 +3,9 @@ package io.github.skippyall.minions.program.value;
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.gui.Displayable;
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import io.github.skippyall.minions.input.ChoiceInput;
|
||||
import io.github.skippyall.minions.input.TextInput;
|
||||
import io.github.skippyall.minions.gui.input.ChoiceInput;
|
||||
import io.github.skippyall.minions.gui.input.TextInput;
|
||||
import io.github.skippyall.minions.program.instruction.execution.TurnExecution;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.registry.Registry;
|
||||
|
||||
@@ -6,7 +6,6 @@ import net.minecraft.util.Identifier;
|
||||
|
||||
public class ModelIdUtil {
|
||||
public static Identifier getItemModelId(Item item) {
|
||||
Identifier identifier = Registries.ITEM.getId(item);
|
||||
return identifier.withPrefixedPath("item/");
|
||||
return Registries.ITEM.getId(item);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user