This commit is contained in:
skippyall
2025-09-24 20:27:40 +02:00
parent bcfb406547
commit 640e6f801a
8 changed files with 83 additions and 17 deletions
@@ -1,15 +1,23 @@
package io.github.skippyall.minions.gui; package io.github.skippyall.minions.gui;
import com.mojang.authlib.properties.PropertyMap;
import com.mojang.datafixers.util.Either;
import eu.pb4.sgui.api.elements.GuiElementBuilder; import eu.pb4.sgui.api.elements.GuiElementBuilder;
import io.github.skippyall.minions.util.ModelIdUtil; import io.github.skippyall.minions.util.ModelIdUtil;
import net.minecraft.block.SkullBlock;
import net.minecraft.block.entity.SkullBlockEntity;
import net.minecraft.component.DataComponentTypes; import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.LoreComponent; import net.minecraft.component.type.LoreComponent;
import net.minecraft.component.type.ProfileComponent;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import java.util.Optional;
import java.util.UUID;
public interface GuiDisplay { public interface GuiDisplay {
default GuiElementBuilder createElement() { default GuiElementBuilder createElement() {
return new GuiElementBuilder(createItemStack()); return new GuiElementBuilder(createItemStack());
@@ -33,4 +41,18 @@ public interface GuiDisplay {
return stack; return stack;
} }
} }
record HeadBased(UUID uuid, String translationKeyBase, boolean withLore) implements GuiDisplay {
@Override
public ItemStack createItemStack() {
ItemStack stack = new ItemStack(Items.PLAYER_HEAD);
stack.set(DataComponentTypes.PROFILE, new ProfileComponent(Optional.empty(), Optional.of(uuid), new PropertyMap()));
stack.set(DataComponentTypes.ITEM_NAME, Text.translatable(translationKeyBase + ".name"));
if(withLore) {
stack.set(DataComponentTypes.LORE, LoreComponent.DEFAULT.with(Text.translatable(translationKeyBase + ".description")));
}
return stack;
}
}
} }
@@ -64,7 +64,6 @@ public class MinionPersistentState extends PersistentState {
} }
public static void create(MinecraftServer server) { public static void create(MinecraftServer server) {
Minions.LOGGER.error("Creating Minion Persistent state");
INSTANCE = server.getWorld(World.OVERWORLD).getPersistentStateManager().getOrCreate(TYPE); INSTANCE = server.getWorld(World.OVERWORLD).getPersistentStateManager().getOrCreate(TYPE);
} }
} }
@@ -29,17 +29,14 @@ public interface InstructionExecution<R> {
/** /**
* Called every tick to determine if the execution of this instruction should be stopped. * Called every tick to determine if the execution of this instruction should be stopped.
* Shouldn't
* @param minion The minion executing the instruction * @param minion The minion executing the instruction
* @return <code>true</code> if the instruction is done, <code>false</code> otherwise. * @return <code>true</code> if the instruction is done, <code>false</code> otherwise.
*/ */
boolean isDone(MinionFakePlayer minion); boolean isDone(MinionFakePlayer minion);
/** /**
* Stops this execution. This is guaranteed to be called if {@link InstructionExecution#isDone(MinionFakePlayer) isDone} * Stops this execution. Is called when isDone returns true, but it may also be called before that.
* returns true after ticking the execution, but it may also be called before that. * In this case, the return value is ignored.
* In this case, the return value is ignored unless this is a
* {@link io.github.skippyall.minions.program.instruction.execution.ContinuousInstructionExecution ContinuousInstructionExecution}.</br>
* This should undo changes to the minion unless they are supposed to be permanent. * This should undo changes to the minion unless they are supposed to be permanent.
* *
* @param minion The minion that was executing this instruction. * @param minion The minion that was executing this instruction.
@@ -6,7 +6,7 @@ import io.github.skippyall.minions.program.argument.ArgumentList;
import net.minecraft.storage.ReadView; import net.minecraft.storage.ReadView;
import net.minecraft.storage.WriteView; import net.minecraft.storage.WriteView;
public class ActionExecution implements ContinuousInstructionExecution<Void> { public class ActionExecution implements ContinuousInstructionExecution {
private final EntityPlayerActionPack.ActionType action; private final EntityPlayerActionPack.ActionType action;
public ActionExecution(EntityPlayerActionPack.ActionType action) { public ActionExecution(EntityPlayerActionPack.ActionType action) {
@@ -31,5 +31,7 @@ public class ActionExecution implements ContinuousInstructionExecution<Void> {
public void save(WriteView view, MinionFakePlayer minion) {} public void save(WriteView view, MinionFakePlayer minion) {}
@Override @Override
public void load(ReadView view, MinionFakePlayer minion) {} public void load(ReadView view, MinionFakePlayer minion) {
minion.getMinionActionPack().start(action, EntityPlayerActionPack.Action.continuous());
}
} }
@@ -3,7 +3,7 @@ package io.github.skippyall.minions.program.instruction.execution;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.program.instruction.InstructionExecution; import io.github.skippyall.minions.program.instruction.InstructionExecution;
public interface ContinuousInstructionExecution<R> extends InstructionExecution<R> { public interface ContinuousInstructionExecution extends InstructionExecution<Void> {
@Override @Override
default boolean isDone(MinionFakePlayer minion) { default boolean isDone(MinionFakePlayer minion) {
return false; return false;
@@ -1,24 +1,40 @@
package io.github.skippyall.minions.program.instruction.execution; package io.github.skippyall.minions.program.instruction.execution;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import io.github.skippyall.minions.gui.Displayable;
import io.github.skippyall.minions.gui.GuiDisplay;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.program.argument.ArgumentList; import io.github.skippyall.minions.program.argument.ArgumentList;
import io.github.skippyall.minions.program.argument.Parameter;
import io.github.skippyall.minions.program.instruction.InstructionExecution; import io.github.skippyall.minions.program.instruction.InstructionExecution;
import io.github.skippyall.minions.program.value.ValueTypes;
import net.minecraft.storage.ReadView; import net.minecraft.storage.ReadView;
import net.minecraft.storage.WriteView; import net.minecraft.storage.WriteView;
import net.minecraft.util.StringIdentifiable; import net.minecraft.util.StringIdentifiable;
public class TurnExecution implements InstructionExecution<Void> { import java.util.UUID;
public class TurnExecution implements InstructionExecution<Void> {
public static final Parameter<Float> ANGLE = new Parameter<>("maxAngle", ValueTypes.FLOAT);
public static final Parameter<TurnDirection> DIRECTION = new Parameter<>("direction", ValueTypes.TURN_DIRECTION);
private static final float anglePerTick = 5;
private float maxAngle;
private float rotatedAngle;
private TurnDirection direction;
@Override @Override
public void start(MinionFakePlayer minion) { public void tick(MinionFakePlayer minion) {
InstructionExecution.super.start(minion); float toRotate = Math.min(anglePerTick, maxAngle - rotatedAngle);
minion.getMinionActionPack().turn(direction.xFactor * toRotate, direction.yFactor * toRotate);
rotatedAngle += toRotate;
} }
@Override @Override
public boolean isDone(MinionFakePlayer minion) { public boolean isDone(MinionFakePlayer minion) {
return false; return Math.abs(maxAngle - rotatedAngle) < 0.001F;
} }
@Override @Override
@@ -28,20 +44,23 @@ public class TurnExecution implements InstructionExecution<Void> {
@Override @Override
public void readArguments(ArgumentList arguments, MinionFakePlayer minion) { public void readArguments(ArgumentList arguments, MinionFakePlayer minion) {
maxAngle = arguments.getValue(ANGLE, minion);
direction = arguments.getValue(DIRECTION, minion);
} }
@Override @Override
public void save(WriteView view, MinionFakePlayer minion) { public void save(WriteView view, MinionFakePlayer minion) {
view.putFloat("maxAngle", maxAngle);
view.put("direction", TurnDirection.CODEC, direction);
} }
@Override @Override
public void load(ReadView view, MinionFakePlayer minion) { public void load(ReadView view, MinionFakePlayer minion) {
maxAngle = view.getFloat("maxAngle", 0);
direction = view.read("direction", TurnDirection.CODEC).orElseThrow();
} }
public enum TurnDirection implements StringIdentifiable { public enum TurnDirection implements StringIdentifiable, Displayable {
LEFT("left", -1, 0), LEFT("left", -1, 0),
UP("up", 0, -1), UP("up", 0, -1),
RIGHT("right", 1, 0), RIGHT("right", 1, 0),
@@ -49,6 +68,11 @@ public class TurnExecution implements InstructionExecution<Void> {
public static final Codec<TurnDirection> CODEC = StringIdentifiable.createCodec(TurnDirection::values); public static final Codec<TurnDirection> CODEC = StringIdentifiable.createCodec(TurnDirection::values);
private static final UUID MHF_ArrowLeft = UUID.fromString("a68f0b64-8d14-4000-a95f-4b9ba14f8df9");
private static final UUID MHF_ArrowUp = UUID.fromString("fef039ef-e6cd-4987-9c84-26a3e6134277");
private static final UUID MHF_ArrowRight = UUID.fromString("50c8510b-5ea0-4d60-be9a-7d542d6cd156");
private static final UUID MHF_ArrowDown = UUID.fromString("68f59b9b-5b0b-4b05-a9f2-e1d1405aa348");
public final String name; public final String name;
public final int xFactor; public final int xFactor;
public final int yFactor; public final int yFactor;
@@ -63,5 +87,15 @@ public class TurnExecution implements InstructionExecution<Void> {
public String asString() { public String asString() {
return name; return name;
} }
@Override
public GuiDisplay getDisplay() {
return switch (this) {
case LEFT -> new GuiDisplay.HeadBased(MHF_ArrowLeft, "minions.direction.left", false);
case UP -> new GuiDisplay.HeadBased(MHF_ArrowUp, "minions.direction.up", false);
case RIGHT -> new GuiDisplay.HeadBased(MHF_ArrowRight, "minions.direction.right", false);
case DOWN -> new GuiDisplay.HeadBased(MHF_ArrowDown, "minions.direction.down", false);
};
}
} }
} }
@@ -1,6 +1,7 @@
package io.github.skippyall.minions.program.value; package io.github.skippyall.minions.program.value;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import io.github.skippyall.minions.gui.Displayable;
import io.github.skippyall.minions.gui.GuiDisplay; import io.github.skippyall.minions.gui.GuiDisplay;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
@@ -3,8 +3,11 @@ package io.github.skippyall.minions.program.value;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import io.github.skippyall.minions.MinionRegistries; import io.github.skippyall.minions.MinionRegistries;
import io.github.skippyall.minions.Minions; import io.github.skippyall.minions.Minions;
import io.github.skippyall.minions.gui.Displayable;
import io.github.skippyall.minions.gui.GuiDisplay; import io.github.skippyall.minions.gui.GuiDisplay;
import io.github.skippyall.minions.input.ChoiceInput;
import io.github.skippyall.minions.input.TextInput; import io.github.skippyall.minions.input.TextInput;
import io.github.skippyall.minions.program.instruction.execution.TurnExecution;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.registry.Registry; import net.minecraft.registry.Registry;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
@@ -52,6 +55,14 @@ public class ValueTypes {
) )
); );
public static ValueType<TurnExecution.TurnDirection> TURN_DIRECTION = registerSimple(
"turn_direction",
TurnExecution.TurnDirection.CODEC,
base -> new GuiDisplay.ModelBased(Items.STRUCTURE_VOID, base, true),
TurnExecution.TurnDirection.RIGHT,
ChoiceInput.createDialogOpener(TurnExecution.TurnDirection.values())
);
public static ValueType<Void> VOID = registerSimple( public static ValueType<Void> VOID = registerSimple(
"void", "void",
Codec.unit(null), Codec.unit(null),