This commit is contained in:
skippyall
2025-06-11 11:28:43 +02:00
parent 66cbad38cb
commit e42e3adf84
31 changed files with 377 additions and 110 deletions
@@ -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);
@@ -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<ServerCommandSource> 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;
}
@@ -15,33 +15,41 @@ import static net.minecraft.server.command.CommandManager.literal;
public class SpawnSubcommand {
public static final LiteralArgumentBuilder<ServerCommandSource> 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;
}
}
@@ -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<ActionType, Action> 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);
}
@@ -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();
@@ -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();
}
@@ -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<Boolean> cir)
{
if (getControllingPassenger() instanceof MinionFakePlayer) cir.setReturnValue(!world.isClient);
}
}
@@ -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);
}
}
@@ -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 = "<init>", 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();
}
}
@@ -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();
}
@@ -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,
@@ -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;
@@ -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<CodeBlock<?,?>> getCodeBlocks();
List<Command> getCommands();
List<InstructionDisplay> getInstructions();
}
@@ -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<CodeBlock<?,?>> codeBlocks, List<Command> commands, Item vanillaItem) {
return MinionItems.registerItem(id, settings -> new SimpleModuleItem(codeBlocks, commands, settings, vanillaItem));
public static SimpleModuleItem register(Identifier id, List<InstructionDisplay> instructions, Item vanillaItem) {
return MinionItems.registerItem(id, settings -> new SimpleModuleItem(instructions, settings, vanillaItem));
}
}
@@ -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<CodeBlock<?,?>> codeBlocks;
private final List<Command> commands;
private final List<InstructionDisplay> instructions;
public SimpleModuleItem(List<CodeBlock<?,?>> codeBlocks, List<Command> commands, Settings settings, Item vanillaItem) {
public SimpleModuleItem(List<InstructionDisplay> instructions, Settings settings, Item vanillaItem) {
super(settings.maxCount(1), vanillaItem);
this.codeBlocks = codeBlocks;
this.commands = commands;
this.instructions = instructions;
}
@Override
public List<CodeBlock<?, ?>> getCodeBlocks() {
return codeBlocks;
}
@Override
public List<Command> getCommands() {
return commands;
public List<InstructionDisplay> getInstructions() {
return instructions;
}
}
@@ -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<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));
@@ -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) {
}
@@ -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<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);
}
}
@@ -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> {
T resolve(MinionFakePlayer minion);
ValueType<T> getType();
}
@@ -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<GenericArgumentType> 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 <V> SpecificArgumentType<V, ?> getArgumentType(Identifier id, ValueType<V> 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);
}
}
@@ -0,0 +1,7 @@
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);
}
@@ -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<V, A extends Argument<V>> {
protected final ValueType<V> valueType;
public SpecificArgumentType(ValueType<V> valueType) {
this.valueType = valueType;
}
public abstract Codec<A> getArgumentCodec();
public abstract CompletableFuture<A> openArgumentDialog(ServerPlayerEntity player, A previousArgument);
public ValueType<V> getValueType() {
return valueType;
}
}
@@ -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<T> implements Argument<T> {
private final ValueType<T> valueType;
private final T value;
public ValueArgument(ValueType<T> 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<T> getType() {
return valueType;
}
}
@@ -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<V> extends SpecificArgumentType<V, ValueArgument<V>> {
public ValueArgumentType(ValueType<V> valueType) {
super(valueType);
}
@Override
public Codec<ValueArgument<V>> getArgumentCodec() {
return valueType.getCodec().xmap(value -> new ValueArgument<>(valueType, value), ValueArgument::getValue);
}
@Override
public CompletableFuture<ValueArgument<V>> openArgumentDialog(ServerPlayerEntity player, ValueArgument<V> previousArgument) {
return valueType.openValueDialog(player, previousArgument.getValue()).thenApply(value -> new ValueArgument<>(valueType, value));
}
}
@@ -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<Type<?>> getParameterTypes();
Type<?> getReturnType();
InstructionRun run(MinionFakePlayer minion, ParameterList params);
}
@@ -0,0 +1,9 @@
package io.github.skippyall.minions.new_program.instruction;
public interface InstructionRun {
default void tick() {}
default boolean isDone() {
return true;
}
}
@@ -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<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());
}
}
@@ -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<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());
}
}
@@ -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<T> {
Codec<T> getCodec();
CompletableFuture<T> openValueDialog(ServerPlayerEntity player, T previousValue);
}
@@ -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;
+4 -3
View File
@@ -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"
],