Redo everything
This commit is contained in:
@@ -2,7 +2,6 @@ package io.github.skippyall.minions;
|
||||
|
||||
import eu.pb4.polymer.core.api.item.SimplePolymerItem;
|
||||
import io.github.skippyall.minions.minion.MinionItem;
|
||||
import io.github.skippyall.minions.module.Modules;
|
||||
import net.minecraft.component.DataComponentTypes;
|
||||
import net.minecraft.component.type.DamageResistantComponent;
|
||||
import net.minecraft.entity.damage.DamageType;
|
||||
@@ -39,6 +38,5 @@ public class MinionItems {
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
Modules.register();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package io.github.skippyall.minions;
|
||||
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import io.github.skippyall.minions.minion.skin.SkinProvider;
|
||||
import io.github.skippyall.minions.new_program.argument.GenericArgumentType;
|
||||
import io.github.skippyall.minions.new_program.instruction.InstructionType;
|
||||
import io.github.skippyall.minions.new_program.value.ValueType;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.SimpleRegistry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class MinionRegistries {
|
||||
public static final Registry<ValueType<?>> VALUE_TYPES = registry("value_type");
|
||||
public static final Registry<GenericArgumentType> GENERIC_ARGUMENT_TYPE_REGISTRY = registry("generic_argument_type");
|
||||
public static final Registry<InstructionType<?>> INSTRUCTION_TYPES = registry("instruction_type");
|
||||
public static final Registry<SkinProvider> SKIN_PROVIDERS = registry("skin_providers");
|
||||
|
||||
private static <T> Registry<T> registry(String id) {
|
||||
return new SimpleRegistry<>(RegistryKey.ofRegistry(Identifier.of(Minions.MOD_ID, id)), Lifecycle.stable());
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,19 @@ import io.github.skippyall.minions.command.MinionsCommand;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.minion.MinionData;
|
||||
import io.github.skippyall.minions.minion.MinionPersistentState;
|
||||
import io.github.skippyall.minions.minion.skin.SkinProviders;
|
||||
import io.github.skippyall.minions.mixins.PlayerListEntryS2CPacket$EntryMixin;
|
||||
import io.github.skippyall.minions.new_module.MinionModule;
|
||||
import io.github.skippyall.minions.new_module.ModuleLoader;
|
||||
import io.github.skippyall.minions.new_program.instruction.Instructions;
|
||||
import io.github.skippyall.minions.new_program.value.ValueTypes;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -21,10 +28,12 @@ public class Minions implements ModInitializer {
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
Instructions.register();
|
||||
|
||||
MinionData.register();
|
||||
PolymerEntityUtils.registerType();
|
||||
MinionModule.register();
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTED.register(server -> {
|
||||
LOGGER.error("Initializing Minion data");
|
||||
MinionPersistentState.create(server);
|
||||
MinionPersistentState.INSTANCE.getMinionData().forEach((uuid, data) -> {
|
||||
if(data.isSpawned()) {
|
||||
@@ -32,14 +41,16 @@ public class Minions implements ModInitializer {
|
||||
}
|
||||
});
|
||||
});
|
||||
PlayerEntity
|
||||
ClientPlayNetworkHandler
|
||||
|
||||
CommandRegistrationCallback.EVENT.register((commandDispatcher, commandRegistryAccess, registrationEnvironment) -> {
|
||||
MinionsCommand.register(commandDispatcher);
|
||||
});
|
||||
|
||||
ValueTypes.register();
|
||||
SkinProviders.register();
|
||||
MinionItems.register();
|
||||
MinionCreativeTab.registerGroup();
|
||||
|
||||
ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(new ModuleLoader());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,8 @@
|
||||
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.module.command.Command;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.module.ModuleItem;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class CommandsGui {
|
||||
public static void openServerModuleCommandGui(ServerPlayerEntity player, MinionFakePlayer minion) {
|
||||
Collection<ModuleItem> modules = minion.getModuleInventory().getModuleItems();
|
||||
/*public static void openServerModuleCommandGui(ServerPlayerEntity player, MinionFakePlayer minion) {
|
||||
Collection<ModuleItem> modules = minion.getModuleInventory().getModules();
|
||||
|
||||
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_9X3, player, false);
|
||||
|
||||
@@ -48,5 +36,5 @@ public class CommandsGui {
|
||||
}
|
||||
|
||||
commandGui.open();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package io.github.skippyall.minions.gui;
|
||||
|
||||
public interface Displayable {
|
||||
GuiDisplay getDisplay();
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package io.github.skippyall.minions.gui;
|
||||
|
||||
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||
import io.github.skippyall.minions.util.ModelIdUtil;
|
||||
import net.minecraft.component.DataComponentTypes;
|
||||
import net.minecraft.component.type.LoreComponent;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public interface GuiDisplay {
|
||||
default GuiElementBuilder createElement() {
|
||||
return new GuiElementBuilder(createItemStack());
|
||||
}
|
||||
|
||||
ItemStack createItemStack();
|
||||
|
||||
record ModelBased(Identifier model, String translationKeyBase, boolean withLore) implements GuiDisplay {
|
||||
public ModelBased(Item model, String translationKeyBase, boolean withLore) {
|
||||
this(ModelIdUtil.getItemModelId(model), translationKeyBase, withLore);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack createItemStack() {
|
||||
ItemStack stack = new ItemStack(Items.BARRIER);
|
||||
stack.set(DataComponentTypes.ITEM_MODEL, model);
|
||||
stack.set(DataComponentTypes.ITEM_NAME, Text.translatable(translationKeyBase + ".name"));
|
||||
if(withLore) {
|
||||
stack.set(DataComponentTypes.LORE, LoreComponent.DEFAULT.with(Text.translatable(translationKeyBase + ".description")));
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ public class MinionGui {
|
||||
.setItem(Items.COMMAND_BLOCK)
|
||||
.setName(Text.translatable("minions.gui.main.commands"))
|
||||
.setCallback((i, clickType, slotActionType) -> {
|
||||
openCommandsGui(player, minion);
|
||||
InstructionGui.openInstructionMainMenu(minion, player);
|
||||
})
|
||||
);
|
||||
gui.setSlot(3, new GuiElementBuilder()
|
||||
@@ -50,7 +50,7 @@ public class MinionGui {
|
||||
}
|
||||
|
||||
public static void openCommandsGui(ServerPlayerEntity player, MinionFakePlayer minion) {
|
||||
CommandsGui.openServerModuleCommandGui(player, minion);
|
||||
//CommandsGui.openServerModuleCommandGui(player, minion);
|
||||
}
|
||||
|
||||
public static void openProgrammingInventory(ServerPlayerEntity player, MinionFakePlayer minion) {
|
||||
|
||||
@@ -2,6 +2,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.minion.MinionData;
|
||||
import io.github.skippyall.minions.minion.MinionItem;
|
||||
@@ -57,13 +58,13 @@ public class MinionLookGui extends SimpleGui {
|
||||
}
|
||||
|
||||
private void cycleSkinProvider() {
|
||||
int currentId = SkinProviders.SKIN_PROVIDERS.getRawId(currentSkinProvider);
|
||||
int currentId = MinionRegistries.SKIN_PROVIDERS.getRawId(currentSkinProvider);
|
||||
currentId++;
|
||||
if(SkinProviders.SKIN_PROVIDERS.size() == currentId) {
|
||||
if(MinionRegistries.SKIN_PROVIDERS.size() == currentId) {
|
||||
currentId = 0;
|
||||
}
|
||||
|
||||
currentSkinProvider = SkinProviders.SKIN_PROVIDERS.get(currentId);
|
||||
currentSkinProvider = MinionRegistries.SKIN_PROVIDERS.get(currentId);
|
||||
updateSkinProvider();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package io.github.skippyall.minions.gui;
|
||||
|
||||
import io.github.skippyall.minions.module.command.Command;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.module.ModuleItem;
|
||||
import io.github.skippyall.minions.program.block.CodeBlock;
|
||||
import io.github.skippyall.minions.new_module.MinionModule;
|
||||
import io.github.skippyall.minions.new_program.instruction.InstructionType;
|
||||
import net.minecraft.inventory.Inventories;
|
||||
import net.minecraft.inventory.SimpleInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -20,7 +19,7 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ModuleInventory extends SimpleInventory {
|
||||
private final Set<ModuleItem> modules = new HashSet<>();
|
||||
private final Set<MinionModule> modules = new HashSet<>();
|
||||
public ModuleInventory() {
|
||||
super(27);
|
||||
}
|
||||
@@ -36,7 +35,7 @@ public class ModuleInventory extends SimpleInventory {
|
||||
|
||||
@Override
|
||||
public boolean isValid(int slot, ItemStack stack) {
|
||||
return (stack.getCount() <= getMaxCountPerStack()) && stack.getItem() instanceof ModuleItem;
|
||||
return (stack.getCount() <= getMaxCountPerStack()) && stack.contains(MinionModule.COMPONENT_TYPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,8 +47,9 @@ public class ModuleInventory extends SimpleInventory {
|
||||
public void updateModules() {
|
||||
modules.clear();
|
||||
for (ItemStack heldStack : heldStacks) {
|
||||
if(heldStack.getItem() instanceof ModuleItem moduleItem) {
|
||||
modules.add(moduleItem);
|
||||
MinionModule module = heldStack.get(MinionModule.COMPONENT_TYPE);
|
||||
if(module != null) {
|
||||
modules.add(module);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,31 +63,19 @@ public class ModuleInventory extends SimpleInventory {
|
||||
Inventories.writeData(view, heldStacks);
|
||||
}
|
||||
|
||||
public boolean hasModule(ModuleItem module) {
|
||||
public boolean hasModule(MinionModule module) {
|
||||
return modules.contains(module);
|
||||
}
|
||||
|
||||
public Collection<ModuleItem> getModuleItems() {
|
||||
public Collection<MinionModule> getModules() {
|
||||
return modules;
|
||||
}
|
||||
|
||||
public List<Command> getAllCommands() {
|
||||
ArrayList<Command> commands = new ArrayList<>();
|
||||
for(ItemStack stack : heldStacks) {
|
||||
if(stack.getItem() instanceof ModuleItem module) {
|
||||
commands.addAll(module.getCommands());
|
||||
}
|
||||
public List<InstructionType<?>> getAllInstructions() {
|
||||
ArrayList<InstructionType<?>> instructionTypes = new ArrayList<>();
|
||||
for(MinionModule module : modules) {
|
||||
instructionTypes.addAll(module.instructions());
|
||||
}
|
||||
return commands;
|
||||
}
|
||||
|
||||
public List<CodeBlock<?,?>> getAllCodeBlocks() {
|
||||
ArrayList<CodeBlock<?,?>> commands = new ArrayList<>();
|
||||
for(ItemStack stack : heldStacks) {
|
||||
if(stack.getItem() instanceof ModuleItem module) {
|
||||
commands.addAll(module.getCodeBlocks());
|
||||
}
|
||||
}
|
||||
return commands;
|
||||
return instructionTypes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ public class TextInput<T> extends AnvilInputGui {
|
||||
private final Function<String, CompletableFuture<Result<T, Text>>> parser;
|
||||
private final CompletableFuture<T> future;
|
||||
private Result<T, Text> result;
|
||||
private boolean isConfirm;
|
||||
|
||||
public TextInput(ServerPlayerEntity player, Text title, String defaultValue, Function<String, CompletableFuture<Result<T, Text>>> parser, CompletableFuture<T> future) {
|
||||
super(player, false);
|
||||
@@ -74,7 +75,7 @@ public class TextInput<T> extends AnvilInputGui {
|
||||
|
||||
@Override
|
||||
public void onClose() {
|
||||
if(!future.isDone()) {
|
||||
if(!future.isDone() && !isConfirm) {
|
||||
future.cancel(false);
|
||||
}
|
||||
}
|
||||
@@ -82,8 +83,9 @@ public class TextInput<T> extends AnvilInputGui {
|
||||
public void onConfirm() {
|
||||
if(result != null) {
|
||||
result.ifSuccess(success -> {
|
||||
future.complete(success);
|
||||
isConfirm = true;
|
||||
close();
|
||||
future.complete(success);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package io.github.skippyall.minions.minion;
|
||||
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.new_program.instruction.ConfiguredInstruction;
|
||||
import io.github.skippyall.minions.new_program.instruction.InstructionType;
|
||||
import net.minecraft.storage.ReadView;
|
||||
import net.minecraft.storage.WriteView;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class MinionInstructionManager {
|
||||
private final MinionFakePlayer minion;
|
||||
private final Map<String, ConfiguredInstruction<?>> configuredInstructions = new HashMap<>();
|
||||
|
||||
public MinionInstructionManager(MinionFakePlayer minion) {
|
||||
this.minion = minion;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
for (ConfiguredInstruction<?> instruction : configuredInstructions.values()) {
|
||||
instruction.tick(minion);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<String> getInstructionNames() {
|
||||
return configuredInstructions.keySet();
|
||||
}
|
||||
|
||||
public <T> ConfiguredInstruction<T> createInstruction(String name, InstructionType<T> instructionType) {
|
||||
ConfiguredInstruction<T> instruction = new ConfiguredInstruction<>(instructionType, name);
|
||||
configuredInstructions.put(name, instruction);
|
||||
return instruction;
|
||||
}
|
||||
|
||||
public void removeInstruction(String name) {
|
||||
ConfiguredInstruction<?> instruction = getInstruction(name);
|
||||
instruction.stop(minion);
|
||||
configuredInstructions.remove(name);
|
||||
}
|
||||
|
||||
public ConfiguredInstruction<?> getInstruction(String name) {
|
||||
return configuredInstructions.get(name);
|
||||
}
|
||||
|
||||
public void save(WriteView view) {
|
||||
WriteView.ListView list = view.getList("configuredInstructions");
|
||||
for (Map.Entry<String, ConfiguredInstruction<?>> instruction : configuredInstructions.entrySet()) {
|
||||
WriteView inner = list.add();
|
||||
inner.putString("name", instruction.getKey());
|
||||
instruction.getValue().save(inner, minion);
|
||||
}
|
||||
}
|
||||
|
||||
public void load(ReadView view) {
|
||||
ReadView.ListReadView list = view.getListReadView("configuredInstructions");
|
||||
for (ReadView inner : list) {
|
||||
Optional<String> name = inner.getOptionalString("name");
|
||||
if(name.isEmpty()) {
|
||||
Minions.LOGGER.error("Tried deserializing configured instruction without a name of minion \"{}\":", minion.getGameProfile().getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
ConfiguredInstruction<?> instruction = ConfiguredInstruction.load(inner, minion, name.get());
|
||||
configuredInstructions.put(name.get(), instruction);
|
||||
} catch (Exception e) {
|
||||
Minions.LOGGER.error("Could not deserialize configured instruction \"{}\" of minion \"{}\":", name.get(), minion.getGameProfile().getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,16 +6,15 @@ import com.mojang.authlib.properties.PropertyMap;
|
||||
import io.github.skippyall.minions.MinionItems;
|
||||
import io.github.skippyall.minions.minion.MinionData;
|
||||
import io.github.skippyall.minions.gui.MinionGui;
|
||||
import io.github.skippyall.minions.minion.MinionInstructionManager;
|
||||
import io.github.skippyall.minions.minion.MinionItem;
|
||||
import io.github.skippyall.minions.minion.MinionPersistentState;
|
||||
import io.github.skippyall.minions.minion.MinionProfileUtils;
|
||||
import io.github.skippyall.minions.gui.ModuleInventory;
|
||||
import io.github.skippyall.minions.program.runtime.MinionRuntime;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.ItemEntity;
|
||||
import net.minecraft.entity.MovementType;
|
||||
import net.minecraft.entity.attribute.EntityAttributes;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
import net.minecraft.entity.player.HungerManager;
|
||||
@@ -56,7 +55,7 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
private float moveSideways;
|
||||
|
||||
private final ModuleInventory moduleInventory = new ModuleInventory();
|
||||
private final MinionRuntime runtime = new MinionRuntime(this);
|
||||
private final MinionInstructionManager instructionManager = new MinionInstructionManager(this);
|
||||
|
||||
private final MinionData data;
|
||||
|
||||
@@ -115,14 +114,26 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
return moduleInventory;
|
||||
}
|
||||
|
||||
public MinionRuntime getRuntime() {
|
||||
return runtime;
|
||||
}
|
||||
|
||||
public EntityPlayerActionPack getMinionActionPack() {
|
||||
return actionPack;
|
||||
}
|
||||
|
||||
public MinionInstructionManager getInstructionManager() {
|
||||
return instructionManager;
|
||||
}
|
||||
|
||||
public MinionData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public boolean canSpawnMobs() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean canDespawnMobs() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult interact(PlayerEntity player, Hand hand) {
|
||||
if(player instanceof ServerPlayerEntity spe) {
|
||||
@@ -176,13 +187,13 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
{
|
||||
super.tick();
|
||||
this.playerTick();
|
||||
instructionManager.tick();
|
||||
}
|
||||
catch (NullPointerException ignored)
|
||||
{
|
||||
// happens with that paper port thingy - not sure what that would fix, but hey
|
||||
// the game not gonna crash violently.
|
||||
}
|
||||
runtime.tick();
|
||||
|
||||
}
|
||||
|
||||
@@ -238,7 +249,7 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
return networkHandler.player;
|
||||
}
|
||||
|
||||
public void moveForward(float forward) {
|
||||
/*public void moveForward(float forward) {
|
||||
this.moveForward += forward;
|
||||
EntityPlayerActionPack actionPack = getMinionActionPack();
|
||||
if (moveForward != 0) {
|
||||
@@ -274,7 +285,7 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
moveSideways = newSideways;
|
||||
}
|
||||
super.move(movementType, newMovement);
|
||||
}
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public void drop(ServerWorld world, DamageSource damageSource) {
|
||||
@@ -291,19 +302,17 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
return stack;
|
||||
}
|
||||
|
||||
public MinionData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeCustomData(WriteView view) {
|
||||
super.writeCustomData(view);
|
||||
moduleInventory.writeData(view.get("modules"));
|
||||
instructionManager.save(view.get("instructionManager"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readCustomData(ReadView view) {
|
||||
super.readCustomData(view);
|
||||
moduleInventory.readData(view.getReadView("modules"));
|
||||
instructionManager.load(view.getReadView("instructionManager"));
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,17 @@
|
||||
package io.github.skippyall.minions.minion.skin;
|
||||
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.SimpleRegistry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class SkinProviders {
|
||||
public static final Registry<SkinProvider> SKIN_PROVIDERS = new SimpleRegistry<>(RegistryKey.ofRegistry(Identifier.of(Minions.MOD_ID, "skin_providers")), Lifecycle.stable());
|
||||
|
||||
public static NameSkinProvider NAME = register(new NameSkinProvider(), "name");
|
||||
public static UUIDSkinProvider UUID = register(new UUIDSkinProvider(), "uuid");
|
||||
public static Base64SkinProvider BASE64 = register(new Base64SkinProvider(), "base64");
|
||||
|
||||
|
||||
public static <T extends SkinProvider> T register(T skinProvider, String path) {
|
||||
return Registry.register(SKIN_PROVIDERS, Identifier.of(Minions.MOD_ID, path), skinProvider);
|
||||
return Registry.register(MinionRegistries.SKIN_PROVIDERS, Identifier.of(Minions.MOD_ID, path), skinProvider);
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.mixinhelper.EntityViewMixinHelper;
|
||||
import io.github.skippyall.minions.module.MobSpawningModule;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
@@ -18,7 +17,7 @@ public abstract class MobEntityMixin {
|
||||
public PlayerEntity checkMobDespawningMinion(World instance, Entity entity, double maxDistance, Operation<PlayerEntity> original) {
|
||||
EntityViewMixinHelper.ADDITIONAL_PREDICATE.set(entity2 -> {
|
||||
if(entity2 instanceof MinionFakePlayer minion) {
|
||||
return MobSpawningModule.canMinionDespawnMobs(minion);
|
||||
return minion.canDespawnMobs();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.github.skippyall.minions.mixins;
|
||||
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.module.MobSpawningModule;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.predicate.entity.EntityPredicates;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
@@ -18,7 +17,7 @@ public class SpawnHelperMixin {
|
||||
return instance.getClosestPlayer(x, y, z, maxDistance, EntityPredicates.EXCEPT_SPECTATOR.and(entity -> {
|
||||
if(entity instanceof ServerPlayerEntity player) {
|
||||
if(player instanceof MinionFakePlayer minion) {
|
||||
return MobSpawningModule.canMinionSpawnMobs(minion);
|
||||
return minion.canSpawnMobs();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
+1
-2
@@ -3,7 +3,6 @@ package io.github.skippyall.minions.mixins.antimobcap;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.mixinhelper.ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor;
|
||||
import io.github.skippyall.minions.mixinhelper.ChunkLevelManagerAccessor;
|
||||
import io.github.skippyall.minions.module.MobSpawningModule;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ByteMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectSet;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
@@ -47,7 +46,7 @@ public abstract class ChunkLevelManager$DistanceFromNearestPlayerTrackerMixin ex
|
||||
if(players != null) {
|
||||
contains = players.stream().anyMatch(player -> {
|
||||
if (player instanceof MinionFakePlayer minion) {
|
||||
return MobSpawningModule.canMinionSpawnMobs(minion);
|
||||
return minion.canSpawnMobs();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
package io.github.skippyall.minions.module;
|
||||
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.module.action.ActionModules;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack;
|
||||
import io.github.skippyall.minions.module.instruction.InstructionDisplay;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.skippyall.minions.module.Modules.register;
|
||||
|
||||
public class AttackModule {
|
||||
public static final InstructionDisplay ATTACK_COMMAND = new InstructionDisplay(
|
||||
Text.translatable("minions.command.attack.name"),
|
||||
Text.translatable("minions.command.attack.description"),
|
||||
Items.DIAMOND_PICKAXE,
|
||||
ActionModules.detailSelectionExecutor(EntityPlayerActionPack.ActionType.ATTACK, Text.translatable("minions.command.attack.name"))
|
||||
);
|
||||
|
||||
public static final SimpleModuleItem ATTACK_MODULE = register(
|
||||
Identifier.of(Minions.MOD_ID, "attack_module"),
|
||||
List.of(),
|
||||
List.of(ATTACK_COMMAND),
|
||||
Items.DIAMOND_PICKAXE
|
||||
);
|
||||
|
||||
public static void registerMe() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package io.github.skippyall.minions.module;
|
||||
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.module.command.SimpleCommand;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static io.github.skippyall.minions.module.Modules.register;
|
||||
|
||||
public class ChatModule {
|
||||
public static final SimpleModuleItem CHAT_MODULE = register(Identifier.of(Minions.MOD_ID, "chat_module"),
|
||||
new ArrayList<>(), Arrays.asList(
|
||||
new SimpleCommand(Text.of("Message"), Text.of("Send Message in Public Chat"), Items.PAPER, (player, minion) -> minion.getServer().getPlayerManager().broadcast(Text.of("message"), true)),
|
||||
new SimpleCommand(Text.of("Prvt-Message"), Text.of("Send Message to one Person"), Items.TRIAL_KEY, (player, minion) -> {})
|
||||
), Items.PAPER);
|
||||
|
||||
public static void registerMe() {}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package io.github.skippyall.minions.module;
|
||||
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.module.action.ActionModules;
|
||||
import io.github.skippyall.minions.module.command.SimpleCommand;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.skippyall.minions.module.Modules.register;
|
||||
|
||||
public class InteractModule {
|
||||
public static final SimpleCommand INTERACT_COMMAND = new SimpleCommand(
|
||||
Text.translatable("minions.command.interact.name"),
|
||||
Text.translatable("minions.command.interact.description"),
|
||||
Items.LEVER,
|
||||
ActionModules.detailSelectionExecutor(EntityPlayerActionPack.ActionType.USE, Text.translatable("minions.command.interact.name"))
|
||||
);
|
||||
|
||||
public static final SimpleModuleItem INTERACT_MODULE = register(
|
||||
Identifier.of(Minions.MOD_ID, "interact_module"),
|
||||
List.of(),
|
||||
List.of(INTERACT_COMMAND),
|
||||
Items.LEVER
|
||||
);
|
||||
|
||||
public static void registerMe() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
package io.github.skippyall.minions.module;
|
||||
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.skippyall.minions.module.Modules.register;
|
||||
|
||||
public class MobSpawningModule {
|
||||
public static final SimpleModuleItem MOB_SPAWNING_MODULE =
|
||||
register(
|
||||
Identifier.of(Minions.MOD_ID, "mob_spawning_module"),
|
||||
List.of(),
|
||||
List.of(),
|
||||
Items.SPAWNER
|
||||
);
|
||||
|
||||
public static boolean canMinionSpawnMobs(MinionFakePlayer minion) {
|
||||
return minion.getModuleInventory().hasModule(MOB_SPAWNING_MODULE);
|
||||
}
|
||||
|
||||
public static boolean canMinionDespawnMobs(MinionFakePlayer minion) {
|
||||
return minion.getModuleInventory().hasModule(MOB_SPAWNING_MODULE);
|
||||
}
|
||||
|
||||
public static void registerMe() {}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package io.github.skippyall.minions.module;
|
||||
|
||||
import io.github.skippyall.minions.module.instruction.InstructionDisplay;
|
||||
import net.minecraft.item.ItemConvertible;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ModuleItem extends ItemConvertible {
|
||||
List<InstructionDisplay> getInstructions();
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package io.github.skippyall.minions.module;
|
||||
|
||||
import io.github.skippyall.minions.MinionItems;
|
||||
import io.github.skippyall.minions.module.command.Command;
|
||||
import io.github.skippyall.minions.module.instruction.InstructionDisplay;
|
||||
import io.github.skippyall.minions.new_program.instruction.Instruction;
|
||||
import io.github.skippyall.minions.program.block.CodeBlock;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Modules {
|
||||
public static void register() {
|
||||
ChatModule.registerMe();
|
||||
MountModule.registerMe();
|
||||
MoveModule.registerMe();
|
||||
MobSpawningModule.registerMe();
|
||||
InteractModule.registerMe();
|
||||
AttackModule.registerMe();
|
||||
}
|
||||
|
||||
public static SimpleModuleItem register(Identifier id, List<InstructionDisplay> instructions, Item vanillaItem) {
|
||||
return MinionItems.registerItem(id, settings -> new SimpleModuleItem(instructions, settings, vanillaItem));
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package io.github.skippyall.minions.module;
|
||||
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.module.command.SimpleCommand;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.skippyall.minions.module.Modules.register;
|
||||
|
||||
public class MountModule {
|
||||
public static final SimpleCommand MOUNT_COMMAND = new SimpleCommand(
|
||||
Text.of("Mount"),
|
||||
Text.of("Mount the minion to the nearest mountable Entity"),
|
||||
Items.MINECART,
|
||||
(player, minion) -> minion.getMinionActionPack().mount(true)
|
||||
);
|
||||
|
||||
public static final SimpleCommand DISMOUNT_COMMAND = new SimpleCommand(
|
||||
Text.of("Dismount"),
|
||||
Text.of("Dismount the minion"),
|
||||
Items.BARRIER,
|
||||
(player, minion) -> minion.getMinionActionPack().dismount()
|
||||
);
|
||||
|
||||
public static final SimpleModuleItem MOUNT_MODULE =
|
||||
register(Identifier.of(Minions.MOD_ID, "mount_module"),
|
||||
List.of(),
|
||||
List.of(
|
||||
MOUNT_COMMAND,
|
||||
DISMOUNT_COMMAND
|
||||
),
|
||||
Items.MINECART
|
||||
);
|
||||
|
||||
public static void registerMe() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package io.github.skippyall.minions.module;
|
||||
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.module.command.SimpleCommand;
|
||||
import io.github.skippyall.minions.input.TextInput;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.skippyall.minions.module.Modules.register;
|
||||
|
||||
public class MoveModule {
|
||||
public static final SimpleCommand WALK_COMMAND =
|
||||
new SimpleCommand(
|
||||
Text.literal("Walk"),
|
||||
Text.literal("Walk a specific amount of blocks forward"),
|
||||
Items.IRON_BOOTS,
|
||||
(player, minion) -> TextInput.inputFloat(player, Text.literal("Amount of Blocks"), "1")
|
||||
.thenAccept(minion::moveForward)
|
||||
);
|
||||
|
||||
public static final SimpleCommand TURN_RIGHT_COMMAND =
|
||||
new SimpleCommand(
|
||||
Text.literal("Turn Right"),
|
||||
Text.literal("Turn a specific amount of degrees right"),
|
||||
Items.COMPASS,
|
||||
(player, minion) -> TextInput.inputFloat(player, Text.literal("Degrees"), "90")
|
||||
.thenAccept(degrees -> minion.getMinionActionPack().turn(degrees, 0))
|
||||
);
|
||||
|
||||
public static final SimpleCommand TURN_LEFT_COMMAND =
|
||||
new SimpleCommand(
|
||||
Text.literal("Turn Left"),
|
||||
Text.literal("Turn a specific amount of degrees left"),
|
||||
Items.COMPASS,
|
||||
(player, minion) -> TextInput.inputFloat(player, Text.literal("Degrees"), "90")
|
||||
.thenAccept(degrees -> minion.getMinionActionPack().turn(-degrees, 0))
|
||||
);
|
||||
|
||||
public static final SimpleCommand TURN_UP_COMMAND =
|
||||
new SimpleCommand(
|
||||
Text.literal("Turn Up"),
|
||||
Text.literal("Turn a specific amount of degrees up"),
|
||||
Items.COMPASS,
|
||||
(player, minion) -> TextInput.inputFloat(player, Text.literal("Degrees"), "90")
|
||||
.thenAccept(degrees -> minion.getMinionActionPack().turn(0, -degrees))
|
||||
);
|
||||
|
||||
public static final SimpleCommand TURN_DOWN_COMMAND =
|
||||
new SimpleCommand(
|
||||
Text.literal("Turn Down"),
|
||||
Text.literal("Turn a specific amount of degrees down"),
|
||||
Items.COMPASS,
|
||||
(player, minion) -> TextInput.inputFloat(player, Text.literal("Degrees"), "90")
|
||||
.thenAccept(degrees -> minion.getMinionActionPack().turn(0, degrees))
|
||||
);
|
||||
|
||||
|
||||
|
||||
public static final SimpleModuleItem MOVE_MODULE =
|
||||
register(Identifier.of(Minions.MOD_ID, "move_module"),
|
||||
List.of(),
|
||||
List.of(
|
||||
WALK_COMMAND,
|
||||
TURN_RIGHT_COMMAND,
|
||||
TURN_LEFT_COMMAND,
|
||||
TURN_UP_COMMAND,
|
||||
TURN_DOWN_COMMAND
|
||||
),
|
||||
Items.IRON_BOOTS
|
||||
);
|
||||
|
||||
public static void registerMe() {}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package io.github.skippyall.minions.module;
|
||||
|
||||
import eu.pb4.polymer.core.api.item.SimplePolymerItem;
|
||||
import io.github.skippyall.minions.module.command.Command;
|
||||
import io.github.skippyall.minions.module.instruction.InstructionDisplay;
|
||||
import io.github.skippyall.minions.new_program.instruction.Instruction;
|
||||
import io.github.skippyall.minions.program.block.CodeBlock;
|
||||
import net.minecraft.item.Item;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SimpleModuleItem extends SimplePolymerItem implements ModuleItem {
|
||||
private final List<InstructionDisplay> instructions;
|
||||
|
||||
public SimpleModuleItem(List<InstructionDisplay> instructions, Settings settings, Item vanillaItem) {
|
||||
super(settings.maxCount(1), vanillaItem);
|
||||
this.instructions = instructions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InstructionDisplay> getInstructions() {
|
||||
return instructions;
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package io.github.skippyall.minions.module.action;
|
||||
|
||||
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||
import eu.pb4.sgui.api.gui.SimpleGui;
|
||||
import io.github.skippyall.minions.input.TextInput;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.new_program.instruction.Instruction;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ActionModules {
|
||||
public static void executeOnce(EntityPlayerActionPack.ActionType actionType, ServerPlayerEntity player, MinionFakePlayer minion) {
|
||||
minion.getMinionActionPack().start(actionType, EntityPlayerActionPack.Action.once());
|
||||
}
|
||||
|
||||
public static void executeContinuous(EntityPlayerActionPack.ActionType actionType, ServerPlayerEntity player, MinionFakePlayer minion) {
|
||||
minion.getMinionActionPack().start(actionType, EntityPlayerActionPack.Action.continuous());
|
||||
}
|
||||
|
||||
public static void executeInterval(EntityPlayerActionPack.ActionType actionType, ServerPlayerEntity player, MinionFakePlayer minion) {
|
||||
TextInput.inputFloat(player, Text.translatable("minions.command.action.interval.enter"), "3.5").thenAccept(interval -> {
|
||||
int ticks = Math.round(interval * 20);
|
||||
minion.getMinionActionPack().start(actionType, EntityPlayerActionPack.Action.interval(ticks));
|
||||
});
|
||||
}
|
||||
|
||||
public static void executeStop(EntityPlayerActionPack.ActionType actionType, ServerPlayerEntity player, MinionFakePlayer minion) {
|
||||
minion.getMinionActionPack().stop(actionType);
|
||||
}
|
||||
|
||||
public static List<Instruction> actionInstruction(EntityPlayerActionPack.ActionType actionType, Text actionName) {
|
||||
return List.of(
|
||||
|
||||
)
|
||||
|
||||
return (player, minion) -> {
|
||||
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_3X3, player, false);
|
||||
gui.setTitle(Text.translatable("minions.command.action.details", actionName));
|
||||
|
||||
gui.setSlot(1, new GuiElementBuilder()
|
||||
.setItem(Items.COMMAND_BLOCK)
|
||||
.setName(Text.translatable("minions.command.action.once", actionName))
|
||||
.setCallback(() -> executeOnce(actionType, player, minion))
|
||||
);
|
||||
gui.setSlot(3, new GuiElementBuilder()
|
||||
.setItem(Items.REPEATING_COMMAND_BLOCK)
|
||||
.setName(Text.translatable("minions.command.action.continuous", actionName))
|
||||
.setCallback(() -> executeContinuous(actionType, player, minion))
|
||||
);
|
||||
gui.setSlot(5, new GuiElementBuilder()
|
||||
.setItem(Items.CHAIN_COMMAND_BLOCK)
|
||||
.setName(Text.translatable("minions.command.action.interval", actionName))
|
||||
.setCallback(() -> executeInterval(actionType, player, minion))
|
||||
);
|
||||
gui.setSlot(4, new GuiElementBuilder()
|
||||
.setItem(Items.BARRIER)
|
||||
.setName(Text.translatable("minions.command.action.stop", actionName))
|
||||
.setCallback(() -> executeStop(actionType, player, minion))
|
||||
);
|
||||
gui.open();
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package io.github.skippyall.minions.module.command;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public interface Command extends CommandExecutor {
|
||||
Text getName();
|
||||
Text getDescription();
|
||||
Item getItemRepresentation();
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package io.github.skippyall.minions.module.command;
|
||||
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
|
||||
public interface CommandExecutor {
|
||||
void execute(ServerPlayerEntity player, MinionFakePlayer minion);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package io.github.skippyall.minions.module.command;
|
||||
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public class SimpleCommand implements Command {
|
||||
private final Text name;
|
||||
private final Text description;
|
||||
private final Item itemRepresentation;
|
||||
private final CommandExecutor executor;
|
||||
|
||||
public SimpleCommand(Text name, Text description, Item itemRepresentation, CommandExecutor executor) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.itemRepresentation = itemRepresentation;
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getItemRepresentation() {
|
||||
return itemRepresentation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(ServerPlayerEntity player, MinionFakePlayer minion) {
|
||||
executor.execute(player, minion);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package io.github.skippyall.minions.module.instruction;
|
||||
|
||||
import io.github.skippyall.minions.new_program.instruction.Instruction;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public record InstructionDisplay(Text name, Text description, Item itemRepresentation, Instruction instruction) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.github.skippyall.minions.new_module;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import eu.pb4.polymer.core.api.other.PolymerComponent;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.new_program.instruction.InstructionType;
|
||||
import net.minecraft.component.ComponentType;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.entry.RegistryEntry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record MinionModule(List<InstructionType<?>> instructions) {
|
||||
public static final Codec<MinionModule> CODEC = RecordCodecBuilder.create(instance ->
|
||||
instance.group(
|
||||
MinionRegistries.INSTRUCTION_TYPES.getCodec().listOf().fieldOf("instructions").forGetter(MinionModule::instructions)
|
||||
).apply(instance, MinionModule::new)
|
||||
);
|
||||
|
||||
public static final Codec<MinionModule> DATAPACK_CODEC = Codec.withAlternative(Identifier.CODEC.xmap(ModuleLoader.MODULES::get, ModuleLoader.ID_BY_MODULE::get), CODEC);
|
||||
|
||||
public static final ComponentType<MinionModule> COMPONENT_TYPE = ComponentType.<MinionModule>builder().codec(DATAPACK_CODEC).build();
|
||||
|
||||
public static final MinionModule EMPTY = new MinionModule(List.of());
|
||||
|
||||
public MinionModule(List<InstructionType<?>> instructions) {
|
||||
this.instructions = List.copyOf(instructions);
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
Registry.register(Registries.DATA_COMPONENT_TYPE, Identifier.of(Minions.MOD_ID, "minion_module"), COMPONENT_TYPE);
|
||||
PolymerComponent.registerDataComponent(COMPONENT_TYPE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package io.github.skippyall.minions.new_module;
|
||||
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
|
||||
import net.minecraft.resource.JsonDataLoader;
|
||||
import net.minecraft.resource.ResourceFinder;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ModuleLoader implements SimpleSynchronousResourceReloadListener {
|
||||
public static final HashMap<MinionModule, Identifier> ID_BY_MODULE = new HashMap<>();
|
||||
public static final Map<Identifier, MinionModule> MODULES = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public Identifier getFabricId() {
|
||||
return Identifier.of(Minions.MOD_ID, "module");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload(ResourceManager manager) {
|
||||
MODULES.clear();
|
||||
ID_BY_MODULE.clear();
|
||||
JsonDataLoader.load(manager, ResourceFinder.json("minion_module"), JsonOps.INSTANCE, MinionModule.CODEC, MODULES);
|
||||
MODULES.forEach((id, module) -> ID_BY_MODULE.put(module, id));
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package io.github.skippyall.minions.new_program;
|
||||
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.new_program.argument.Argument;
|
||||
import io.github.skippyall.minions.new_program.value.ValueType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ParameterList {
|
||||
Map<String, Argument<?>> parameters = new HashMap<>();
|
||||
|
||||
public <T> @Nullable T getValue(String name, ValueType<T> valueType, MinionFakePlayer minion) {
|
||||
Argument<T> argument = getArgument(name, valueType);
|
||||
return argument != null ? argument.resolve(minion) : null;
|
||||
}
|
||||
|
||||
public <T> @Nullable Argument<T> getArgument(String name, ValueType<T> valueType) {
|
||||
Argument<?> argument = parameters.get(name);
|
||||
if(argument != null && argument.getType() == valueType) {
|
||||
//noinspection unchecked
|
||||
return (Argument<T>) argument;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setArgument(String name, Argument<?> argument) {
|
||||
parameters.put(name, argument);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,34 @@
|
||||
package io.github.skippyall.minions.new_program.argument;
|
||||
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.new_program.value.ValueType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface Argument<T> {
|
||||
/**
|
||||
* An <code>Argument</code> can be supplied to an instruction with a matching parameter.
|
||||
* Its value is resolved at runtime and can vary between executions.
|
||||
* <code>Argument</code>s are created exclusively by <code>SpecificArgumentType</code>s.
|
||||
* @param <T> The type of the <code>Argument</code>'s value
|
||||
* @param <S> The <code>SpecificArgumentType</code>
|
||||
*/
|
||||
public interface Argument<T, S extends SpecificArgumentType<T, ? extends Argument<T, S>>> {
|
||||
T resolve(MinionFakePlayer minion);
|
||||
ValueType<T> getType();
|
||||
|
||||
default ValueType<T> getValueType() {
|
||||
return getType().getValueType();
|
||||
}
|
||||
|
||||
GuiDisplay getDisplay();
|
||||
|
||||
S getType();
|
||||
|
||||
default <U, A extends Argument<U, ? extends SpecificArgumentType<U,A>>> @Nullable A cast(ValueType<U> type) {
|
||||
if(getValueType() == type) {
|
||||
//noinspection unchecked
|
||||
return (A) this;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package io.github.skippyall.minions.new_program.argument;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ArgumentList {
|
||||
public static final Codec<ArgumentList> CODEC = Codec.unboundedMap(Codec.STRING, Arguments.ARGUMENT_CODEC)
|
||||
.xmap(ArgumentList::new, list -> list.arguments);
|
||||
|
||||
private final Map<String, Argument<?, ?>> arguments;
|
||||
|
||||
public ArgumentList() {
|
||||
arguments = new HashMap<>();
|
||||
}
|
||||
|
||||
public ArgumentList(Map<String, Argument<?,?>> arguments) {
|
||||
this.arguments = new HashMap<>(arguments);
|
||||
}
|
||||
|
||||
public <T> T getValue(Parameter<T> parameter, MinionFakePlayer minion) {
|
||||
Argument<T,?> argument = getArgument(parameter);
|
||||
return argument != null ? argument.resolve(minion) : null;
|
||||
}
|
||||
|
||||
public <T, A extends Argument<T, ? extends SpecificArgumentType<T,A>>> A getArgument(Parameter<T> parameter) {
|
||||
Argument<?, ?> argument = arguments.get(parameter.name());
|
||||
return argument == null ? null : argument.cast(parameter.type());
|
||||
}
|
||||
|
||||
public <T> void setArgument(Parameter<T> parameter, Argument<T,?> argument) {
|
||||
arguments.put(parameter.name(), argument);
|
||||
}
|
||||
|
||||
public boolean hasArgumentFor(Parameter<?> parameter) {
|
||||
return getArgument(parameter) != null;
|
||||
}
|
||||
|
||||
public boolean hasArgumentForAll(Collection<Parameter<?>> checkParameters) {
|
||||
for(Parameter<?> parameter : checkParameters) {
|
||||
if(!hasArgumentFor(parameter)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package io.github.skippyall.minions.new_program.argument;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.new_program.value.ValueType;
|
||||
import net.minecraft.registry.Registry;
|
||||
@@ -9,20 +11,30 @@ import net.minecraft.registry.SimpleRegistry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class Arguments {
|
||||
public static final Registry<GenericArgumentType> GENERIC_ARGUMENT_TYPE_REGISTRY = new SimpleRegistry<>(RegistryKey.ofRegistry(Identifier.of("minions", "generic_argument_type")), Lifecycle.stable());
|
||||
public static final Codec<SpecificArgumentType<?,?>> SPECIFIC_ARGUMENT_TYPE_CODEC = MinionRegistries.GENERIC_ARGUMENT_TYPE_REGISTRY.getCodec().dispatch(
|
||||
"type",
|
||||
SpecificArgumentType::getGenericArgumentType,
|
||||
generic ->
|
||||
MinionRegistries.VALUE_TYPES.getCodec().xmap(
|
||||
generic::createTypeSpecific,
|
||||
SpecificArgumentType::getValueType
|
||||
).fieldOf("valueType")
|
||||
);
|
||||
|
||||
public static final Codec<Argument<?,?>> ARGUMENT_CODEC = SPECIFIC_ARGUMENT_TYPE_CODEC.dispatch(Argument::getType, specific -> specific.getArgumentCodec().fieldOf("data"));
|
||||
|
||||
public static final GenericArgumentType VALUE_ARGUMENT = register(Identifier.of(Minions.MOD_ID, "value"), ValueArgumentType::new);
|
||||
|
||||
public static <V> SpecificArgumentType<V, ?> getArgumentType(Identifier id, ValueType<V> valueType) {
|
||||
GenericArgumentType generic = GENERIC_ARGUMENT_TYPE_REGISTRY.get(id);
|
||||
/*public static <V> SpecificArgumentType<V, ? extends Argument<V, ?>> getArgumentType(Identifier id, ValueType<V> valueType) {
|
||||
GenericArgumentType generic = MinionRegistries.GENERIC_ARGUMENT_TYPE_REGISTRY.get(id);
|
||||
if(generic != null) {
|
||||
return generic.createTypeSpecific(valueType);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}*/
|
||||
|
||||
public static GenericArgumentType register(Identifier id, GenericArgumentType argumentType) {
|
||||
return Registry.register(GENERIC_ARGUMENT_TYPE_REGISTRY, id, argumentType);
|
||||
return Registry.register(MinionRegistries.GENERIC_ARGUMENT_TYPE_REGISTRY, id, argumentType);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,5 +3,5 @@ package io.github.skippyall.minions.new_program.argument;
|
||||
import io.github.skippyall.minions.new_program.value.ValueType;
|
||||
|
||||
public interface GenericArgumentType {
|
||||
<V> SpecificArgumentType<V, ? extends Argument<V>> createTypeSpecific(ValueType<V> valueType);
|
||||
<V> SpecificArgumentType<V, ? extends Argument<V,?>> createTypeSpecific(ValueType<V> valueType);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package io.github.skippyall.minions.new_program.argument;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.new_program.value.ValueType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public record Parameter<T>(String name, ValueType<T> type) {
|
||||
public static final Codec<Parameter<?>> CODEC = RecordCodecBuilder.create(instance ->
|
||||
instance.group(
|
||||
Codec.STRING.fieldOf("name").forGetter(Parameter::name),
|
||||
MinionRegistries.VALUE_TYPES.getCodec().fieldOf("type").forGetter(Parameter::type)
|
||||
).apply(instance, Parameter::new));
|
||||
|
||||
public <U> @Nullable Parameter<U> cast(ValueType<U> type) {
|
||||
if(this.type == type) {
|
||||
//noinspection unchecked
|
||||
return (Parameter<U>) this;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-2
@@ -3,19 +3,28 @@ package io.github.skippyall.minions.new_program.argument;
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.new_program.value.ValueType;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public abstract class SpecificArgumentType<V, A extends Argument<V>> {
|
||||
/**
|
||||
* <code>SpecificArgumentType</code>s create <code>Argument</code>s of the specified <code>ValueType</code>.
|
||||
* They are also responsible for the serialization and user input of arguments.
|
||||
* @param <V> The value type of the <code>Argument</code>s to create
|
||||
* @param <A> The type of the <code>Argument</code>s themselves
|
||||
*/
|
||||
public abstract class SpecificArgumentType<V, A extends Argument<V, ? extends SpecificArgumentType<V, A>>> {
|
||||
protected final ValueType<V> valueType;
|
||||
|
||||
public SpecificArgumentType(ValueType<V> valueType) {
|
||||
this.valueType = valueType;
|
||||
}
|
||||
|
||||
public abstract GenericArgumentType getGenericArgumentType();
|
||||
|
||||
public abstract Codec<A> getArgumentCodec();
|
||||
|
||||
public abstract CompletableFuture<A> openArgumentDialog(ServerPlayerEntity player, A previousArgument);
|
||||
public abstract CompletableFuture<A> openArgumentDialog(ServerPlayerEntity player, @Nullable A previousArgument);
|
||||
|
||||
public ValueType<V> getValueType() {
|
||||
return valueType;
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
package io.github.skippyall.minions.new_program.argument;
|
||||
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.new_program.value.ValueType;
|
||||
|
||||
public class ValueArgument<T> implements Argument<T> {
|
||||
private final ValueType<T> valueType;
|
||||
/**
|
||||
* An argument that always resolves to a fixed value
|
||||
*/
|
||||
public class ValueArgument<T> implements Argument<T, ValueArgumentType<T>> {
|
||||
private final ValueArgumentType<T> type;
|
||||
private final T value;
|
||||
|
||||
public ValueArgument(ValueType<T> valueType, T value) {
|
||||
this.valueType = valueType;
|
||||
public ValueArgument(ValueArgumentType<T> valueType, T value) {
|
||||
this.type = valueType;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@@ -22,7 +26,12 @@ public class ValueArgument<T> implements Argument<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueType<T> getType() {
|
||||
return valueType;
|
||||
public GuiDisplay getDisplay() {
|
||||
return getValueType().display();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueArgumentType<T> getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
+13
-4
@@ -3,6 +3,7 @@ package io.github.skippyall.minions.new_program.argument;
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.new_program.value.ValueType;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@@ -12,12 +13,20 @@ public class ValueArgumentType<V> extends SpecificArgumentType<V, ValueArgument<
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec<ValueArgument<V>> getArgumentCodec() {
|
||||
return valueType.getCodec().xmap(value -> new ValueArgument<>(valueType, value), ValueArgument::getValue);
|
||||
public GenericArgumentType getGenericArgumentType() {
|
||||
return Arguments.VALUE_ARGUMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<ValueArgument<V>> openArgumentDialog(ServerPlayerEntity player, ValueArgument<V> previousArgument) {
|
||||
return valueType.openValueDialog(player, previousArgument.getValue()).thenApply(value -> new ValueArgument<>(valueType, value));
|
||||
public Codec<ValueArgument<V>> getArgumentCodec() {
|
||||
return valueType.codec().xmap(value -> new ValueArgument<>(this, value), ValueArgument::getValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<ValueArgument<V>> openArgumentDialog(ServerPlayerEntity player, @Nullable ValueArgument<V> previousArgument) {
|
||||
return valueType.openValueDialog(
|
||||
player,
|
||||
previousArgument != null ? previousArgument.getValue() : valueType.defaultValue()
|
||||
).thenApply(value -> new ValueArgument<>(this, value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package io.github.skippyall.minions.new_program.instruction;
|
||||
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.new_program.ParameterList;
|
||||
import io.github.skippyall.minions.program.variables.Type;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface Instruction {
|
||||
List<Type<?>> getParameterTypes();
|
||||
|
||||
Type<?> getReturnType();
|
||||
|
||||
InstructionRun run(MinionFakePlayer minion, ParameterList params);
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package io.github.skippyall.minions.new_program.instruction;
|
||||
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.new_program.argument.ArgumentList;
|
||||
import net.minecraft.storage.ReadView;
|
||||
import net.minecraft.storage.WriteView;
|
||||
|
||||
/**
|
||||
* Responsible for executing instructions.
|
||||
* When an instruction is executed:
|
||||
* <li>A new instance is created using the factory</li>
|
||||
* <li>{@link InstructionExecution#readArguments(ArgumentList, MinionFakePlayer) readFromParameters} is called</li>
|
||||
* <li>{@link InstructionExecution#start(MinionFakePlayer) start} is called</li>
|
||||
* @param <R>
|
||||
*/
|
||||
public interface InstructionExecution<R> {
|
||||
/**
|
||||
* Starts the execution.
|
||||
* @param minion
|
||||
*/
|
||||
default void start(MinionFakePlayer minion) {}
|
||||
|
||||
/**
|
||||
* Continues the execution of this instruction.
|
||||
* Called every tick while executing the instruction.
|
||||
* @param minion
|
||||
*/
|
||||
default void tick(MinionFakePlayer minion) {}
|
||||
|
||||
/**
|
||||
* Called every tick to determine if the execution of this instruction should be stopped.
|
||||
* Shouldn't
|
||||
* @param minion The minion executing the instruction
|
||||
* @return <code>true</code> if the instruction is done, <code>false</code> otherwise.
|
||||
*/
|
||||
boolean isDone(MinionFakePlayer minion);
|
||||
|
||||
/**
|
||||
* Stops this execution. This is guaranteed to be called if {@link InstructionExecution#isDone(MinionFakePlayer) isDone}
|
||||
* returns true after ticking the execution, but it may also be called before that.
|
||||
* In this case, the return value is ignored unless this is a
|
||||
* {@link io.github.skippyall.minions.new_program.instruction.execution.ContinuousInstructionExecution ContinuousInstructionExecution}.</br>
|
||||
* This should undo changes to the minion unless they are supposed to be permanent.
|
||||
*
|
||||
* @param minion The minion that was executing this instruction.
|
||||
* @return The return value of the instruction
|
||||
*/
|
||||
R stop(MinionFakePlayer minion);
|
||||
|
||||
/**
|
||||
* Initializes the execution with its arguments.
|
||||
* @param arguments The arguments to initialize the execution
|
||||
* @param minion The minion should be used to resolve the arguments
|
||||
*/
|
||||
void readArguments(ArgumentList arguments, MinionFakePlayer minion);
|
||||
|
||||
/**
|
||||
* Saves the execution, e.g. when the server is closed.
|
||||
*/
|
||||
void save(WriteView view, MinionFakePlayer minion);
|
||||
|
||||
/**
|
||||
* Loads the execution, e.g. when the server is started.
|
||||
*/
|
||||
void load(ReadView view, MinionFakePlayer minion);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package io.github.skippyall.minions.new_program.instruction;
|
||||
|
||||
public interface InstructionRun {
|
||||
default void tick() {}
|
||||
|
||||
default boolean isDone() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package io.github.skippyall.minions.new_program.instruction;
|
||||
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.new_program.argument.Parameter;
|
||||
import io.github.skippyall.minions.new_program.argument.ArgumentList;
|
||||
import io.github.skippyall.minions.new_program.value.ValueType;
|
||||
import net.minecraft.storage.ReadView;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class InstructionType<R> {
|
||||
private final GuiDisplay display;
|
||||
private final Collection<Parameter<?>> parameters;
|
||||
private final ValueType<R> returnType;
|
||||
private final Supplier<InstructionExecution<R>> executionFactory;
|
||||
|
||||
private InstructionType(GuiDisplay display, Supplier<InstructionExecution<R>> executionFactory, ValueType<R> returnType, Collection<Parameter<?>> parameters) {
|
||||
this.display = display;
|
||||
this.parameters = parameters;
|
||||
this.returnType = returnType;
|
||||
this.executionFactory = executionFactory;
|
||||
}
|
||||
|
||||
public static <R> InstructionType<R> create(GuiDisplay display, Supplier<InstructionExecution<R>> executionFactory, ValueType<R> returnType, Collection<Parameter<?>> parameters) {
|
||||
return new InstructionType<>(display, executionFactory, returnType, List.copyOf(parameters));
|
||||
}
|
||||
|
||||
public static <R> InstructionType<R> create(GuiDisplay display, Supplier<InstructionExecution<R>> executionFactory, ValueType<R> returnType, Parameter<?>... parameters) {
|
||||
return new InstructionType<>(display, executionFactory, returnType, List.of(parameters));
|
||||
}
|
||||
|
||||
public Collection<Parameter<?>> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public ValueType<R> getReturnType() {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
public GuiDisplay getDisplay() {
|
||||
return display;
|
||||
}
|
||||
|
||||
public InstructionExecution<R> createExecution(ArgumentList parameters, MinionFakePlayer minion) {
|
||||
InstructionExecution<R> execution = executionFactory.get();
|
||||
execution.readArguments(parameters, minion);
|
||||
return execution;
|
||||
}
|
||||
|
||||
public InstructionExecution<R> loadExecution(ReadView view, MinionFakePlayer minion) {
|
||||
InstructionExecution<R> execution = executionFactory.get();
|
||||
execution.load(view, minion);
|
||||
return execution;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package io.github.skippyall.minions.new_program.instruction;
|
||||
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import io.github.skippyall.minions.new_program.instruction.execution.WalkExecution;
|
||||
import io.github.skippyall.minions.new_program.argument.Parameter;
|
||||
import io.github.skippyall.minions.new_program.value.ValueType;
|
||||
import io.github.skippyall.minions.new_program.value.ValueTypes;
|
||||
import io.github.skippyall.minions.util.ModelIdUtil;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class Instructions {
|
||||
public static final InstructionType<Void> WALK = register(
|
||||
"walk",
|
||||
base -> new GuiDisplay.ModelBased(ModelIdUtil.getItemModelId(Items.IRON_BOOTS), base, true),
|
||||
WalkExecution::new,
|
||||
ValueTypes.VOID,
|
||||
WalkExecution.blocksToMoveParam
|
||||
);
|
||||
|
||||
public static final InstructionType<Void> ATTACK = register(
|
||||
"attack",
|
||||
base -> new GuiDisplay.ModelBased(ModelIdUtil.getItemModelId(Items.IRON_PICKAXE), base, true),
|
||||
WalkExecution::new,
|
||||
ValueTypes.VOID,
|
||||
WalkExecution.blocksToMoveParam
|
||||
);
|
||||
|
||||
private static <R> InstructionType<R> register(String id, Function<String, GuiDisplay> displayFunction, Supplier<InstructionExecution<R>> factory, ValueType<R> returnType, Parameter<?>... parameters) {
|
||||
Identifier identifier = Identifier.of(Minions.MOD_ID, id);
|
||||
return Registry.register(MinionRegistries.INSTRUCTION_TYPES, identifier, InstructionType.create(displayFunction.apply(identifier.toTranslationKey("instruction_type")), factory, returnType, parameters));
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package io.github.skippyall.minions.new_program.instruction.execution;
|
||||
|
||||
import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.new_program.argument.ArgumentList;
|
||||
import net.minecraft.storage.ReadView;
|
||||
import net.minecraft.storage.WriteView;
|
||||
|
||||
public class ActionExecution implements ContinuousInstructionExecution<Void> {
|
||||
private final EntityPlayerActionPack.ActionType action;
|
||||
|
||||
public ActionExecution(EntityPlayerActionPack.ActionType action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(MinionFakePlayer minion) {
|
||||
minion.getMinionActionPack().start(action, EntityPlayerActionPack.Action.continuous());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void stop(MinionFakePlayer minion) {
|
||||
minion.getMinionActionPack().stop(action);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readArguments(ArgumentList parameters, MinionFakePlayer minion) {}
|
||||
|
||||
@Override
|
||||
public void save(WriteView view, MinionFakePlayer minion) {}
|
||||
|
||||
@Override
|
||||
public void load(ReadView view, MinionFakePlayer minion) {}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package io.github.skippyall.minions.new_program.instruction.execution;
|
||||
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.new_program.instruction.InstructionExecution;
|
||||
|
||||
public interface ContinuousInstructionExecution<R> extends InstructionExecution<R> {
|
||||
@Override
|
||||
default boolean isDone(MinionFakePlayer minion) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package io.github.skippyall.minions.new_program.instruction.execution;
|
||||
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.new_program.instruction.InstructionExecution;
|
||||
import net.minecraft.storage.ReadView;
|
||||
import net.minecraft.storage.WriteView;
|
||||
|
||||
/**
|
||||
* An <code>InstructionExecution</code> that takes a predefined time to execute.
|
||||
* The timer must be set with <code>setTimer</code> when reading from parameters.
|
||||
* Saving and loading of the timer is automatic if the super method is called by the subclass.
|
||||
*/
|
||||
public abstract class TimedInstructionExecution<T> implements InstructionExecution<T> {
|
||||
int timer;
|
||||
|
||||
public int getTimer() {
|
||||
return timer;
|
||||
}
|
||||
|
||||
protected void setTimer(int timer) {
|
||||
this.timer = timer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(MinionFakePlayer minion) {
|
||||
timer--;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone(MinionFakePlayer minion) {
|
||||
return timer > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(WriteView view, MinionFakePlayer minion) {
|
||||
view.putInt("timer", timer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(ReadView view, MinionFakePlayer minion) {
|
||||
timer = view.getInt("timer", 0);
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
package io.github.skippyall.minions.new_program.instruction.execution;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.new_program.argument.ArgumentList;
|
||||
import io.github.skippyall.minions.new_program.instruction.InstructionExecution;
|
||||
import net.minecraft.storage.ReadView;
|
||||
import net.minecraft.storage.WriteView;
|
||||
import net.minecraft.util.StringIdentifiable;
|
||||
|
||||
public class TurnExecution implements InstructionExecution<Void> {
|
||||
|
||||
|
||||
@Override
|
||||
public void start(MinionFakePlayer minion) {
|
||||
InstructionExecution.super.start(minion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone(MinionFakePlayer minion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void stop(MinionFakePlayer minion) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readArguments(ArgumentList arguments, MinionFakePlayer minion) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(WriteView view, MinionFakePlayer minion) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(ReadView view, MinionFakePlayer minion) {
|
||||
|
||||
}
|
||||
|
||||
public enum TurnDirection implements StringIdentifiable {
|
||||
LEFT("left", -1, 0),
|
||||
UP("up", 0, -1),
|
||||
RIGHT("right", 1, 0),
|
||||
DOWN("down", 0, 1);
|
||||
|
||||
public static final Codec<TurnDirection> CODEC = StringIdentifiable.createCodec(TurnDirection::values);
|
||||
|
||||
public final String name;
|
||||
public final int xFactor;
|
||||
public final int yFactor;
|
||||
|
||||
TurnDirection(String name, int xFactor, int yFactor) {
|
||||
this.xFactor = xFactor;
|
||||
this.yFactor = yFactor;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package io.github.skippyall.minions.new_program.instruction.execution;
|
||||
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.new_program.instruction.InstructionExecution;
|
||||
import io.github.skippyall.minions.new_program.argument.Parameter;
|
||||
import io.github.skippyall.minions.new_program.argument.ArgumentList;
|
||||
import io.github.skippyall.minions.new_program.value.ValueTypes;
|
||||
import net.minecraft.entity.MovementType;
|
||||
import net.minecraft.storage.ReadView;
|
||||
import net.minecraft.storage.WriteView;
|
||||
|
||||
public class WalkExecution implements InstructionExecution<Void> {
|
||||
public static final Parameter<Float> blocksToMoveParam = new Parameter<>("blocksToMove", ValueTypes.FLOAT);
|
||||
private final float ACCURACY = 1F / 32F;
|
||||
|
||||
private float totalBlocksToMove;
|
||||
private float blocksMoved;
|
||||
|
||||
@Override
|
||||
public void tick(MinionFakePlayer minion) {
|
||||
float speed = Math.min(minion.getMovementSpeed(), totalBlocksToMove - blocksMoved);
|
||||
minion.move(MovementType.SELF, minion.getHorizontalFacing().getDoubleVector().normalize().multiply(speed));
|
||||
blocksMoved += speed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone(MinionFakePlayer minion) {
|
||||
return totalBlocksToMove - blocksMoved < ACCURACY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void stop(MinionFakePlayer minion) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readArguments(ArgumentList parameters, MinionFakePlayer minion) {
|
||||
totalBlocksToMove = parameters.getValue(blocksToMoveParam, minion);
|
||||
blocksMoved = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(WriteView view, MinionFakePlayer minion) {
|
||||
view.putFloat("totalBlocksToMove", totalBlocksToMove);
|
||||
view.putFloat("blocksMoved", blocksMoved);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(ReadView view, MinionFakePlayer minion) {
|
||||
totalBlocksToMove = view.getFloat("totalBlocksToMove", 0F);
|
||||
blocksMoved = view.getFloat("blocksMoved", 0F);
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package io.github.skippyall.minions.new_program.value;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.input.TextInput;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class FloatValueType implements ValueType<Float> {
|
||||
@Override
|
||||
public Codec<Float> getCodec() {
|
||||
return Codec.FLOAT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Float> openValueDialog(ServerPlayerEntity player, Float previousValue) {
|
||||
return TextInput.inputFloat(player, Text.literal("Please enter a decimal number."), previousValue.toString());
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package io.github.skippyall.minions.new_program.value;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.input.TextInput;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class IntegerValueType implements ValueType<Integer> {
|
||||
@Override
|
||||
public Codec<Integer> getCodec() {
|
||||
return Codec.INT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Integer> openValueDialog(ServerPlayerEntity player, Integer previousValue) {
|
||||
return TextInput.inputInt(player, Text.literal("Please enter an integer number."), previousValue.toString());
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
package io.github.skippyall.minions.new_program.value;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public interface ValueType<T> {
|
||||
Codec<T> getCodec();
|
||||
|
||||
CompletableFuture<T> openValueDialog(ServerPlayerEntity player, T previousValue);
|
||||
public record ValueType<T>(Codec<T> codec, GuiDisplay display, T defaultValue, BiFunction<ServerPlayerEntity, T, CompletableFuture<T>> valueDialogOpener) {
|
||||
public CompletableFuture<T> openValueDialog(ServerPlayerEntity player, T previousValue) {
|
||||
return valueDialogOpener.apply(player, previousValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package io.github.skippyall.minions.new_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.GuiDisplay;
|
||||
import io.github.skippyall.minions.input.TextInput;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
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<Integer> INTEGER = registerSimple(
|
||||
"integer",
|
||||
Codec.INT,
|
||||
key -> new GuiDisplay.ModelBased(Items.NETHERITE_SCRAP, key, true),
|
||||
0,
|
||||
(player, oldValue) -> TextInput.inputInt(
|
||||
player,
|
||||
Text.literal("Integer"),
|
||||
String.valueOf(oldValue)
|
||||
)
|
||||
);
|
||||
|
||||
public static ValueType<Float> FLOAT = registerSimple(
|
||||
"float",
|
||||
Codec.FLOAT,
|
||||
key -> new GuiDisplay.ModelBased(Items.BAMBOO_RAFT, key, true),
|
||||
0F,
|
||||
(player, oldValue) -> TextInput.inputFloat(
|
||||
player,
|
||||
Text.literal("Number"),
|
||||
String.valueOf(oldValue)
|
||||
)
|
||||
);
|
||||
|
||||
public static ValueType<String> STRING = registerSimple(
|
||||
"string",
|
||||
Codec.STRING,
|
||||
key -> new GuiDisplay.ModelBased(Items.STRING, key, true),
|
||||
"",
|
||||
((player, oldValue) -> TextInput.inputString(
|
||||
player,
|
||||
Text.literal("Text"),
|
||||
oldValue)
|
||||
)
|
||||
);
|
||||
|
||||
public static ValueType<Void> VOID = registerSimple(
|
||||
"void",
|
||||
Codec.unit(null),
|
||||
key -> new GuiDisplay.ModelBased(Items.BARRIER, key, false),
|
||||
null,
|
||||
(player, oldValue) -> CompletableFuture.completedFuture(null)
|
||||
);
|
||||
|
||||
private static <T> ValueType<T> registerSimple(String id, Codec<T> codec, Function<String, GuiDisplay> displayFunction, T defaultValue, BiFunction<ServerPlayerEntity, T, CompletableFuture<T>> valueDialogOpener) {
|
||||
Identifier identifier = Identifier.of(Minions.MOD_ID, id);
|
||||
return Registry.register(
|
||||
MinionRegistries.VALUE_TYPES,
|
||||
identifier,
|
||||
new ValueType<>(
|
||||
codec,
|
||||
displayFunction.apply(identifier.toTranslationKey("value_type")),
|
||||
defaultValue,
|
||||
valueDialogOpener
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public static void register() {}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package io.github.skippyall.minions.program.argument;
|
||||
|
||||
import io.github.skippyall.minions.program.runtime.ProgramRuntime;
|
||||
import io.github.skippyall.minions.program.variables.Type;
|
||||
|
||||
public interface Arg<T> {
|
||||
T resolve(ProgramRuntime runtime);
|
||||
Type<T> getType();
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package io.github.skippyall.minions.program.argument;
|
||||
|
||||
import io.github.skippyall.minions.program.runtime.ProgramRuntime;
|
||||
import io.github.skippyall.minions.program.tuple.Tuple;
|
||||
import io.github.skippyall.minions.program.tuple.Tuple0;
|
||||
|
||||
public class ArgUtils {
|
||||
public static Tuple resolveArgs(Tuple args, ProgramRuntime runtime) {
|
||||
Tuple tuple = new Tuple0();
|
||||
for(Object object : args) {
|
||||
Arg<?> arg =(Arg<?>) object;
|
||||
tuple = tuple.add(arg.getType().cast(arg.resolve(runtime)));
|
||||
}
|
||||
return tuple;
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package io.github.skippyall.minions.program.block;
|
||||
|
||||
import io.github.skippyall.minions.program.argument.Arg;
|
||||
import io.github.skippyall.minions.program.runtime.ProgramRuntime;
|
||||
import io.github.skippyall.minions.program.statement.Statement;
|
||||
import io.github.skippyall.minions.program.tuple.Tuple;
|
||||
import io.github.skippyall.minions.program.variables.Type;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
|
||||
public abstract class CodeBlock<R, A extends Tuple> {
|
||||
private String name;
|
||||
private final List<Type<?>> arguments;
|
||||
private final Type<?> returnType;
|
||||
|
||||
public CodeBlock(String name, List<Type<?>> arguments, Type<?> returnType) {
|
||||
this.arguments = arguments;
|
||||
this.returnType = returnType;
|
||||
}
|
||||
|
||||
protected abstract R execute(ProgramRuntime runtime, A args, Statement<R,A>.Run run);
|
||||
|
||||
public boolean fits(Arg<?> arg, int slot) {
|
||||
return arguments.get(slot) == arg.getType();
|
||||
}
|
||||
|
||||
public void start(ProgramRuntime runtime, A args, Statement<R,A>.Run run) {
|
||||
ForkJoinPool.commonPool().execute(() -> {
|
||||
R result = execute(runtime, args, run);
|
||||
run.afterRun(result);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package io.github.skippyall.minions.program.block;
|
||||
|
||||
public class CodeBlocks {
|
||||
public static final GoBlock GO = new GoBlock();
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package io.github.skippyall.minions.program.block;
|
||||
|
||||
import io.github.skippyall.minions.program.variables.Type;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class CodeContainingCodeBlock extends CodeBlock{
|
||||
public CodeContainingCodeBlock(String name, List<Type> arguments, Type returnType) {
|
||||
super(name, arguments, returnType);
|
||||
}
|
||||
|
||||
protected void executeBlocks() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package io.github.skippyall.minions.program.block;
|
||||
|
||||
import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.program.runtime.MinionRuntime;
|
||||
import io.github.skippyall.minions.program.runtime.ProgramRuntime;
|
||||
import io.github.skippyall.minions.program.statement.Statement;
|
||||
import io.github.skippyall.minions.program.tuple.Tuple2;
|
||||
import io.github.skippyall.minions.program.variables.Types;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GoBlock extends CodeBlock<Void, Tuple2<Float, Float>> {
|
||||
public GoBlock() {
|
||||
super("move", List.of(Types.FLOAT, Types.FLOAT), Types.VOID);
|
||||
}
|
||||
|
||||
public Void execute(ProgramRuntime runtime, Tuple2<Float, Float> args, Statement<Void, Tuple2<Float, Float>>.Run run) {
|
||||
if(runtime instanceof MinionRuntime minionRuntime) {
|
||||
MinionFakePlayer minion = minionRuntime.getMinion();
|
||||
EntityPlayerActionPack action = ((ServerPlayerInterface) minion).minions$getActionPack();
|
||||
minion.moveForward(args.v0());
|
||||
minion.moveSideways(args.v1());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package io.github.skippyall.minions.program.block;
|
||||
|
||||
import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.program.runtime.MinionRuntime;
|
||||
import io.github.skippyall.minions.program.runtime.ProgramRuntime;
|
||||
import io.github.skippyall.minions.program.statement.Statement;
|
||||
import io.github.skippyall.minions.program.tuple.Tuple0;
|
||||
import io.github.skippyall.minions.program.variables.Types;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UseBlock extends CodeBlock<Void, Tuple0>{
|
||||
public UseBlock(String name) {
|
||||
super("use", List.of(), Types.VOID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void execute(ProgramRuntime runtime, Tuple0 args, Statement<Void,Tuple0>.Run run) {
|
||||
if(runtime instanceof MinionRuntime minionRuntime) {
|
||||
MinionFakePlayer minion = minionRuntime.getMinion();
|
||||
minion.getMinionActionPack().start(EntityPlayerActionPack.ActionType.USE, EntityPlayerActionPack.Action.once());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package io.github.skippyall.minions.program.runtime;
|
||||
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
|
||||
public class MinionRuntime extends ProgramRuntime {
|
||||
private final MinionFakePlayer minion;
|
||||
|
||||
public MinionRuntime(MinionFakePlayer minion) {
|
||||
this.minion = minion;
|
||||
}
|
||||
|
||||
public MinionFakePlayer getMinion() {
|
||||
return minion;
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package io.github.skippyall.minions.program.runtime;
|
||||
|
||||
import io.github.skippyall.minions.program.statement.StatementList;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class ProgramRuntime {
|
||||
private final Map<String, Object> variables = new HashMap<>();
|
||||
private StatementList statements;
|
||||
private StatementList.Run run;
|
||||
|
||||
public ProgramRuntime() {
|
||||
this(new StatementList());
|
||||
}
|
||||
|
||||
public ProgramRuntime(StatementList statements) {
|
||||
this.statements = statements;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
run = statements.start(this);
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if(run != null) {
|
||||
run.tick();
|
||||
}
|
||||
}
|
||||
|
||||
public StatementList getStatementList() {
|
||||
return statements;
|
||||
}
|
||||
|
||||
public Object getVariable(String name) {
|
||||
return variables.get(name);
|
||||
}
|
||||
|
||||
public void setVariable(String name, Object value) {
|
||||
variables.put(name, value);
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package io.github.skippyall.minions.program.statement;
|
||||
|
||||
import io.github.skippyall.minions.program.argument.ArgUtils;
|
||||
import io.github.skippyall.minions.program.block.CodeBlock;
|
||||
import io.github.skippyall.minions.program.runtime.ProgramRuntime;
|
||||
import io.github.skippyall.minions.program.tuple.Tuple;
|
||||
import io.github.skippyall.minions.program.variables.ValueStorage;
|
||||
|
||||
public record Statement<R,A extends Tuple>(CodeBlock<R,A> codeBlock, A args, ValueStorage<R> valueStorage) {
|
||||
@SuppressWarnings("unchecked")
|
||||
public Run start(ProgramRuntime runtime) {
|
||||
Run run = new Run(runtime);
|
||||
codeBlock.start(runtime, (A) ArgUtils.resolveArgs(args, runtime), run);
|
||||
return run;
|
||||
}
|
||||
|
||||
public class Run {
|
||||
private boolean running = false;
|
||||
private boolean waiting = false;
|
||||
private boolean afterRun = false;
|
||||
private R cachedResult;
|
||||
private int ticksRunning = 0;
|
||||
private int ticksLeft = 0;
|
||||
|
||||
private final ProgramRuntime runtime;
|
||||
|
||||
Run(ProgramRuntime runtime) {
|
||||
this.runtime = runtime;
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return !running;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if(running) {
|
||||
ticksRunning ++;
|
||||
ticksLeft --;
|
||||
if(ticksLeft == 0 && waiting && afterRun) {
|
||||
complete(cachedResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void afterRun(R result) {
|
||||
afterRun = true;
|
||||
if(ticksLeft == 0) {
|
||||
complete(result);
|
||||
}
|
||||
}
|
||||
|
||||
private void complete(R result) {
|
||||
if(valueStorage != null) {
|
||||
valueStorage.storeValue(result, runtime);
|
||||
}
|
||||
running = false;
|
||||
waiting = false;
|
||||
cachedResult = null;
|
||||
ticksRunning = 0;
|
||||
ticksLeft = 0;
|
||||
}
|
||||
|
||||
public void completeAfter(int ticks, R value) {
|
||||
waiting = true;
|
||||
ticksLeft = ticks;
|
||||
cachedResult = value;
|
||||
}
|
||||
|
||||
public int getTicksRunning() {
|
||||
return ticksRunning;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package io.github.skippyall.minions.program.statement;
|
||||
|
||||
import io.github.skippyall.minions.program.runtime.ProgramRuntime;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class StatementList {
|
||||
private final List<Statement<?,?>> statements;
|
||||
|
||||
public StatementList() {
|
||||
this.statements = List.of();
|
||||
}
|
||||
|
||||
public StatementList(List<Statement<?,?>> statements) {
|
||||
this.statements = List.copyOf(statements);
|
||||
}
|
||||
|
||||
public Run start(ProgramRuntime runtime) {
|
||||
return new Run(runtime);
|
||||
}
|
||||
|
||||
public class Run {
|
||||
final ProgramRuntime runtime;
|
||||
final Iterator<Statement<?,?>> iterator;
|
||||
Statement<?,?>.Run run;
|
||||
|
||||
public Run(ProgramRuntime runtime) {
|
||||
this.runtime = runtime;
|
||||
iterator = statements.iterator();
|
||||
startNext();
|
||||
}
|
||||
|
||||
private boolean startNext() {
|
||||
if(iterator.hasNext()) {
|
||||
run = iterator.next().start(runtime);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
run.tick();
|
||||
if(run.isDone()){
|
||||
startNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package io.github.skippyall.minions.program.tuple;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public interface Tuple extends Iterable<Object>{
|
||||
<T> Tuple add(T value);
|
||||
Tuple removeLast();
|
||||
List<Object> getValueList();
|
||||
int size();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
default Iterator<Object> iterator() {
|
||||
return getValueList().iterator();
|
||||
}
|
||||
|
||||
static Tuple ofList(List<?> list) {
|
||||
return switch (list.size()) {
|
||||
case 0 -> new Tuple0();
|
||||
case 1 -> new Tuple1<Object>(list.get(0));
|
||||
case 2 -> new Tuple2<Object, Object>(list.get(0), list.get(1));
|
||||
case 3 -> new Tuple3<Object, Object, Object>(list.get(0), list.get(1), list.get(2));
|
||||
default -> throw new UnsupportedOperationException();
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package io.github.skippyall.minions.program.tuple;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record Tuple0() implements Tuple{
|
||||
@Override
|
||||
public <T> Tuple add(T value) {
|
||||
return new Tuple1<>(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tuple removeLast() {
|
||||
throw new UnsupportedOperationException("Cannot remove element from length 0 tuple.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getValueList() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package io.github.skippyall.minions.program.tuple;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record Tuple1<T0>(T0 v0) implements Tuple{
|
||||
@Override
|
||||
public <T> Tuple add(T value) {
|
||||
return new Tuple2<>(v0, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tuple removeLast() {
|
||||
return new Tuple0();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getValueList() {
|
||||
return List.of(v0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package io.github.skippyall.minions.program.tuple;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record Tuple2<T0, T1>(T0 v0, T1 v1) implements Tuple {
|
||||
@Override
|
||||
public <T> Tuple add(T value) {
|
||||
return new Tuple3<>(v0, v1, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tuple removeLast() {
|
||||
return new Tuple1<>(v0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getValueList() {
|
||||
return List.of(v0, v1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package io.github.skippyall.minions.program.tuple;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record Tuple3<T0, T1, T2>(T0 v0, T1 v1, T2 v2) implements Tuple {
|
||||
@Override
|
||||
public <T> Tuple add(T value) {
|
||||
return new Tuple4<>(v0, v1, v2, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tuple removeLast() {
|
||||
return new Tuple2<>(v0, v1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getValueList() {
|
||||
return List.of(v0, v1, v2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package io.github.skippyall.minions.program.tuple;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record Tuple4<T0, T1, T2, T3, T4>(T0 v0, T1 v1, T2 v2, T3 v3) implements Tuple {
|
||||
@Override
|
||||
public <T> Tuple add(T value) {
|
||||
return new Tuple5<>(v0, v1, v2, v3, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tuple removeLast() {
|
||||
return new Tuple3<>(v0, v1, v2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getValueList() {
|
||||
return List.of(v0, v1, v2, v3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package io.github.skippyall.minions.program.tuple;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record Tuple5<T0, T1, T2, T3, T4>(T0 v0, T1 v1, T2 v2, T3 v3, T4 v4) implements Tuple {
|
||||
@Override
|
||||
public <T> Tuple add(T value) {
|
||||
throw new UnsupportedOperationException("Cannot add element to length 5 tuple.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tuple removeLast() {
|
||||
return new Tuple4<>(v0, v1, v2, v3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getValueList() {
|
||||
return List.of(v0, v1, v2, v3, v4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
package io.github.skippyall.minions.program.variables;
|
||||
|
||||
public class FloatType extends Type<Float>{
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
package io.github.skippyall.minions.program.variables;
|
||||
|
||||
public class IntegerType extends Type<Integer>{
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package io.github.skippyall.minions.program.variables;
|
||||
|
||||
public abstract class Type<T> {
|
||||
@SuppressWarnings("unchecked")
|
||||
public T cast(Object object) throws ClassCastException {
|
||||
return (T) object;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package io.github.skippyall.minions.program.variables;
|
||||
|
||||
public class Types {
|
||||
public static final IntegerType INTEGER = new IntegerType();
|
||||
public static final FloatType FLOAT = new FloatType();
|
||||
public static final Type<Void> VOID = new Type<>() {};
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package io.github.skippyall.minions.program.variables;
|
||||
|
||||
import io.github.skippyall.minions.program.runtime.ProgramRuntime;
|
||||
|
||||
public interface ValueStorage<T> {
|
||||
void storeValue(T value, ProgramRuntime runtime);
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package io.github.skippyall.minions.program.variables;
|
||||
|
||||
import io.github.skippyall.minions.program.argument.Arg;
|
||||
import io.github.skippyall.minions.program.runtime.ProgramRuntime;
|
||||
|
||||
public class Variable<T> implements Arg<T>, ValueStorage<T> {
|
||||
private final Type<T> type;
|
||||
private final String name;
|
||||
|
||||
public Variable(Type<T> type, String name) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T resolve(ProgramRuntime runtime) {
|
||||
return type.cast(runtime.getVariable(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type<T> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeValue(T value, ProgramRuntime runtime) {
|
||||
runtime.setVariable(name, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package io.github.skippyall.minions.util;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class ModelIdUtil {
|
||||
public static Identifier getItemModelId(Item item) {
|
||||
Identifier identifier = Registries.ITEM.getId(item);
|
||||
return identifier.withPrefixedPath("item/");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package io.github.skippyall.minions.util;
|
||||
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class TranslationUtil {
|
||||
public static <T> String getTranslationKey(T object, Registry<T> registry, String defaultKey) {
|
||||
return getTranslationKey(object, registry, registry.getKey().getValue().getPath(), defaultKey);
|
||||
}
|
||||
|
||||
public static <T> String getTranslationKey(T object, Registry<T> registry, String prefix, String defaultKey) {
|
||||
if(object == null) {
|
||||
return defaultKey;
|
||||
}
|
||||
|
||||
Identifier id = registry.getId(object);
|
||||
if(id == null) {
|
||||
return defaultKey;
|
||||
}
|
||||
return id.toTranslationKey(prefix);
|
||||
}
|
||||
|
||||
public static <T> String getTranslationKey(T object, Registry<T> registry) {
|
||||
return getTranslationKey(object, registry, "minions.generic.unknown");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user