diff --git a/src/main/java/io/github/skippyall/minions/Minions.java b/src/main/java/io/github/skippyall/minions/Minions.java index 88c9b90..71ba195 100644 --- a/src/main/java/io/github/skippyall/minions/Minions.java +++ b/src/main/java/io/github/skippyall/minions/Minions.java @@ -5,9 +5,12 @@ 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.mixins.PlayerListEntryS2CPacket$EntryMixin; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.entity.player.PlayerEntity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,6 +32,8 @@ public class Minions implements ModInitializer { } }); }); + PlayerEntity + ClientPlayNetworkHandler CommandRegistrationCallback.EVENT.register((commandDispatcher, commandRegistryAccess, registrationEnvironment) -> { MinionsCommand.register(commandDispatcher); diff --git a/src/main/java/io/github/skippyall/minions/command/MobCapDebugSubcommand.java b/src/main/java/io/github/skippyall/minions/command/MobCapDebugSubcommand.java index 567a671..7babd1d 100644 --- a/src/main/java/io/github/skippyall/minions/command/MobCapDebugSubcommand.java +++ b/src/main/java/io/github/skippyall/minions/command/MobCapDebugSubcommand.java @@ -6,7 +6,7 @@ import io.github.skippyall.minions.mixinhelper.ChunkLevelManager$DistanceFromNea import io.github.skippyall.minions.mixinhelper.ChunkLevelManagerAccessor; import io.github.skippyall.minions.mixins.antimobcap.ServerChunkManagerAccessor; import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.server.world.ChunkTicketManager; +import net.minecraft.server.world.ChunkLevelManager; import net.minecraft.text.Text; import static net.minecraft.server.command.CommandManager.literal; @@ -16,8 +16,8 @@ public class MobCapDebugSubcommand { .executes(MobCapDebugSubcommand::mobcapdebugCommand); public static int mobcapdebugCommand(CommandContext context) { - ChunkTicketManager ticketManager = ((ServerChunkManagerAccessor)context.getSource().getWorld().getChunkManager()).getTicketManager(); - int tickedChunkCount = ((ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor)((ChunkLevelManagerAccessor)ticketManager).minions$getMinionless()).minions$getTickedChunkCount(); + ChunkLevelManager levelManager = ((ServerChunkManagerAccessor)context.getSource().getWorld().getChunkManager()).getLevelManager(); + int tickedChunkCount = ((ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor)((ChunkLevelManagerAccessor)levelManager).minions$getMinionless()).minions$getTickedChunkCount(); context.getSource().sendFeedback(() -> Text.of(String.valueOf(tickedChunkCount)), false); return 0; } diff --git a/src/main/java/io/github/skippyall/minions/command/SpawnSubcommand.java b/src/main/java/io/github/skippyall/minions/command/SpawnSubcommand.java index ae42925..4b7a42a 100644 --- a/src/main/java/io/github/skippyall/minions/command/SpawnSubcommand.java +++ b/src/main/java/io/github/skippyall/minions/command/SpawnSubcommand.java @@ -15,33 +15,41 @@ import static net.minecraft.server.command.CommandManager.literal; public class SpawnSubcommand { public static final LiteralArgumentBuilder SPAWN = literal("spawn") + .requires(source -> source.hasPermissionLevel(2)) .then(argument("minion", StringArgumentType.word()) .suggests(MinionArgument.SUGGESTION_PROVIDER) - .then(argument("pos", Vec3ArgumentType.vec3())) - .executes(context -> - spawnCommand( - context.getSource(), - StringArgumentType.getString(context, "minion"), - Vec3ArgumentType.getPosArgument(context, "pos"), - false - ) - ) - - .then(argument("force", BoolArgumentType.bool()) + .then(argument("pos", Vec3ArgumentType.vec3()) .executes(context -> spawnCommand( context.getSource(), StringArgumentType.getString(context, "minion"), Vec3ArgumentType.getPosArgument(context, "pos"), - BoolArgumentType.getBool(context, "force") + false + ) + ) + .then(argument("force", BoolArgumentType.bool()) + .executes(context -> + spawnCommand( + context.getSource(), + StringArgumentType.getString(context, "minion"), + Vec3ArgumentType.getPosArgument(context, "pos"), + BoolArgumentType.getBool(context, "force") + ) ) ) ) + .executes(context -> + spawnCommand( + context.getSource(), + StringArgumentType.getString(context, "minion"), + null, + false + )) ); public static int spawnCommand(ServerCommandSource source, String minion, PosArgument pos, boolean force) throws CommandSyntaxException { MinionData data = MinionArgument.parse(minion); - MinionFakePlayer.spawnMinion(data, source.getWorld(), pos.getPos(source), pos.getRotation(source), force); + MinionFakePlayer.spawnMinion(data, source.getWorld(), pos != null ? pos.getPos(source) : null, pos != null ? pos.getRotation(source) : null, force); return 0; } } diff --git a/src/main/java/io/github/skippyall/minions/minion/fakeplayer/EntityPlayerActionPack.java b/src/main/java/io/github/skippyall/minions/minion/fakeplayer/EntityPlayerActionPack.java index f9f40ab..f03d9e0 100644 --- a/src/main/java/io/github/skippyall/minions/minion/fakeplayer/EntityPlayerActionPack.java +++ b/src/main/java/io/github/skippyall/minions/minion/fakeplayer/EntityPlayerActionPack.java @@ -7,6 +7,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import com.mojang.serialization.Codec; import io.github.skippyall.minions.mixins.EntityAccessor; import net.minecraft.block.BlockState; import net.minecraft.command.argument.EntityAnchorArgumentType; @@ -17,6 +18,7 @@ import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.vehicle.BoatEntity; import net.minecraft.entity.vehicle.MinecartEntity; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; import net.minecraft.network.packet.s2c.play.UpdateSelectedSlotS2CPacket; import net.minecraft.server.network.ServerPlayerEntity; @@ -34,7 +36,7 @@ import net.minecraft.util.math.Vec3d; public class EntityPlayerActionPack { - private final ServerPlayerEntity player; + private final MinionFakePlayer player; private final Map actions = new EnumMap<>(ActionType.class); @@ -50,7 +52,7 @@ public class EntityPlayerActionPack private int itemUseCooldown; - public EntityPlayerActionPack(ServerPlayerEntity playerIn) + public EntityPlayerActionPack(MinionFakePlayer playerIn) { player = playerIn; stopAll(); @@ -297,9 +299,9 @@ public class EntityPlayerActionPack USE(true) { @Override - boolean execute(ServerPlayerEntity player, Action action) + boolean execute(MinionFakePlayer player, Action action) { - EntityPlayerActionPack ap = ((ServerPlayerInterface) player).minions$getActionPack(); + EntityPlayerActionPack ap = player.getMinionActionPack(); if (ap.itemUseCooldown > 0) { ap.itemUseCooldown--; @@ -366,16 +368,16 @@ public class EntityPlayerActionPack } @Override - void inactiveTick(ServerPlayerEntity player, Action action) + void inactiveTick(MinionFakePlayer player, Action action) { - EntityPlayerActionPack ap = ((ServerPlayerInterface) player).minions$getActionPack(); + EntityPlayerActionPack ap = player.getMinionActionPack(); ap.itemUseCooldown = 0; player.stopUsingItem(); } }, ATTACK(true) { @Override - boolean execute(ServerPlayerEntity player, Action action) { + boolean execute(MinionFakePlayer player, Action action) { HitResult hit = getTarget(player); switch (hit.getType()) { case ENTITY: { @@ -390,7 +392,7 @@ public class EntityPlayerActionPack return true; } case BLOCK: { - EntityPlayerActionPack ap = ((ServerPlayerInterface) player).minions$getActionPack(); + EntityPlayerActionPack ap = player.getMinionActionPack(); if (ap.blockHitDelay > 0) { ap.blockHitDelay--; @@ -459,9 +461,9 @@ public class EntityPlayerActionPack } @Override - void inactiveTick(ServerPlayerEntity player, Action action) + void inactiveTick(MinionFakePlayer player, Action action) { - EntityPlayerActionPack ap = ((ServerPlayerInterface) player).minions$getActionPack(); + EntityPlayerActionPack ap = player.getMinionActionPack(); if (ap.currentBlock == null) return; player.getWorld().setBlockBreakingInfo(-1, ap.currentBlock, -1); player.interactionManager.processBlockBreakingAction(ap.currentBlock, PlayerActionC2SPacket.Action.ABORT_DESTROY_BLOCK, Direction.DOWN, player.getWorld().getTopYInclusive(), -1); @@ -471,7 +473,7 @@ public class EntityPlayerActionPack JUMP(true) { @Override - boolean execute(ServerPlayerEntity player, Action action) + boolean execute(MinionFakePlayer player, Action action) { if (action.limit == 1) { @@ -485,7 +487,7 @@ public class EntityPlayerActionPack } @Override - void inactiveTick(ServerPlayerEntity player, Action action) + void inactiveTick(MinionFakePlayer player, Action action) { player.setJumping(false); } @@ -493,7 +495,7 @@ public class EntityPlayerActionPack DROP_ITEM(true) { @Override - boolean execute(ServerPlayerEntity player, Action action) + boolean execute(MinionFakePlayer player, Action action) { player.updateLastActionTime(); player.dropSelectedItem(false); // dropSelectedItem @@ -503,7 +505,7 @@ public class EntityPlayerActionPack DROP_STACK(true) { @Override - boolean execute(ServerPlayerEntity player, Action action) + boolean execute(MinionFakePlayer player, Action action) { player.updateLastActionTime(); player.dropSelectedItem(true); // dropSelectedItem @@ -513,7 +515,7 @@ public class EntityPlayerActionPack SWAP_HANDS(true) { @Override - boolean execute(ServerPlayerEntity player, Action action) + boolean execute(MinionFakePlayer player, Action action) { player.updateLastActionTime(); ItemStack itemStack_1 = player.getStackInHand(Hand.OFF_HAND); @@ -530,10 +532,10 @@ public class EntityPlayerActionPack this.preventSpectator = preventSpectator; } - void start(ServerPlayerEntity player, Action action) {} - abstract boolean execute(ServerPlayerEntity player, Action action); - void inactiveTick(ServerPlayerEntity player, Action action) {} - void stop(ServerPlayerEntity player, Action action) + void start(MinionFakePlayer player, Action action) {} + abstract boolean execute(MinionFakePlayer player, Action action); + void inactiveTick(MinionFakePlayer player, Action action) {} + void stop(MinionFakePlayer player, Action action) { inactiveTick(player, action); } diff --git a/src/main/java/io/github/skippyall/minions/minion/fakeplayer/MinionFakePlayer.java b/src/main/java/io/github/skippyall/minions/minion/fakeplayer/MinionFakePlayer.java index 37dcd90..d8e9219 100644 --- a/src/main/java/io/github/skippyall/minions/minion/fakeplayer/MinionFakePlayer.java +++ b/src/main/java/io/github/skippyall/minions/minion/fakeplayer/MinionFakePlayer.java @@ -50,6 +50,8 @@ import java.util.Set; public class MinionFakePlayer extends ServerPlayerEntity { public Runnable fixStartingPosition = () -> {}; + private EntityPlayerActionPack actionPack; + private float moveForward; private float moveSideways; @@ -106,6 +108,7 @@ public class MinionFakePlayer extends ServerPlayerEntity { { super(server, worldIn, profile, cli); this.data = data; + actionPack = new EntityPlayerActionPack(this); } public ModuleInventory getModuleInventory() { @@ -117,7 +120,7 @@ public class MinionFakePlayer extends ServerPlayerEntity { } public EntityPlayerActionPack getMinionActionPack() { - return ((ServerPlayerInterface)this).minions$getActionPack(); + return actionPack; } @Override @@ -163,6 +166,7 @@ public class MinionFakePlayer extends ServerPlayerEntity { @Override public void tick() { + actionPack.onUpdate(); if (this.getServer().getTicks() % 10 == 0) { this.networkHandler.syncWithPlayerPosition(); diff --git a/src/main/java/io/github/skippyall/minions/minion/fakeplayer/ServerPlayerInterface.java b/src/main/java/io/github/skippyall/minions/minion/fakeplayer/ServerPlayerInterface.java deleted file mode 100644 index dcbd1d6..0000000 --- a/src/main/java/io/github/skippyall/minions/minion/fakeplayer/ServerPlayerInterface.java +++ /dev/null @@ -1,7 +0,0 @@ -//code from https://github.com/gnembon/fabric-carpet -package io.github.skippyall.minions.minion.fakeplayer; - -public interface ServerPlayerInterface -{ - EntityPlayerActionPack minions$getActionPack(); -} diff --git a/src/main/java/io/github/skippyall/minions/mixins/EntityMixin.java b/src/main/java/io/github/skippyall/minions/mixins/EntityMixin.java new file mode 100644 index 0000000..1b9fb8f --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/mixins/EntityMixin.java @@ -0,0 +1,27 @@ +package io.github.skippyall.minions.mixins; + +import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(Entity.class) +public abstract class EntityMixin { + @Shadow + public abstract @Nullable LivingEntity getControllingPassenger(); + + @Shadow + private World world; + + @Inject(method = "isLogicalSideForUpdatingMovement", at = @At("HEAD"), cancellable = true) + private void isFakePlayer(CallbackInfoReturnable cir) + { + if (getControllingPassenger() instanceof MinionFakePlayer) cir.setReturnValue(!world.isClient); + } +} diff --git a/src/main/java/io/github/skippyall/minions/mixins/PlayerMixin.java b/src/main/java/io/github/skippyall/minions/mixins/PlayerMixin.java new file mode 100644 index 0000000..f10307b --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/mixins/PlayerMixin.java @@ -0,0 +1,28 @@ +//code from https://github.com/gnembon/fabric-carpet +package io.github.skippyall.minions.mixins; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.sugar.Local; +import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(PlayerEntity.class) +public abstract class PlayerMixin { + /** + * To make sure player attacks are able to knockback fake players + */ + @ModifyExpressionValue( + method = "attack", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/entity/Entity;velocityModified:Z", + ordinal = 0 + ) + ) + private boolean velocityModifiedAndNotCarpetFakePlayer(boolean value, @Local(argsOnly = true) Entity entity) { + return value && !(entity instanceof MinionFakePlayer); + } +} diff --git a/src/main/java/io/github/skippyall/minions/mixins/ServerPlayerMixin.java b/src/main/java/io/github/skippyall/minions/mixins/ServerPlayerMixin.java deleted file mode 100644 index 9bc2c61..0000000 --- a/src/main/java/io/github/skippyall/minions/mixins/ServerPlayerMixin.java +++ /dev/null @@ -1,37 +0,0 @@ -package io.github.skippyall.minions.mixins; - -import com.mojang.authlib.GameProfile; -import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack; -import io.github.skippyall.minions.minion.fakeplayer.ServerPlayerInterface; -import net.minecraft.network.packet.c2s.common.SyncedClientOptions; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ServerPlayerEntity.class) -public abstract class ServerPlayerMixin implements ServerPlayerInterface { - @Unique - public EntityPlayerActionPack actionPack; - @Override - public EntityPlayerActionPack minions$getActionPack() - { - return actionPack; - } - - @Inject(method = "", at = @At(value = "RETURN")) - private void onServerPlayerEntityConstructor(MinecraftServer minecraftServer, ServerWorld serverLevel, GameProfile gameProfile, SyncedClientOptions clientInformation, CallbackInfo ci) - { - this.actionPack = new EntityPlayerActionPack((ServerPlayerEntity) (Object) this); - } - - @Inject(method = "tick", at = @At(value = "HEAD")) - private void onTick(CallbackInfo ci) - { - actionPack.onUpdate(); - } -} diff --git a/src/main/java/io/github/skippyall/minions/mixins/antimobcap/ServerChunkManagerAccessor.java b/src/main/java/io/github/skippyall/minions/mixins/antimobcap/ServerChunkManagerAccessor.java index b03d5fa..ceedb6c 100644 --- a/src/main/java/io/github/skippyall/minions/mixins/antimobcap/ServerChunkManagerAccessor.java +++ b/src/main/java/io/github/skippyall/minions/mixins/antimobcap/ServerChunkManagerAccessor.java @@ -1,6 +1,6 @@ package io.github.skippyall.minions.mixins.antimobcap; -import net.minecraft.server.world.ChunkTicketManager; +import net.minecraft.server.world.ChunkLevelManager; import net.minecraft.server.world.ServerChunkManager; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; @@ -8,5 +8,5 @@ import org.spongepowered.asm.mixin.gen.Accessor; @Mixin(ServerChunkManager.class) public interface ServerChunkManagerAccessor { @Accessor - ChunkTicketManager getTicketManager(); + ChunkLevelManager getLevelManager(); } diff --git a/src/main/java/io/github/skippyall/minions/module/AttackModule.java b/src/main/java/io/github/skippyall/minions/module/AttackModule.java index 5f18ff1..ed3913c 100644 --- a/src/main/java/io/github/skippyall/minions/module/AttackModule.java +++ b/src/main/java/io/github/skippyall/minions/module/AttackModule.java @@ -1,8 +1,9 @@ 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.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; @@ -12,7 +13,7 @@ import java.util.List; import static io.github.skippyall.minions.module.Modules.register; public class AttackModule { - public static final SimpleCommand ATTACK_COMMAND = new SimpleCommand( + public static final InstructionDisplay ATTACK_COMMAND = new InstructionDisplay( Text.translatable("minions.command.attack.name"), Text.translatable("minions.command.attack.description"), Items.DIAMOND_PICKAXE, diff --git a/src/main/java/io/github/skippyall/minions/module/InteractModule.java b/src/main/java/io/github/skippyall/minions/module/InteractModule.java index fc5aa3a..9689ac3 100644 --- a/src/main/java/io/github/skippyall/minions/module/InteractModule.java +++ b/src/main/java/io/github/skippyall/minions/module/InteractModule.java @@ -1,6 +1,7 @@ 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; diff --git a/src/main/java/io/github/skippyall/minions/module/ModuleItem.java b/src/main/java/io/github/skippyall/minions/module/ModuleItem.java index b91091b..87a9e21 100644 --- a/src/main/java/io/github/skippyall/minions/module/ModuleItem.java +++ b/src/main/java/io/github/skippyall/minions/module/ModuleItem.java @@ -1,13 +1,10 @@ package io.github.skippyall.minions.module; -import io.github.skippyall.minions.module.command.Command; -import io.github.skippyall.minions.program.block.CodeBlock; +import io.github.skippyall.minions.module.instruction.InstructionDisplay; import net.minecraft.item.ItemConvertible; import java.util.List; public interface ModuleItem extends ItemConvertible { - List> getCodeBlocks(); - - List getCommands(); + List getInstructions(); } diff --git a/src/main/java/io/github/skippyall/minions/module/Modules.java b/src/main/java/io/github/skippyall/minions/module/Modules.java index 6a350d1..739e8eb 100644 --- a/src/main/java/io/github/skippyall/minions/module/Modules.java +++ b/src/main/java/io/github/skippyall/minions/module/Modules.java @@ -2,6 +2,8 @@ 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; @@ -22,7 +24,7 @@ public class Modules { AttackModule.registerMe(); } - public static SimpleModuleItem register(Identifier id, List> codeBlocks, List commands, Item vanillaItem) { - return MinionItems.registerItem(id, settings -> new SimpleModuleItem(codeBlocks, commands, settings, vanillaItem)); + public static SimpleModuleItem register(Identifier id, List instructions, Item vanillaItem) { + return MinionItems.registerItem(id, settings -> new SimpleModuleItem(instructions, settings, vanillaItem)); } } diff --git a/src/main/java/io/github/skippyall/minions/module/SimpleModuleItem.java b/src/main/java/io/github/skippyall/minions/module/SimpleModuleItem.java index 1071998..0659e50 100644 --- a/src/main/java/io/github/skippyall/minions/module/SimpleModuleItem.java +++ b/src/main/java/io/github/skippyall/minions/module/SimpleModuleItem.java @@ -2,28 +2,23 @@ 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> codeBlocks; - private final List commands; + private final List instructions; - public SimpleModuleItem(List> codeBlocks, List commands, Settings settings, Item vanillaItem) { + public SimpleModuleItem(List instructions, Settings settings, Item vanillaItem) { super(settings.maxCount(1), vanillaItem); - this.codeBlocks = codeBlocks; - this.commands = commands; + this.instructions = instructions; } @Override - public List> getCodeBlocks() { - return codeBlocks; - } - - @Override - public List getCommands() { - return commands; + public List getInstructions() { + return instructions; } } diff --git a/src/main/java/io/github/skippyall/minions/module/ActionModules.java b/src/main/java/io/github/skippyall/minions/module/action/ActionModules.java similarity index 90% rename from src/main/java/io/github/skippyall/minions/module/ActionModules.java rename to src/main/java/io/github/skippyall/minions/module/action/ActionModules.java index 6c13e7b..1cbd104 100644 --- a/src/main/java/io/github/skippyall/minions/module/ActionModules.java +++ b/src/main/java/io/github/skippyall/minions/module/action/ActionModules.java @@ -1,16 +1,18 @@ -package io.github.skippyall.minions.module; +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.module.command.CommandExecutor; 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()); @@ -31,7 +33,11 @@ public class ActionModules { minion.getMinionActionPack().stop(actionType); } - public static CommandExecutor detailSelectionExecutor(EntityPlayerActionPack.ActionType actionType, Text actionName) { + public static List 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)); diff --git a/src/main/java/io/github/skippyall/minions/module/instruction/InstructionDisplay.java b/src/main/java/io/github/skippyall/minions/module/instruction/InstructionDisplay.java new file mode 100644 index 0000000..8bd2cc9 --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/module/instruction/InstructionDisplay.java @@ -0,0 +1,9 @@ +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) { + +} diff --git a/src/main/java/io/github/skippyall/minions/new_program/ParameterList.java b/src/main/java/io/github/skippyall/minions/new_program/ParameterList.java new file mode 100644 index 0000000..646a25a --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/new_program/ParameterList.java @@ -0,0 +1,32 @@ +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> parameters = new HashMap<>(); + + public @Nullable T getValue(String name, ValueType valueType, MinionFakePlayer minion) { + Argument argument = getArgument(name, valueType); + return argument != null ? argument.resolve(minion) : null; + } + + public @Nullable Argument getArgument(String name, ValueType valueType) { + Argument argument = parameters.get(name); + if(argument != null && argument.getType() == valueType) { + //noinspection unchecked + return (Argument) argument; + } else { + return null; + } + } + + public void setArgument(String name, Argument argument) { + parameters.put(name, argument); + } +} diff --git a/src/main/java/io/github/skippyall/minions/new_program/argument/Argument.java b/src/main/java/io/github/skippyall/minions/new_program/argument/Argument.java new file mode 100644 index 0000000..3b1813a --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/new_program/argument/Argument.java @@ -0,0 +1,9 @@ +package io.github.skippyall.minions.new_program.argument; + +import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; +import io.github.skippyall.minions.new_program.value.ValueType; + +public interface Argument { + T resolve(MinionFakePlayer minion); + ValueType getType(); +} diff --git a/src/main/java/io/github/skippyall/minions/new_program/argument/Arguments.java b/src/main/java/io/github/skippyall/minions/new_program/argument/Arguments.java new file mode 100644 index 0000000..d745475 --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/new_program/argument/Arguments.java @@ -0,0 +1,28 @@ +package io.github.skippyall.minions.new_program.argument; + +import com.mojang.serialization.Lifecycle; +import io.github.skippyall.minions.Minions; +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 Arguments { + public static final Registry GENERIC_ARGUMENT_TYPE_REGISTRY = new SimpleRegistry<>(RegistryKey.ofRegistry(Identifier.of("minions", "generic_argument_type")), Lifecycle.stable()); + + public static final GenericArgumentType VALUE_ARGUMENT = register(Identifier.of(Minions.MOD_ID, "value"), ValueArgumentType::new); + + public static SpecificArgumentType getArgumentType(Identifier id, ValueType valueType) { + GenericArgumentType generic = 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); + } +} diff --git a/src/main/java/io/github/skippyall/minions/new_program/argument/GenericArgumentType.java b/src/main/java/io/github/skippyall/minions/new_program/argument/GenericArgumentType.java new file mode 100644 index 0000000..17595ae --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/new_program/argument/GenericArgumentType.java @@ -0,0 +1,7 @@ +package io.github.skippyall.minions.new_program.argument; + +import io.github.skippyall.minions.new_program.value.ValueType; + +public interface GenericArgumentType { + SpecificArgumentType> createTypeSpecific(ValueType valueType); +} diff --git a/src/main/java/io/github/skippyall/minions/new_program/argument/SpecificArgumentType.java b/src/main/java/io/github/skippyall/minions/new_program/argument/SpecificArgumentType.java new file mode 100644 index 0000000..ad5914c --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/new_program/argument/SpecificArgumentType.java @@ -0,0 +1,23 @@ +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 java.util.concurrent.CompletableFuture; + +public abstract class SpecificArgumentType> { + protected final ValueType valueType; + + public SpecificArgumentType(ValueType valueType) { + this.valueType = valueType; + } + + public abstract Codec getArgumentCodec(); + + public abstract CompletableFuture openArgumentDialog(ServerPlayerEntity player, A previousArgument); + + public ValueType getValueType() { + return valueType; + } +} diff --git a/src/main/java/io/github/skippyall/minions/new_program/argument/ValueArgument.java b/src/main/java/io/github/skippyall/minions/new_program/argument/ValueArgument.java new file mode 100644 index 0000000..f3509d1 --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/new_program/argument/ValueArgument.java @@ -0,0 +1,28 @@ +package io.github.skippyall.minions.new_program.argument; + +import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; +import io.github.skippyall.minions.new_program.value.ValueType; + +public class ValueArgument implements Argument { + private final ValueType valueType; + private final T value; + + public ValueArgument(ValueType valueType, T value) { + this.valueType = valueType; + this.value = value; + } + + public T getValue() { + return value; + } + + @Override + public T resolve(MinionFakePlayer minion) { + return value; + } + + @Override + public ValueType getType() { + return valueType; + } +} diff --git a/src/main/java/io/github/skippyall/minions/new_program/argument/ValueArgumentType.java b/src/main/java/io/github/skippyall/minions/new_program/argument/ValueArgumentType.java new file mode 100644 index 0000000..a7b9788 --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/new_program/argument/ValueArgumentType.java @@ -0,0 +1,23 @@ +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 java.util.concurrent.CompletableFuture; + +public class ValueArgumentType extends SpecificArgumentType> { + public ValueArgumentType(ValueType valueType) { + super(valueType); + } + + @Override + public Codec> getArgumentCodec() { + return valueType.getCodec().xmap(value -> new ValueArgument<>(valueType, value), ValueArgument::getValue); + } + + @Override + public CompletableFuture> openArgumentDialog(ServerPlayerEntity player, ValueArgument previousArgument) { + return valueType.openValueDialog(player, previousArgument.getValue()).thenApply(value -> new ValueArgument<>(valueType, value)); + } +} diff --git a/src/main/java/io/github/skippyall/minions/new_program/instruction/Instruction.java b/src/main/java/io/github/skippyall/minions/new_program/instruction/Instruction.java new file mode 100644 index 0000000..979f075 --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/new_program/instruction/Instruction.java @@ -0,0 +1,15 @@ +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> getParameterTypes(); + + Type getReturnType(); + + InstructionRun run(MinionFakePlayer minion, ParameterList params); +} diff --git a/src/main/java/io/github/skippyall/minions/new_program/instruction/InstructionRun.java b/src/main/java/io/github/skippyall/minions/new_program/instruction/InstructionRun.java new file mode 100644 index 0000000..b76359c --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/new_program/instruction/InstructionRun.java @@ -0,0 +1,9 @@ +package io.github.skippyall.minions.new_program.instruction; + +public interface InstructionRun { + default void tick() {} + + default boolean isDone() { + return true; + } +} diff --git a/src/main/java/io/github/skippyall/minions/new_program/value/FloatValueType.java b/src/main/java/io/github/skippyall/minions/new_program/value/FloatValueType.java new file mode 100644 index 0000000..139e3f8 --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/new_program/value/FloatValueType.java @@ -0,0 +1,20 @@ +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 { + @Override + public Codec getCodec() { + return Codec.FLOAT; + } + + @Override + public CompletableFuture openValueDialog(ServerPlayerEntity player, Float previousValue) { + return TextInput.inputFloat(player, Text.literal("Please enter a decimal number."), previousValue.toString()); + } +} diff --git a/src/main/java/io/github/skippyall/minions/new_program/value/IntegerValueType.java b/src/main/java/io/github/skippyall/minions/new_program/value/IntegerValueType.java new file mode 100644 index 0000000..99bcfaf --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/new_program/value/IntegerValueType.java @@ -0,0 +1,20 @@ +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 { + @Override + public Codec getCodec() { + return Codec.INT; + } + + @Override + public CompletableFuture openValueDialog(ServerPlayerEntity player, Integer previousValue) { + return TextInput.inputInt(player, Text.literal("Please enter an integer number."), previousValue.toString()); + } +} diff --git a/src/main/java/io/github/skippyall/minions/new_program/value/ValueType.java b/src/main/java/io/github/skippyall/minions/new_program/value/ValueType.java new file mode 100644 index 0000000..92ad1c9 --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/new_program/value/ValueType.java @@ -0,0 +1,12 @@ +package io.github.skippyall.minions.new_program.value; + +import com.mojang.serialization.Codec; +import net.minecraft.server.network.ServerPlayerEntity; + +import java.util.concurrent.CompletableFuture; + +public interface ValueType { + Codec getCodec(); + + CompletableFuture openValueDialog(ServerPlayerEntity player, T previousValue); +} diff --git a/src/main/java/io/github/skippyall/minions/program/block/GoBlock.java b/src/main/java/io/github/skippyall/minions/program/block/GoBlock.java index 80a5078..ea0265c 100644 --- a/src/main/java/io/github/skippyall/minions/program/block/GoBlock.java +++ b/src/main/java/io/github/skippyall/minions/program/block/GoBlock.java @@ -2,7 +2,6 @@ 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.minion.fakeplayer.ServerPlayerInterface; import io.github.skippyall.minions.program.runtime.MinionRuntime; import io.github.skippyall.minions.program.runtime.ProgramRuntime; import io.github.skippyall.minions.program.statement.Statement; diff --git a/src/main/resources/minions.mixins.json b/src/main/resources/minions.mixins.json index 7fd1874..c599b87 100644 --- a/src/main/resources/minions.mixins.json +++ b/src/main/resources/minions.mixins.json @@ -7,19 +7,20 @@ "ChunkTicketManagerFixMixin", "ConnectionMixin", "EntityAccessor", - "GraveCompatMixin", + "EntityMixin", "EntityViewMixin", + "GraveCompatMixin", "MinecraftServerMixin", "MobEntityMixin", "PlayerListEntryS2CPacket$EntryMixin", "PlayerListMixin", - "ServerPlayerMixin", + "PlayerMixin", "ServerPlayNetworkHandlerMixin", "SleepManagerMixin", "SpawnHelperMixin", - "antimobcap.ChunkPosDistanceLevelPropagatorMixin", "antimobcap.ChunkLevelManager$DistanceFromNearestPlayerTrackerMixin", "antimobcap.ChunkLevelManagerMixin", + "antimobcap.ChunkPosDistanceLevelPropagatorMixin", "antimobcap.ServerChunkManagerAccessor", "antimobcap.ServerChunkManagerMixin" ],