4 Commits

Author SHA1 Message Date
skippyall f3c934c619 Gehen Sie zu Kotlin. Gehen Sie nicht über Los und ziehen Sie nicht 200 RM ein.
Migrate some classes to Kotlin, let's see if I will regret
2026-05-02 10:48:13 +02:00
skippyall 71016f9e70 Rename .java to .kt 2026-05-02 10:48:13 +02:00
skippyall 08f9763b83 Go Back! 2026-04-30 23:56:21 +02:00
skippyall e117139a63 Port to 26.1 2026-04-29 17:20:13 +02:00
105 changed files with 1134 additions and 886 deletions
-138
View File
@@ -1,138 +0,0 @@
plugins {
id 'net.fabricmc.fabric-loom-remap' version '1.16-SNAPSHOT'
id 'maven-publish'
}
version = project.mod_version
group = project.maven_group
base {
archivesName = project.archives_base_name
}
loom {
accessWidenerPath = file("src/main/resources/minions.accesswidener")
splitEnvironmentSourceSets()
mods {
minions {
sourceSet sourceSets.main
sourceSet sourceSets.client
}
}
runs.forEach {
it.vmArg("-XX:+AllowEnhancedClassRedefinition")
}
}
repositories {
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
maven { url 'https://maven.nucleoid.xyz' }
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
filter {
includeGroup "maven.modrinth"
}
}
}
dependencies {
// To change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings loom.officialMojangMappings()
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
// Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
modImplementation "eu.pb4:polymer-core:${project.polymer_version}"
modImplementation "eu.pb4:polymer-virtual-entity:${project.polymer_version}"
modImplementation "eu.pb4:polymer-resource-pack:${project.polymer_version}"
modLocalRuntime "eu.pb4:polymer-autohost:${project.polymer_version}"
modImplementation include("eu.pb4:sgui:${project.sgui_version}")
modImplementation include("xyz.nucleoid:server-translations-api:${project.server_translations_version}")
implementation include("com.electronwill.night-config:toml:${project.night_config_version}")
modCompileOnly "maven.modrinth:universal-graves:${project.universal_graves_version}"
}
processResources {
inputs.property "version", project.version
inputs.property "minecraft_version", project.minecraft_version
inputs.property "loader_version", project.loader_version
filteringCharset "UTF-8"
filesMatching("fabric.mod.json") {
expand "version": project.version,
"minecraft_version": project.minecraft_version,
"loader_version": project.loader_version
}
}
def targetJavaVersion = 21
tasks.withType(JavaCompile).configureEach {
// ensure that the encoding is set to UTF-8, no matter what the system default is
// this fixes some edge cases with special characters not displaying correctly
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
// If Javadoc is generated, this must be specified in that task too.
it.options.encoding = "UTF-8"
if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) {
it.options.release.set(targetJavaVersion)
}
}
java {
def javaVersion = JavaVersion.toVersion(targetJavaVersion)
if (JavaVersion.current() < javaVersion) {
toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion)
}
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
// if it is present.
// If you remove this line, sources will not be generated.
withSourcesJar()
}
jar {
from("LICENSE") {
rename { "${it}_${project.archives_base_name}"}
}
from("src/main/resoures/assets/minions/lang") {
include("*")
into("data/minions/lang/")
}
}
// configure the maven publication
publishing {
publications {
maven (MavenPublication) {
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
maven {
name = "foxgalaxy"
url = "https://maven.foxgalaxy.de/private"
credentials(PasswordCredentials)
}
}
}
+128
View File
@@ -0,0 +1,128 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
id("net.fabricmc.fabric-loom")
`maven-publish`
id("org.jetbrains.kotlin.jvm") version "2.3.21"
}
version = providers.gradleProperty("mod_version").get()
group = providers.gradleProperty("maven_group").get()
repositories {
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
maven("https://maven.nucleoid.xyz")
exclusiveContent {
forRepository {
maven ("https://api.modrinth.com/maven")
}
filter {
includeGroup("maven.modrinth")
}
}
}
loom {
splitEnvironmentSourceSets()
mods {
register("minions") {
sourceSet(sourceSets.main.get())
sourceSet(sourceSets.getByName("client"))
}
}
for (settings in runs) {
settings.vmArg("-XX:+AllowEnhancedClassRedefinition")
}
accessWidenerPath = file("src/main/resources/minions.classtweaker")
}
dependencies {
// To change the versions see the gradle.properties file
minecraft("com.mojang:minecraft:${providers.gradleProperty("minecraft_version").get()}")
implementation("net.fabricmc:fabric-loader:${providers.gradleProperty("loader_version").get()}")
// Fabric API. This is technically optional, but you probably want it anyway.
implementation("net.fabricmc.fabric-api:fabric-api:${providers.gradleProperty("fabric_api_version").get()}")
implementation("net.fabricmc:fabric-language-kotlin:${providers.gradleProperty("fabric_kotlin_version").get()}")
val polymer_version = providers.gradleProperty("polymer_version").get()
implementation("eu.pb4:polymer-core:${polymer_version}")
implementation("eu.pb4:polymer-virtual-entity:${polymer_version}")
implementation("eu.pb4:polymer-resource-pack:${polymer_version}")
localRuntime("eu.pb4:polymer-autohost:${polymer_version}")
implementation("eu.pb4:sgui:${providers.gradleProperty("sgui_version").get()}")
implementation("xyz.nucleoid:server-translations-api:${providers.gradleProperty("server_translations_version").get()}")
implementation("com.electronwill.night-config:toml:${providers.gradleProperty("night_config_version").get()}")
compileOnly("maven.modrinth:universal-graves:${providers.gradleProperty("universal_graves_version").get()}")
}
tasks.processResources {
val version = version
inputs.property("version", version)
filesMatching("fabric.mod.json") {
expand("version" to version)
}
}
tasks.withType<JavaCompile>().configureEach {
options.release = 25
}
kotlin {
compilerOptions {
jvmTarget = JvmTarget.JVM_25
}
}
java {
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
// if it is present.
// If you remove this line, sources will not be generated.
withSourcesJar()
sourceCompatibility = JavaVersion.VERSION_25
targetCompatibility = JavaVersion.VERSION_25
}
tasks.jar {
val projectName = project.name
inputs.property("projectName", projectName)
from("LICENSE") {
rename { "${it}_$projectName" }
}
}
// configure the maven publication
publishing {
publications {
register<MavenPublication>("mavenJava") {
from(components["java"])
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
maven("https://maven.foxgalaxy.de/private") {
name = "foxgalaxy"
credentials(PasswordCredentials::class.java)
}
}
}
+9 -8
View File
@@ -3,9 +3,9 @@ org.gradle.jvmargs=-Xmx1G
# Fabric Properties # Fabric Properties
# check these on https://modmuss50.me/fabric.html # check these on https://modmuss50.me/fabric.html
minecraft_version=1.21.7 loom_version=1.16-SNAPSHOT
loader_version=0.16.14 minecraft_version=26.1.2
yarn_mappings=1.21.7+build.2 loader_version=0.19.2
# Mod Properties # Mod Properties
mod_version = 1.0.0-TEST-1 mod_version = 1.0.0-TEST-1
@@ -14,12 +14,13 @@ org.gradle.jvmargs=-Xmx1G
# Dependencies # Dependencies
# check this on https://modmuss50.me/fabric.html # check this on https://modmuss50.me/fabric.html
fabric_version=0.128.1+1.21.7 fabric_api_version=0.147.0+26.1.2
fabric_kotlin_version=1.13.11+kotlin.2.3.21
polymer_version=0.13.3+1.21.6 polymer_version=0.16.3+26.1.2
sgui_version=1.10.0+1.21.6 sgui_version=2.0.0+26.1
server_translations_version=2.5.1+1.21.5 server_translations_version=3.0.3+26.1
night_config_version=3.8.3 night_config_version=3.8.3
universal_graves_version=3.8.0+1.21.6 universal_graves_version=3.11.0+26.1.2
-9
View File
@@ -1,9 +0,0 @@
pluginManagement {
repositories {
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
gradlePluginPortal()
}
}
+17
View File
@@ -0,0 +1,17 @@
pluginManagement {
repositories {
maven {
name = "Fabric"
url = uri("https://maven.fabricmc.net/")
}
mavenCentral()
gradlePluginPortal()
}
plugins {
id("net.fabricmc.fabric-loom") version providers.gradleProperty("loom_version")
}
}
// Should match your modid
rootProject.name = "minions"
@@ -2,16 +2,11 @@ package io.github.skippyall.minions.client;
import eu.pb4.polymer.networking.api.client.PolymerClientNetworking; import eu.pb4.polymer.networking.api.client.PolymerClientNetworking;
import io.github.skippyall.minions.polymer.VersionSync; import io.github.skippyall.minions.polymer.VersionSync;
import io.github.skippyall.minions.registration.MinionBlocks;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.rendering.v1.BlockRenderLayerMap;
import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
public class MinionsClient implements ClientModInitializer { public class MinionsClient implements ClientModInitializer {
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
BlockRenderLayerMap.putBlock(MinionBlocks.MINION_TRIGGER_BLOCK, ChunkSectionLayer.TRANSLUCENT);
PolymerClientNetworking.registerCommonHandler(VersionSync.VersionSyncPayload.class, (client, handler, payload) -> {}); PolymerClientNetworking.registerCommonHandler(VersionSync.VersionSyncPayload.class, (client, handler, payload) -> {});
} }
} }
@@ -16,7 +16,7 @@ public class AnalogInputBlock extends Block {
@Override @Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
if(!world.isClientSide) { if(!world.isClientSide()) {
player.getInventory().placeItemBackInInventory(ClipboardItem.createBlockPosReference(world, pos), true); player.getInventory().placeItemBackInInventory(ClipboardItem.createBlockPosReference(world, pos), true);
} }
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
@@ -7,7 +7,9 @@ import io.github.skippyall.minions.registration.MinionBlocks;
import io.github.skippyall.minions.registration.MinionComponentTypes; import io.github.skippyall.minions.registration.MinionComponentTypes;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ClientboundSoundPacket;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
@@ -30,10 +32,10 @@ public abstract class InstructionBoundBlock extends Block implements EntityBlock
@Override @Override
protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
if(stack.get(MinionComponentTypes.REFERENCE) instanceof InstructionClipboard instruction) { if(stack.get(MinionComponentTypes.REFERENCE) instanceof InstructionClipboard instruction && player instanceof ServerPlayer serverPlayer) {
world.getBlockEntity(pos, getBlockEntityType()).ifPresent(be -> { world.getBlockEntity(pos, getBlockEntityType()).ifPresent(be -> {
be.setInstruction(instruction.selectedMinion(), instruction.selectedInstruction()); be.setInstruction(instruction.selectedMinion(), instruction.selectedInstruction());
player.playNotifySound(SoundEvents.NOTE_BLOCK_CHIME.value(), SoundSource.BLOCKS, 1, 1); serverPlayer.connection.send(new ClientboundSoundPacket(SoundEvents.NOTE_BLOCK_CHIME, SoundSource.BLOCKS, pos.getX(), pos.getY(), pos.getZ(), 1, 1, 0));
stack.shrink(1); stack.shrink(1);
}); });
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
@@ -50,7 +52,7 @@ public abstract class InstructionBoundBlock extends Block implements EntityBlock
world.getBlockEntity(pos, getBlockEntityType()).ifPresent(be -> { world.getBlockEntity(pos, getBlockEntityType()).ifPresent(be -> {
String name = MinionPersistentState.get(world.getServer()).getMinionData(be.getMinionUuid()).name(); String name = MinionPersistentState.get(world.getServer()).getMinionData(be.getMinionUuid()).name();
player.displayClientMessage(Component.translatable("minions.reference.instruction.tooltip", name, be.getInstructionName()), true); player.sendSystemMessage(Component.translatable("minions.reference.instruction.tooltip", be.getInstructionName(), name));
}); });
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
} }
@@ -4,14 +4,15 @@ import io.github.skippyall.minions.listener.BlockEntityMinionListener;
import io.github.skippyall.minions.minion.MinionRuntime; import io.github.skippyall.minions.minion.MinionRuntime;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction; import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
import java.util.Optional;
import java.util.UUID;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import java.util.Optional;
import java.util.UUID;
public abstract class InstructionBoundBlockEntity<L extends BlockEntityMinionListener<?>> extends BlockEntity { public abstract class InstructionBoundBlockEntity<L extends BlockEntityMinionListener<?>> extends BlockEntity {
protected UUID minionUuid; protected UUID minionUuid;
protected String instructionName = ""; protected String instructionName = "";
@@ -27,9 +28,11 @@ public abstract class InstructionBoundBlockEntity<L extends BlockEntityMinionLis
public void removeListener() { public void removeListener() {
if(level instanceof ServerLevel serverWorld) { if(level instanceof ServerLevel serverWorld) {
L listener = getListener(); L listener = getListener();
if(listener != null) {
listener.remove(serverWorld.getServer()); listener.remove(serverWorld.getServer());
} }
} }
}
public void addListener() { public void addListener() {
if(level instanceof ServerLevel serverWorld) { if(level instanceof ServerLevel serverWorld) {
@@ -3,7 +3,6 @@ package io.github.skippyall.minions.block.miniontrigger;
import com.mojang.serialization.MapCodec; import com.mojang.serialization.MapCodec;
import eu.pb4.polymer.core.api.block.PolymerBlock; import eu.pb4.polymer.core.api.block.PolymerBlock;
import eu.pb4.polymer.core.api.utils.PolymerClientDecoded; import eu.pb4.polymer.core.api.utils.PolymerClientDecoded;
import eu.pb4.polymer.core.api.utils.PolymerKeepModel;
import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils; import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils;
import eu.pb4.polymer.virtualentity.api.BlockWithElementHolder; import eu.pb4.polymer.virtualentity.api.BlockWithElementHolder;
import eu.pb4.polymer.virtualentity.api.ElementHolder; import eu.pb4.polymer.virtualentity.api.ElementHolder;
@@ -12,10 +11,11 @@ import io.github.skippyall.minions.Minions;
import io.github.skippyall.minions.block.instruction_bound.InstructionBoundBlock; import io.github.skippyall.minions.block.instruction_bound.InstructionBoundBlock;
import io.github.skippyall.minions.polymer.VersionSync; import io.github.skippyall.minions.polymer.VersionSync;
import io.github.skippyall.minions.registration.MinionBlocks; import io.github.skippyall.minions.registration.MinionBlocks;
import net.fabricmc.fabric.api.networking.v1.context.PacketContext;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.component.DataComponents; import net.minecraft.core.component.DataComponents;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.minecraft.server.network.ServerGamePacketListenerImpl;
@@ -37,9 +37,8 @@ import net.minecraft.world.level.redstone.Orientation;
import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.nucleoid.packettweaker.PacketContext;
public class MinionTriggerBlock extends InstructionBoundBlock implements PolymerBlock, PolymerKeepModel, PolymerClientDecoded, BlockWithElementHolder { public class MinionTriggerBlock extends InstructionBoundBlock implements PolymerBlock, PolymerClientDecoded, BlockWithElementHolder {
public static final MapCodec<MinionTriggerBlock> CODEC = simpleCodec(MinionTriggerBlock::new); public static final MapCodec<MinionTriggerBlock> CODEC = simpleCodec(MinionTriggerBlock::new);
public static final BooleanProperty POWERED = BooleanProperty.create("powered"); public static final BooleanProperty POWERED = BooleanProperty.create("powered");
@@ -91,7 +90,7 @@ public class MinionTriggerBlock extends InstructionBoundBlock implements Polymer
} }
@Override @Override
protected int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) { protected int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos, Direction direction) {
return world.getBlockEntity(pos, MinionBlocks.MINION_TRIGGER_BE_TYPE).map(MinionTriggerBlockEntity::getComparatorOutput).orElse(0); return world.getBlockEntity(pos, MinionBlocks.MINION_TRIGGER_BE_TYPE).map(MinionTriggerBlockEntity::getComparatorOutput).orElse(0);
} }
@@ -128,7 +127,7 @@ public class MinionTriggerBlock extends InstructionBoundBlock implements Polymer
} }
}; };
ItemStack stack = new ItemStack(Items.BARRIER); ItemStack stack = new ItemStack(Items.BARRIER);
stack.set(DataComponents.ITEM_MODEL, ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, "minion_trigger_no_plate_" + (initialBlockState.getValue(MinionTriggerBlock.POWERED) ? "active" : "inactive"))); stack.set(DataComponents.ITEM_MODEL, Identifier.fromNamespaceAndPath(Minions.MOD_ID, "minion_trigger_no_plate_" + (initialBlockState.getValue(MinionTriggerBlock.POWERED) ? "active" : "inactive")));
ItemDisplayElement element = new ItemDisplayElement(stack); ItemDisplayElement element = new ItemDisplayElement(stack);
element.setItemDisplayContext(ItemDisplayContext.NONE); element.setItemDisplayContext(ItemDisplayContext.NONE);
@@ -2,12 +2,13 @@ package io.github.skippyall.minions.block.miniontrigger;
import eu.pb4.polymer.core.api.item.PolymerBlockItem; import eu.pb4.polymer.core.api.item.PolymerBlockItem;
import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils; import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils;
import net.minecraft.resources.ResourceLocation; import net.fabricmc.fabric.api.networking.v1.context.PacketContext;
import net.minecraft.core.HolderLookup;
import net.minecraft.resources.Identifier;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.nucleoid.packettweaker.PacketContext;
public class MinionTriggerBlockItem extends PolymerBlockItem { public class MinionTriggerBlockItem extends PolymerBlockItem {
public MinionTriggerBlockItem(Block block, Properties settings, Item polymerItem) { public MinionTriggerBlockItem(Block block, Properties settings, Item polymerItem) {
@@ -15,9 +16,9 @@ public class MinionTriggerBlockItem extends PolymerBlockItem {
} }
@Override @Override
public @Nullable ResourceLocation getPolymerItemModel(ItemStack stack, PacketContext context) { public @Nullable Identifier getPolymerItemModel(ItemStack stack, PacketContext context, HolderLookup.Provider lookup) {
if(PolymerResourcePackUtils.hasMainPack(context)) { if(PolymerResourcePackUtils.hasMainPack(context)) {
return super.getPolymerItemModel(stack, context); return super.getPolymerItemModel(stack, context, lookup);
} else { } else {
return null; return null;
} }
@@ -11,10 +11,11 @@ import io.github.skippyall.minions.program.instruction.ConfiguredInstructionList
import io.github.skippyall.minions.registration.MinionBlocks; import io.github.skippyall.minions.registration.MinionBlocks;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.UUIDUtil; import net.minecraft.core.UUIDUtil;
import net.minecraft.resources.Identifier;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
@@ -82,8 +83,8 @@ public class MinionTriggerMinionListener extends BlockEntityMinionInstructionLis
} }
@Override @Override
public Optional<ResourceLocation> getCodecId() { public Optional<Identifier> getCodecId() {
return Optional.of(ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, "minion_trigger")); return Optional.of(Identifier.fromNamespaceAndPath(Minions.MOD_ID, "minion_trigger"));
} }
public void updateComparatorsIfLoaded(MinecraftServer server) { public void updateComparatorsIfLoaded(MinecraftServer server) {
@@ -2,7 +2,6 @@ package io.github.skippyall.minions.clipboard;
import com.mojang.serialization.MapCodec; import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder; import com.mojang.serialization.codecs.RecordCodecBuilder;
import java.util.function.Consumer;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.component.DataComponentGetter; import net.minecraft.core.component.DataComponentGetter;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
@@ -11,6 +10,8 @@ import net.minecraft.world.item.Item;
import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import java.util.function.Consumer;
public record BlockPosClipboard(ResourceKey<Level> world, BlockPos pos) implements Clipboard { public record BlockPosClipboard(ResourceKey<Level> world, BlockPos pos) implements Clipboard {
public static final MapCodec<BlockPosClipboard> CODEC = RecordCodecBuilder.mapCodec(instance -> public static final MapCodec<BlockPosClipboard> CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group( instance.group(
@@ -3,9 +3,10 @@ package io.github.skippyall.minions.clipboard;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec; import com.mojang.serialization.MapCodec;
import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.registration.MinionRegistries;
import java.util.function.Function;
import net.minecraft.world.item.component.TooltipProvider; import net.minecraft.world.item.component.TooltipProvider;
import java.util.function.Function;
public interface Clipboard extends TooltipProvider { public interface Clipboard extends TooltipProvider {
Codec<Clipboard> CODEC = MinionRegistries.CLIPBOARD_TYPES.byNameCodec().dispatch(Clipboard::getCodec, Function.identity()); Codec<Clipboard> CODEC = MinionRegistries.CLIPBOARD_TYPES.byNameCodec().dispatch(Clipboard::getCodec, Function.identity());
@@ -4,16 +4,17 @@ import eu.pb4.polymer.core.api.item.PolymerItem;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.registration.MinionComponentTypes; import io.github.skippyall.minions.registration.MinionComponentTypes;
import io.github.skippyall.minions.registration.MinionItems; import io.github.skippyall.minions.registration.MinionItems;
import net.fabricmc.fabric.api.networking.v1.context.PacketContext;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.component.DataComponents; import net.minecraft.core.component.DataComponents;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.nucleoid.packettweaker.PacketContext;
public class ClipboardItem extends Item implements PolymerItem { public class ClipboardItem extends Item implements PolymerItem {
public ClipboardItem(Properties settings) { public ClipboardItem(Properties settings) {
@@ -26,20 +27,20 @@ public class ClipboardItem extends Item implements PolymerItem {
} }
@Override @Override
public @Nullable ResourceLocation getPolymerItemModel(ItemStack stack, PacketContext context) { public @Nullable Identifier getPolymerItemModel(ItemStack stack, PacketContext context, HolderLookup.Provider lookup) {
return null; return null;
} }
@Override @Override
public ItemStack getPolymerItemStack(ItemStack itemStack, TooltipFlag tooltipType, PacketContext context) { public ItemStack getPolymerItemStack(ItemStack itemStack, TooltipFlag tooltipType, PacketContext context, HolderLookup.Provider lookup) {
ItemStack stack = PolymerItem.super.getPolymerItemStack(itemStack, tooltipType, context); ItemStack stack = PolymerItem.super.getPolymerItemStack(itemStack, tooltipType, context, lookup);
stack.set(DataComponents.ENCHANTMENT_GLINT_OVERRIDE, true); stack.set(DataComponents.ENCHANTMENT_GLINT_OVERRIDE, true);
return stack; return stack;
} }
public static ItemStack createInstructionReference(MinionFakePlayer minion, String instructionName) { public static ItemStack createInstructionReference(MinionFakePlayer minion, String instructionName) {
ItemStack stack = new ItemStack(MinionItems.REFERENCE_ITEM); ItemStack stack = new ItemStack(MinionItems.REFERENCE_ITEM);
stack.set(MinionComponentTypes.REFERENCE, new InstructionClipboard(minion.getUUID(), instructionName, minion.getGameProfile().getName())); stack.set(MinionComponentTypes.REFERENCE, new InstructionClipboard(minion.getUUID(), instructionName, minion.getGameProfile().name()));
return stack; return stack;
} }
@@ -3,14 +3,15 @@ package io.github.skippyall.minions.clipboard;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec; import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder; import com.mojang.serialization.codecs.RecordCodecBuilder;
import java.util.UUID;
import java.util.function.Consumer;
import net.minecraft.core.UUIDUtil; import net.minecraft.core.UUIDUtil;
import net.minecraft.core.component.DataComponentGetter; import net.minecraft.core.component.DataComponentGetter;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.TooltipFlag;
import java.util.UUID;
import java.util.function.Consumer;
public record InstructionClipboard(UUID selectedMinion, String selectedInstruction, String visualMinionName) implements Clipboard { public record InstructionClipboard(UUID selectedMinion, String selectedInstruction, String visualMinionName) implements Clipboard {
public static final MapCodec<InstructionClipboard> CODEC = RecordCodecBuilder.mapCodec(instance -> public static final MapCodec<InstructionClipboard> CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group( instance.group(
@@ -6,10 +6,11 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder; import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import io.github.skippyall.minions.docs.DocsManager; import io.github.skippyall.minions.docs.DocsManager;
import java.util.concurrent.CompletableFuture;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.arguments.ResourceLocationArgument; import net.minecraft.commands.arguments.IdentifierArgument;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import java.util.concurrent.CompletableFuture;
import static net.minecraft.commands.Commands.argument; import static net.minecraft.commands.Commands.argument;
import static net.minecraft.commands.Commands.literal; import static net.minecraft.commands.Commands.literal;
@@ -17,7 +18,7 @@ import static net.minecraft.commands.Commands.literal;
public class DocsSubcommand { public class DocsSubcommand {
public static final LiteralArgumentBuilder<CommandSourceStack> DOCS = literal("docs") public static final LiteralArgumentBuilder<CommandSourceStack> DOCS = literal("docs")
.then( .then(
argument("docName", ResourceLocationArgument.id()) argument("docName", IdentifierArgument.id())
.suggests(DocsSubcommand::getSuggestions) .suggests(DocsSubcommand::getSuggestions)
.executes(DocsSubcommand::execute) .executes(DocsSubcommand::execute)
); );
@@ -28,7 +29,7 @@ public class DocsSubcommand {
} }
public static int execute(CommandContext<CommandSourceStack> context) throws CommandSyntaxException { public static int execute(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
ResourceLocation id = ResourceLocationArgument.getId(context, "docName"); Identifier id = IdentifierArgument.getId(context, "docName");
DocsManager.showDocsEntry(context.getSource().getPlayerOrException(), id); DocsManager.showDocsEntry(context.getSource().getPlayerOrException(), id);
return 1; return 1;
} }
@@ -4,10 +4,11 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import io.github.skippyall.minions.minion.MinionData; import io.github.skippyall.minions.minion.MinionData;
import io.github.skippyall.minions.minion.MinionPersistentState; import io.github.skippyall.minions.minion.MinionPersistentState;
import java.util.Collection;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import java.util.Collection;
import static net.minecraft.commands.Commands.literal; import static net.minecraft.commands.Commands.literal;
public class ListSubcommand { public class ListSubcommand {
@@ -9,13 +9,14 @@ import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.arguments.coordinates.Coordinates; import net.minecraft.commands.arguments.coordinates.Coordinates;
import net.minecraft.commands.arguments.coordinates.Vec3Argument; import net.minecraft.commands.arguments.coordinates.Vec3Argument;
import net.minecraft.server.permissions.Permissions;
import static net.minecraft.commands.Commands.argument; import static net.minecraft.commands.Commands.argument;
import static net.minecraft.commands.Commands.literal; import static net.minecraft.commands.Commands.literal;
public class SpawnSubcommand { public class SpawnSubcommand {
public static final LiteralArgumentBuilder<CommandSourceStack> SPAWN = literal("spawn") public static final LiteralArgumentBuilder<CommandSourceStack> SPAWN = literal("spawn")
.requires(source -> source.hasPermission(2)) .requires(source -> source.permissions().hasPermission(Permissions.COMMANDS_GAMEMASTER))
.then(argument("minion", StringArgumentType.word()) .then(argument("minion", StringArgumentType.word())
.suggests(MinionArgument.SUGGESTION_PROVIDER) .suggests(MinionArgument.SUGGESTION_PROVIDER)
.then(argument("pos", Vec3Argument.vec3()) .then(argument("pos", Vec3Argument.vec3())
@@ -3,8 +3,6 @@ package io.github.skippyall.minions.command;
import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import io.github.skippyall.minions.Minions; import io.github.skippyall.minions.Minions;
import java.util.Collection;
import java.util.HashSet;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.arguments.coordinates.BlockPosArgument; import net.minecraft.commands.arguments.coordinates.BlockPosArgument;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
@@ -13,6 +11,9 @@ import net.minecraft.network.chat.Component;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import java.util.Collection;
import java.util.HashSet;
import static net.minecraft.commands.Commands.argument; import static net.minecraft.commands.Commands.argument;
import static net.minecraft.commands.Commands.literal; import static net.minecraft.commands.Commands.literal;
@@ -4,11 +4,12 @@ import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec; import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder; import com.mojang.serialization.codecs.RecordCodecBuilder;
import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.registration.MinionRegistries;
import java.util.List;
import java.util.function.Function;
import net.minecraft.core.RegistryAccess; import net.minecraft.core.RegistryAccess;
import net.minecraft.server.dialog.body.DialogBody; import net.minecraft.server.dialog.body.DialogBody;
import java.util.List;
import java.util.function.Function;
public interface DocsEntry { public interface DocsEntry {
Codec<DocsEntry> CODEC = MinionRegistries.DOCS_ENTRY_TYPES.byNameCodec().dispatch(DocsEntry::getCodec, Function.identity()); Codec<DocsEntry> CODEC = MinionRegistries.DOCS_ENTRY_TYPES.byNameCodec().dispatch(DocsEntry::getCodec, Function.identity());
@@ -7,7 +7,7 @@ import net.fabricmc.fabric.api.resource.SimpleResourceReloadListener;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraft.server.dialog.ActionButton; import net.minecraft.server.dialog.ActionButton;
import net.minecraft.server.dialog.CommonButtonData; import net.minecraft.server.dialog.CommonButtonData;
import net.minecraft.server.dialog.CommonDialogData; import net.minecraft.server.dialog.CommonDialogData;
@@ -30,15 +30,15 @@ import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
public class DocsManager implements SimpleResourceReloadListener<Tuple<Map<ResourceLocation, DocsEntry>, DocsTree>> { public class DocsManager implements SimpleResourceReloadListener<Tuple<Map<Identifier, DocsEntry>, DocsTree>> {
private static Map<ResourceLocation, DocsEntry> docs; private static Map<Identifier, DocsEntry> docs;
private static DocsTree tree; private static DocsTree tree;
public static DocsTree getTree() { public static DocsTree getTree() {
return tree; return tree;
} }
public static void showDocsEntry(ServerPlayer player, ResourceLocation id) { public static void showDocsEntry(ServerPlayer player, Identifier id) {
DocsEntry entry = getDocsEntry(id); DocsEntry entry = getDocsEntry(id);
if(entry == null) { if(entry == null) {
return; return;
@@ -48,11 +48,11 @@ public class DocsManager implements SimpleResourceReloadListener<Tuple<Map<Resou
if(tree != null) { if(tree != null) {
DocsTree.DocElement element = tree.getElement(id); DocsTree.DocElement element = tree.getElement(id);
if (element.previous() != null) { if (element.previous() != null) {
ResourceLocation previousId = element.previous().getId(); Identifier previousId = element.previous().getId();
buttons.add(getDialogButton(Component.literal("<- ").append(Component.translatable(getDocsEntry(previousId).getMetadata().titleKey())), previousId.toString())); buttons.add(getDialogButton(Component.literal("<- ").append(Component.translatable(getDocsEntry(previousId).getMetadata().titleKey())), previousId.toString()));
} }
if (element.next() != null) { if (element.next() != null) {
ResourceLocation nextId = element.next().getId(); Identifier nextId = element.next().getId();
buttons.add(getDialogButton(Component.translatable(getDocsEntry(nextId).getMetadata().titleKey()).append(Component.literal(" ->")), nextId.toString())); buttons.add(getDialogButton(Component.translatable(getDocsEntry(nextId).getMetadata().titleKey()).append(Component.literal(" ->")), nextId.toString()));
} }
} }
@@ -87,21 +87,21 @@ public class DocsManager implements SimpleResourceReloadListener<Tuple<Map<Resou
); );
} }
public static DocsEntry getDocsEntry(ResourceLocation id) { public static DocsEntry getDocsEntry(Identifier id) {
return docs.get(id); return docs.get(id);
} }
public static Collection<ResourceLocation> getDocsEntryIds() { public static Collection<Identifier> getDocsEntryIds() {
return docs.keySet(); return docs.keySet();
} }
@Override @Override
public CompletableFuture<Tuple<Map<ResourceLocation, DocsEntry>, DocsTree>> load(ResourceManager resourceManager, Executor executor) { public CompletableFuture<Tuple<Map<Identifier, DocsEntry>, DocsTree>> load(ResourceManager resourceManager, Executor executor) {
return CompletableFuture.supplyAsync(() -> { return CompletableFuture.supplyAsync(() -> {
Map<ResourceLocation, Resource> resources = resourceManager.listResources("docs", id -> id.getNamespace().equals(Minions.MOD_ID) && id.getPath().endsWith(".json")); Map<Identifier, Resource> resources = resourceManager.listResources("docs", id -> id.getNamespace().equals(Minions.MOD_ID) && id.getPath().endsWith(".json"));
final DocsTree.BranchElement[] root = {null}; final DocsTree.BranchElement[] root = {null};
Map<ResourceLocation, DocsEntry> docsEntries = new HashMap<>(); Map<Identifier, DocsEntry> docsEntries = new HashMap<>();
resources.forEach((id, resource) -> { resources.forEach((id, resource) -> {
try(Reader reader = resource.openAsReader()) { try(Reader reader = resource.openAsReader()) {
if(id.getPath().equals("docs/tree.json")) { if(id.getPath().equals("docs/tree.json")) {
@@ -109,7 +109,7 @@ public class DocsManager implements SimpleResourceReloadListener<Tuple<Map<Resou
.ifSuccess(entry -> root[0] = entry.getFirst()) .ifSuccess(entry -> root[0] = entry.getFirst())
.ifError(error -> Minions.LOGGER.warn("Could not parse docs tree {}: {}", id, error.message())); .ifError(error -> Minions.LOGGER.warn("Could not parse docs tree {}: {}", id, error.message()));
} else { } else {
ResourceLocation docId = ResourceLocation.fromNamespaceAndPath(id.getNamespace(), id.getPath().substring("docs/".length(), id.getPath().length() - ".json".length())); Identifier docId = Identifier.fromNamespaceAndPath(id.getNamespace(), id.getPath().substring("docs/".length(), id.getPath().length() - ".json".length()));
DocsEntry.CODEC.decode(JsonOps.INSTANCE, StrictJsonParser.parse(reader)) DocsEntry.CODEC.decode(JsonOps.INSTANCE, StrictJsonParser.parse(reader))
.ifSuccess(entry -> docsEntries.put(docId, entry.getFirst())) .ifSuccess(entry -> docsEntries.put(docId, entry.getFirst()))
.ifError(error -> Minions.LOGGER.warn("Could not parse docs entry {}: {}", id, error.message())); .ifError(error -> Minions.LOGGER.warn("Could not parse docs entry {}: {}", id, error.message()));
@@ -128,7 +128,7 @@ public class DocsManager implements SimpleResourceReloadListener<Tuple<Map<Resou
} }
@Override @Override
public CompletableFuture<Void> apply(Tuple<Map<ResourceLocation, DocsEntry>, DocsTree> o, ResourceManager resourceManager, Executor executor) { public CompletableFuture<Void> apply(Tuple<Map<Identifier, DocsEntry>, DocsTree> o, ResourceManager resourceManager, Executor executor) {
return CompletableFuture.supplyAsync(() -> { return CompletableFuture.supplyAsync(() -> {
docs = o.getA(); docs = o.getA();
tree = o.getB(); tree = o.getB();
@@ -137,7 +137,7 @@ public class DocsManager implements SimpleResourceReloadListener<Tuple<Map<Resou
} }
@Override @Override
public ResourceLocation getFabricId() { public Identifier getFabricId() {
return ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, "docs"); return Identifier.fromNamespaceAndPath(Minions.MOD_ID, "docs");
} }
} }
@@ -2,15 +2,16 @@ package io.github.skippyall.minions.docs;
import com.mojang.datafixers.util.Either; import com.mojang.datafixers.util.Either;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import net.minecraft.resources.Identifier;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import net.minecraft.resources.ResourceLocation;
public class DocsTree { public class DocsTree {
private final BranchElement root; private final BranchElement root;
private final Map<ResourceLocation, DocElement> entries = new HashMap<>(); private final Map<Identifier, DocElement> entries = new HashMap<>();
public DocsTree(BranchElement root) { public DocsTree(BranchElement root) {
this.root = root; this.root = root;
@@ -29,7 +30,7 @@ public class DocsTree {
return root; return root;
} }
public DocElement getElement(ResourceLocation id) { public DocElement getElement(Identifier id) {
return entries.get(id); return entries.get(id);
} }
@@ -54,15 +55,15 @@ public class DocsTree {
} }
public static final class DocElement extends Element { public static final class DocElement extends Element {
public static final Codec<DocElement> CODEC = ResourceLocation.CODEC.xmap(DocElement::new, DocElement::getId); public static final Codec<DocElement> CODEC = Identifier.CODEC.xmap(DocElement::new, DocElement::getId);
private final ResourceLocation id; private final Identifier id;
public DocElement(ResourceLocation element) { public DocElement(Identifier element) {
this.id = element; this.id = element;
} }
public ResourceLocation getId() { public Identifier getId() {
return id; return id;
} }
} }
@@ -4,26 +4,27 @@ import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec; import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder; import com.mojang.serialization.codecs.RecordCodecBuilder;
import io.github.skippyall.minions.gui.GuiDisplay; import io.github.skippyall.minions.gui.GuiDisplay;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import net.minecraft.core.RegistryAccess; import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.ComponentSerialization; import net.minecraft.network.chat.ComponentSerialization;
import net.minecraft.resources.Identifier;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.dialog.body.DialogBody; import net.minecraft.server.dialog.body.DialogBody;
import net.minecraft.server.dialog.body.ItemBody; import net.minecraft.server.dialog.body.ItemBody;
import net.minecraft.server.dialog.body.PlainMessage; import net.minecraft.server.dialog.body.PlainMessage;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public record ReferenceEntry(Metadata metadata, ResourceKey<?> object, Component shortDescription, Component longDescription) implements DocsEntry { public record ReferenceEntry(Metadata metadata, ResourceKey<?> object, Component shortDescription, Component longDescription) implements DocsEntry {
private static final Codec<ResourceKey<?>> REGISTRY_KEY_CODEC = RecordCodecBuilder.create(instance -> private static final Codec<ResourceKey<?>> REGISTRY_KEY_CODEC = RecordCodecBuilder.create(instance ->
instance.group( instance.group(
ResourceLocation.CODEC.fieldOf("registry").forGetter(ResourceKey::registry), Identifier.CODEC.fieldOf("registry").forGetter(ResourceKey::registry),
ResourceLocation.CODEC.fieldOf("value").forGetter(ResourceKey::location) Identifier.CODEC.fieldOf("value").forGetter(ResourceKey::identifier)
).apply(instance, (registry, value) -> ResourceKey.create(ResourceKey.createRegistryKey(registry), value)) ).apply(instance, (registry, value) -> ResourceKey.create(ResourceKey.createRegistryKey(registry), value))
); );
@@ -46,9 +47,9 @@ public record ReferenceEntry(Metadata metadata, ResourceKey<?> object, Component
GuiDisplay display = getObjectDisplay(manager); GuiDisplay display = getObjectDisplay(manager);
if(display != null) { if(display != null) {
bodyElements.add(new ItemBody(display.createItemStack(), Optional.empty(), false, false, 16, 16)); bodyElements.add(new ItemBody(display.createItemStackTemplate(), Optional.empty(), false, false, 16, 16));
} }
bodyElements.add(new PlainMessage(Component.translatable(object.location().toLanguageKey(object.registry().getPath())), 200)); bodyElements.add(new PlainMessage(Component.translatable(object.identifier().toLanguageKey(object.registry().getPath())), 200));
bodyElements.add(new PlainMessage(longDescription, 200)); bodyElements.add(new PlainMessage(longDescription, 200));
return bodyElements; return bodyElements;
@@ -59,15 +60,15 @@ public record ReferenceEntry(Metadata metadata, ResourceKey<?> object, Component
if(object.isFor(Registries.ITEM) || object.isFor(Registries.BLOCK)) { if(object.isFor(Registries.ITEM) || object.isFor(Registries.BLOCK)) {
Item item; Item item;
if(object.isFor(Registries.ITEM)) { if(object.isFor(Registries.ITEM)) {
item = BuiltInRegistries.ITEM.getValue(object.location()); item = BuiltInRegistries.ITEM.getValue(object.identifier());
} else { } else {
item = BuiltInRegistries.BLOCK.getValue(object.location()).asItem(); item = BuiltInRegistries.BLOCK.getValue(object.identifier()).asItem();
} }
if(item != null) { if(item != null) {
display = new GuiDisplay.ItemBased(item); display = new GuiDisplay.ItemBased(item);
} }
} else { } else {
ResourceLocation displayId = object.location().withPrefix(object.registry().getPath() + "/"); Identifier displayId = object.identifier().withPrefix(object.registry().getPath() + "/");
display = GuiDisplay.getGuiDisplay(displayId, manager); display = GuiDisplay.getGuiDisplay(displayId, manager);
} }
return display; return display;
@@ -1,41 +1,54 @@
package io.github.skippyall.minions.gui; package io.github.skippyall.minions.gui;
import com.mojang.authlib.properties.PropertyMap;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.registration.MinionRegistries;
import io.github.skippyall.minions.util.TranslationUtil; import io.github.skippyall.minions.util.TranslationUtil;
import it.unimi.dsi.fastutil.objects.ReferenceSortedSets;
import java.util.Optional;
import java.util.UUID;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess; import net.minecraft.core.RegistryAccess;
import net.minecraft.core.UUIDUtil; import net.minecraft.core.UUIDUtil;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.core.component.DataComponents; import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.ItemStackTemplate;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.item.Rarity; import net.minecraft.world.item.Rarity;
import net.minecraft.world.item.component.ResolvableProfile; import net.minecraft.world.item.component.ResolvableProfile;
import net.minecraft.world.item.component.TooltipDisplay; import net.minecraft.world.item.component.TooltipDisplay;
import java.util.LinkedHashSet;
import java.util.UUID;
public interface GuiDisplay { public interface GuiDisplay {
Codec<GuiDisplay> CODEC = MinionRegistries.GUI_DISPLAY_TYPE.byNameCodec().dispatch(GuiDisplay::getCodec, codec -> codec.fieldOf("data")); Codec<GuiDisplay> CODEC = MinionRegistries.GUI_DISPLAY_TYPE.byNameCodec().dispatch(GuiDisplay::getCodec, codec -> codec.fieldOf("data"));
GuiDisplay DEFAULT_DISPLAY = new ItemBased(Items.BARRIER); GuiDisplay DEFAULT_DISPLAY = new ItemBased(Items.BARRIER);
TooltipDisplay TOOLTIP_DISPLAY = createTooltipDisplay();
static GuiDisplay getGuiDisplay(ResourceLocation id, RegistryAccess manager) { private static TooltipDisplay createTooltipDisplay() {
LinkedHashSet<DataComponentType<?>> set = new LinkedHashSet<>();
for(DataComponentType<?> type : BuiltInRegistries.DATA_COMPONENT_TYPE) {
if(type != DataComponents.LORE) {
set.add(type);
}
}
return new TooltipDisplay(false, set);
}
static GuiDisplay getGuiDisplay(Identifier id, RegistryAccess manager) {
return manager.lookup(MinionRegistries.GUI_DISPLAY).map(registry -> registry.getValue(id)).orElse(DEFAULT_DISPLAY); return manager.lookup(MinionRegistries.GUI_DISPLAY).map(registry -> registry.getValue(id)).orElse(DEFAULT_DISPLAY);
} }
static <T> GuiDisplay getGuiDisplayFor(Registry<T> registry, T element, RegistryAccess manager) { static <T> GuiDisplay getGuiDisplayFor(Registry<T> registry, T element, RegistryAccess manager) {
ResourceLocation elementId = registry.getKey(element); Identifier elementId = registry.getKey(element);
if(elementId == null) { if(elementId == null) {
return DEFAULT_DISPLAY; return DEFAULT_DISPLAY;
} }
ResourceLocation displayId = elementId.withPrefix(registry.key().location().getPath() + "/"); Identifier displayId = elementId.withPrefix(registry.key().identifier().getPath() + "/");
return getGuiDisplay(displayId, manager); return getGuiDisplay(displayId, manager);
} }
@@ -50,24 +63,29 @@ public interface GuiDisplay {
return stack; return stack;
} }
ItemStack createItemStack(); ItemStackTemplate createItemStackTemplate();
default ItemStack createItemStack() {
return createItemStackTemplate().create();
}
Codec<? extends GuiDisplay> getCodec(); Codec<? extends GuiDisplay> getCodec();
class ModelBased implements GuiDisplay { class ModelBased implements GuiDisplay {
public static final Codec<ModelBased> CODEC = ResourceLocation.CODEC.xmap(ModelBased::new, display -> display.model); public static final Codec<ModelBased> CODEC = Identifier.CODEC.xmap(ModelBased::new, display -> display.model);
private final ResourceLocation model; private final Identifier model;
public ModelBased(ResourceLocation model) { public ModelBased(Identifier model) {
this.model = model; this.model = model;
} }
@Override @Override
public ItemStack createItemStack() { public ItemStackTemplate createItemStackTemplate() {
ItemStack stack = new ItemStack(Items.BARRIER); return new ItemStackTemplate(Items.BARRIER, DataComponentPatch.builder()
stack.set(DataComponents.ITEM_MODEL, model); .set(DataComponents.ITEM_MODEL, model)
return stack; .build()
);
} }
@Override @Override
@@ -86,11 +104,11 @@ public interface GuiDisplay {
} }
@Override @Override
public ItemStack createItemStack() { public ItemStackTemplate createItemStackTemplate() {
ItemStack stack = new ItemStack(item); return new ItemStackTemplate(item, DataComponentPatch.builder()
stack.set(DataComponents.TOOLTIP_DISPLAY, new TooltipDisplay(true, ReferenceSortedSets.emptySet())); .set(DataComponents.TOOLTIP_DISPLAY, TOOLTIP_DISPLAY)
stack.set(DataComponents.RARITY, Rarity.COMMON); .set(DataComponents.RARITY, Rarity.COMMON)
return stack; .build());
} }
@Override @Override
@@ -109,10 +127,11 @@ public interface GuiDisplay {
} }
@Override @Override
public ItemStack createItemStack() { public ItemStackTemplate createItemStackTemplate() {
ItemStack stack = new ItemStack(Items.PLAYER_HEAD); return new ItemStackTemplate(Items.PLAYER_HEAD, DataComponentPatch.builder()
stack.set(DataComponents.PROFILE, new ResolvableProfile(Optional.empty(), Optional.of(uuid), new PropertyMap())); .set(DataComponents.PROFILE, ResolvableProfile.createUnresolved(uuid))
return stack; .build()
);
} }
@Override @Override
@@ -122,17 +141,17 @@ public interface GuiDisplay {
} }
class StackBased implements GuiDisplay { class StackBased implements GuiDisplay {
public static final Codec<StackBased> CODEC = ItemStack.CODEC.xmap(StackBased::new, StackBased::createItemStack); public static final Codec<StackBased> CODEC = ItemStackTemplate.CODEC.xmap(StackBased::new, StackBased::createItemStackTemplate);
private final ItemStack stack; private final ItemStackTemplate template;
public StackBased(ItemStack stack) { public StackBased(ItemStackTemplate template) {
this.stack = stack; this.template = template;
} }
@Override @Override
public ItemStack createItemStack() { public ItemStackTemplate createItemStackTemplate() {
return stack; return template;
} }
@Override @Override
@@ -1,95 +0,0 @@
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.gui.input.TextInput;
import io.github.skippyall.minions.minion.MinionData;
import io.github.skippyall.minions.minion.MinionItem;
import io.github.skippyall.minions.minion.MinionProfileUtils;
import io.github.skippyall.minions.minion.skin.SkinProvider;
import io.github.skippyall.minions.registration.MinionRegistries;
import io.github.skippyall.minions.registration.SkinProviders;
import java.util.Optional;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.component.ResolvableProfile;
public class MinionLookGui extends SimpleGui {
private ItemStack minionItem;
private SkinProvider currentSkinProvider;
public MinionLookGui(ServerPlayer player, ItemStack minionItem) {
super(MenuType.GENERIC_9x3, player, false);
this.minionItem = minionItem;
this.currentSkinProvider = SkinProviders.NAME;
}
public void update() {
updateName();
updateSkin();
updateSkinProvider();
}
private void updateName() {
setSlot(10, new GuiElementBuilder()
.setItem(Items.OAK_SIGN)
.setName(Component.literal(getData().name()))
.setCallback(() -> {
openRenameGui(player, minionItem);
})
);
}
private void updateSkin() {
GuiElementBuilder builder = new GuiElementBuilder()
.setItem(Items.PLAYER_HEAD)
.setCallback(() -> currentSkinProvider.openSkinMenu(player).thenAccept(skin -> {
MinionItem.setData(player.getServer(), getData().withSkin(skin), minionItem);
}));
if(MinionItem.getData(player.getServer(), minionItem) != null && MinionItem.getData(player.getServer(), minionItem).skin().isPresent()) {
builder.setComponent(DataComponents.PROFILE, new ResolvableProfile(Optional.empty(), Optional.empty(), getData().skin().get()));
}
setSlot(16, builder);
}
private void cycleSkinProvider() {
int currentId = MinionRegistries.SKIN_PROVIDERS.getId(currentSkinProvider);
currentId++;
if(MinionRegistries.SKIN_PROVIDERS.size() == currentId) {
currentId = 0;
}
currentSkinProvider = MinionRegistries.SKIN_PROVIDERS.byId(currentId);
updateSkinProvider();
}
private void updateSkinProvider() {
setSlot(25, new GuiElementBuilder()
.setItem(Items.GREEN_STAINED_GLASS_PANE)
.setComponent(DataComponents.CUSTOM_NAME, currentSkinProvider.getDisplayName())
.setCallback(this::cycleSkinProvider)
);
}
private MinionData getData() {
return MinionItem.getDataOrDefault(player.getServer(), minionItem);
}
public static void open(ServerPlayer player, ItemStack minionItem) {
MinionLookGui gui = new MinionLookGui(player, minionItem);
gui.update();
gui.open();
}
public void openRenameGui(ServerPlayer player, ItemStack minionItem) {
TextInput.inputSync(player, Component.translatable("minions.gui.look.rename.title"), "Minion", name -> MinionProfileUtils.checkMinionNameWithoutPrefix(player.getServer(), name))
.thenAccept(name -> {
MinionItem.setData(player.getServer(), getData().withName(MinionProfileUtils.getPrefix() + name), minionItem);
open();
});
}
}
@@ -0,0 +1,136 @@
package io.github.skippyall.minions.gui
import com.mojang.authlib.GameProfile
import eu.pb4.sgui.api.elements.GuiElementBuilder
import eu.pb4.sgui.api.gui.SimpleGui
import io.github.skippyall.minions.gui.input.TextInput
import io.github.skippyall.minions.minion.MinionData
import io.github.skippyall.minions.minion.MinionItem
import io.github.skippyall.minions.minion.MinionProfileUtils
import io.github.skippyall.minions.minion.skin.SkinProvider
import io.github.skippyall.minions.registration.MinionRegistries
import io.github.skippyall.minions.registration.SkinProviders
import kotlinx.coroutines.launch
import net.fabricmc.fabric.api.entity.FakePlayer
import net.minecraft.core.component.DataComponents
import net.minecraft.network.chat.Component
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.inventory.MenuType
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraft.world.item.component.ResolvableProfile
import java.util.Optional
import java.util.function.Consumer
import java.util.function.Function
class MinionLookGui(
viewer: ServerPlayer,
private val minionItem: ItemStack
) : MinionsGui(viewer) {
private lateinit var gui: SimpleGui
private var currentSkinProvider: SkinProvider = SkinProviders.NAME
private val data: MinionData
get() = MinionItem.getDataOrDefault(viewer.level().server, minionItem)
init {
open()
}
override fun open() {
gui = object : SimpleGui(MenuType.GENERIC_9x3, viewer, false) {
override fun onPlayerClose(success: Boolean) {
onBackingClosed()
}
}
update()
gui.open()
}
override fun closeBacking() {
gui.close()
}
fun update() {
updateName()
updateSkin()
updateSkinProvider()
}
private fun updateName() {
gui.setSlot(
10, GuiElementBuilder()
.setItem(Items.OAK_SIGN)
.setName(Component.literal(this.data.name))
.setCallback(this::openRenameGui)
)
}
private fun updateSkin() {
val builder = GuiElementBuilder()
.setItem(Items.PLAYER_HEAD)
.setCallback(this::openSkinGui)
if (MinionItem.getData(viewer.level().server, minionItem)?.skin?.isPresent ?: false) {
builder.setComponent(
DataComponents.PROFILE,
ResolvableProfile.createResolved(GameProfile(FakePlayer.DEFAULT_UUID, "", this.data.skin.get()))
)
}
gui.setSlot(16, builder)
}
fun openSkinGui() {
currentSkinProvider.openSkinMenu(this)
.thenCompose(Function { profile: ResolvableProfile? ->
profile!!.resolveProfile(
viewer.level().server.services().profileResolver()
)
})
.thenAccept(Consumer { skin: GameProfile? ->
MinionItem.setData(
viewer.level().server, this.data.withSkin(
Optional.of(skin!!.properties())
), minionItem
)
})
}
private fun cycleSkinProvider() {
var currentId = MinionRegistries.SKIN_PROVIDERS.getId(currentSkinProvider)
currentId++
if (MinionRegistries.SKIN_PROVIDERS.size() == currentId) {
currentId = 0
}
currentSkinProvider = MinionRegistries.SKIN_PROVIDERS.byId(currentId)!!
updateSkinProvider()
}
private fun updateSkinProvider() {
gui.setSlot(
25, GuiElementBuilder()
.setItem(Items.GREEN_STAINED_GLASS_PANE)
.setComponent(DataComponents.CUSTOM_NAME, currentSkinProvider.getDisplayName())
.setCallback(Runnable { this.cycleSkinProvider() })
)
}
fun openRenameGui() {
scope.launch {
val newName = TextInput.input(
this@MinionLookGui,
Component.translatable("minions.gui.look.rename.title"),
"Minion",
) { name ->
MinionProfileUtils.checkMinionNameWithoutPrefix(viewer.level().server, name)
}
if(newName != null) {
this@MinionLookGui.data.withName(newName)
}
}
}
}
@@ -1,65 +0,0 @@
package io.github.skippyall.minions.gui;
import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.Nullable;
public abstract class MinionsGui {
protected final @Nullable MinionsGui parent;
protected final ServerPlayer viewer;
protected @Nullable MinionsGui child = null;
private boolean open = true;
public MinionsGui(MinionsGui parent) {
this.viewer = parent.viewer;
this.parent = parent;
parent.child = this;
}
public MinionsGui(ServerPlayer viewer) {
this.viewer = viewer;
this.parent = null;
}
public ServerPlayer getViewer() {
return viewer;
}
protected abstract void open();
protected void reopen() {
open();
}
public void onBackingClosed() {
if(child != null && child.open) {
return;
}
close();
}
public void close() {
if(open) {
if(parent != null) {
parent.child = null;
parent.reopen();
}
closeNoOpen(parent == null);
}
}
private void closeNoOpen(boolean closeBacking) {
if(child != null) {
child.closeNoOpen(closeBacking);
}
if(parent != null) {
parent.child = null;
}
if(closeBacking) {
closeBacking();
}
open = false;
}
protected abstract void closeBacking();
}
@@ -0,0 +1,84 @@
package io.github.skippyall.minions.gui
import eu.pb4.sgui.api.elements.GuiElementBuilder
import kotlinx.coroutines.CompletableJob
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import net.minecraft.network.chat.Component
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.item.Items
abstract class MinionsGui {
protected val parent: MinionsGui?
@JvmField
val viewer: ServerPlayer
protected var child: MinionsGui? = null
private var open = true
private val job: CompletableJob
val scope: CoroutineScope
constructor(parent: MinionsGui) {
this.viewer = parent.viewer
this.parent = parent
parent.child = this
job = Job(parent.job)
scope = CoroutineScope(Dispatchers.Unconfined.plus(CoroutineName("MinionsGui")).plus(job))
}
constructor(viewer: ServerPlayer) {
this.viewer = viewer
this.parent = null
job = Job(null)
scope = CoroutineScope(Dispatchers.Unconfined.plus(CoroutineName("MinionsGui")).plus(job))
}
protected abstract fun open()
protected fun reopen() {
open()
}
fun onBackingClosed() {
if (child != null && child!!.open) {
return
}
close(true)
}
@JvmOverloads
fun close(alreadyClosed: Boolean = false) {
if (open) {
scope.cancel(null)
open = false
if (child != null) {
child!!.close(alreadyClosed)
} else if (!alreadyClosed) {
closeBacking()
}
}
}
fun goBack() {
if (parent != null) {
open = false
parent.child = null
parent.reopen()
close(true)
} else {
close(false)
}
}
fun backButton(): GuiElementBuilder? {
return GuiElementBuilder(Items.MANGROVE_DOOR)
.setName(Component.translatable("gui.back"))
.setCallback(Runnable { this.goBack() })
}
protected abstract fun closeBacking()
}
@@ -2,13 +2,14 @@ package io.github.skippyall.minions.gui;
import eu.pb4.sgui.api.elements.GuiElementBuilder; import eu.pb4.sgui.api.elements.GuiElementBuilder;
import eu.pb4.sgui.api.gui.SimpleGui; import eu.pb4.sgui.api.gui.SimpleGui;
import java.util.List;
import java.util.function.BiFunction;
import net.minecraft.core.IdMap; import net.minecraft.core.IdMap;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import java.util.List;
import java.util.function.BiFunction;
public class PaginatedList extends MinionsGui { public class PaginatedList extends MinionsGui {
private int page = 0; private int page = 0;
private SimpleGui gui; private SimpleGui gui;
@@ -26,13 +27,15 @@ public class PaginatedList extends MinionsGui {
@Override @Override
protected void open() { protected void open() {
gui = new SimpleGui(MenuType.GENERIC_9x4, viewer, false) { gui = new SimpleGui(MenuType.GENERIC_9x6, viewer, false) {
@Override @Override
public void onClose() { public void onPlayerClose(boolean success) {
onBackingClosed(); onBackingClosed();
} }
}; };
gui.setTitle(title); gui.setTitle(title);
gui.setSlot(8, backButton());
addItems(); addItems();
gui.open(); gui.open();
} }
@@ -51,12 +54,14 @@ public class PaginatedList extends MinionsGui {
} }
private void addItems() { private void addItems() {
for(int i = 27 * page; i < Math.min(27 * (page + 1), size); i++) { int slot = 9;
gui.addSlot(display.apply(i, this)); for(int i = 36 * page; i < Math.min(36 * (page + 1), size); i++) {
gui.setSlot(slot, display.apply(i, this));
slot++;
} }
if(page > 0) { if(page > 0) {
gui.setSlot(30, new GuiElementBuilder(Items.SPECTRAL_ARROW) gui.setSlot(48, new GuiElementBuilder(Items.SPECTRAL_ARROW)
.setItemName(Component.translatable("book.page_button.previous")) .setItemName(Component.translatable("book.page_button.previous"))
.setCallback(() -> { .setCallback(() -> {
page--; page--;
@@ -64,11 +69,11 @@ public class PaginatedList extends MinionsGui {
}) })
); );
} else { } else {
gui.clearSlot(30); gui.clearSlot(48);
} }
if(27 * (page + 1) < size) { if(27 * (page + 1) < size) {
gui.setSlot(32, new GuiElementBuilder(Items.ARROW) gui.setSlot(50, new GuiElementBuilder(Items.ARROW)
.setItemName(Component.translatable("book.page_button.next")) .setItemName(Component.translatable("book.page_button.next"))
.setCallback(() -> { .setCallback(() -> {
page++; page++;
@@ -76,7 +81,7 @@ public class PaginatedList extends MinionsGui {
}) })
); );
} else { } else {
gui.clearSlot(32); gui.clearSlot(50);
} }
} }
} }
@@ -6,15 +6,15 @@ 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.gui.MinionsGui; import io.github.skippyall.minions.gui.MinionsGui;
import io.github.skippyall.minions.gui.minion.SimpleMinionsGui; import io.github.skippyall.minions.gui.minion.SimpleMinionsGui;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.Items;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Function; import java.util.function.Function;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.Items;
public class ChoiceInput { public class ChoiceInput {
public static <T> BiFunction<ServerPlayer, T, CompletableFuture<T>> createDialogOpener(MenuType<?> screen, Component title, Function<T, GuiDisplay> displayFunction, T[] values, @Nullable T fallback) { public static <T> BiFunction<ServerPlayer, T, CompletableFuture<T>> createDialogOpener(MenuType<?> screen, Component title, Function<T, GuiDisplay> displayFunction, T[] values, @Nullable T fallback) {
@@ -23,7 +23,7 @@ public class ChoiceInput {
SimpleGui gui = new SimpleGui(screen, player, false) { SimpleGui gui = new SimpleGui(screen, player, false) {
@Override @Override
public void onClose() { public void onPlayerClose(boolean success) {
if(fallback == null) { if(fallback == null) {
future.cancel(false); future.cancel(false);
} else { } else {
@@ -53,7 +53,7 @@ public class ChoiceInput {
SimpleGui gui = new SimpleGui(MenuType.GENERIC_3x3, player, false) { SimpleGui gui = new SimpleGui(MenuType.GENERIC_3x3, player, false) {
@Override @Override
public void onClose() { public void onPlayerClose(boolean success) {
future.cancel(false); future.cancel(false);
} }
}; };
@@ -74,14 +74,14 @@ public class ChoiceInput {
return future; return future;
} }
public static CompletableFuture<Void> confirm(MinionsGui parent, Component title) { public static CompletableFuture<Boolean> confirm(MinionsGui parent, Component title) {
CompletableFuture<Void> future = new CompletableFuture<>(); CompletableFuture<Boolean> future = new CompletableFuture<>();
new SimpleMinionsGui(parent, (onClose, me) -> { new SimpleMinionsGui(parent, (onClose, me) -> {
SimpleGui gui = new SimpleGui(MenuType.GENERIC_3x3, parent.getViewer(), false) { SimpleGui gui = new SimpleGui(MenuType.GENERIC_3x3, parent.viewer, false) {
@Override @Override
public void onClose() { public void onPlayerClose(boolean success) {
future.cancel(false); future.complete(false);
onClose.run(); onClose.run();
} }
}; };
@@ -90,12 +90,18 @@ public class ChoiceInput {
gui.setSlot(3, new GuiElementBuilder(Items.REDSTONE_BLOCK) gui.setSlot(3, new GuiElementBuilder(Items.REDSTONE_BLOCK)
.setName(Component.translatable("minions.gui.abort")) .setName(Component.translatable("minions.gui.abort"))
.setCallback(() -> future.cancel(false)) .setCallback(() -> {
future.complete(false);
me.goBack();
})
); );
gui.setSlot(5, new GuiElementBuilder(Items.EMERALD_BLOCK) gui.setSlot(5, new GuiElementBuilder(Items.EMERALD_BLOCK)
.setName(Component.translatable("minions.gui.confirm")) .setName(Component.translatable("minions.gui.confirm"))
.setCallback(() -> future.complete(null)) .setCallback(() -> {
future.complete(true);
me.goBack();
})
); );
gui.open(); gui.open();
@@ -1,122 +0,0 @@
package io.github.skippyall.minions.gui.input;
import eu.pb4.sgui.api.elements.GuiElementBuilder;
import eu.pb4.sgui.api.gui.AnvilInputGui;
import io.github.skippyall.minions.gui.MinionsGui;
import io.github.skippyall.minions.gui.minion.SimpleMinionsGui;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.inventory.AnvilMenu;
import net.minecraft.world.item.Items;
public class TextInput<T> extends AnvilInputGui {
private final GuiElementBuilder valid = new GuiElementBuilder()
.setItem(Items.EMERALD_BLOCK)
.setName(Component.literal("OK"))
.setCallback(this::onConfirm);
private final GuiElementBuilder invalid = new GuiElementBuilder()
.setItem(Items.REDSTONE_BLOCK);
private final Function<String, CompletableFuture<Result<T, Component>>> parser;
private final CompletableFuture<T> future;
private Result<T, Component> result;
private boolean isConfirm;
public TextInput(ServerPlayer player, Component title, String defaultValue, Function<String, CompletableFuture<Result<T, Component>>> parser, CompletableFuture<T> future) {
super(player, false);
setTitle(title);
setDefaultInputValue(defaultValue);
this.parser = parser;
this.future = future;
updateConfirmButton(defaultValue);
}
public static <T> CompletableFuture<T> inputSync(ServerPlayer player, Component title, String defaultValue, Function<String, Result<T, Component>> parser) {
return input(player, title, defaultValue, (String string) -> CompletableFuture.completedFuture(parser.apply(string)));
}
public static <T> CompletableFuture<T> inputSync(MinionsGui gui, Component title, String defaultValue, Function<String, Result<T, Component>> parser) {
return input(gui, title, defaultValue, (String string) -> CompletableFuture.completedFuture(parser.apply(string)));
}
public static <T> CompletableFuture<T> input(ServerPlayer player, Component title, String defaultValue, Function<String, CompletableFuture<Result<T, Component>>> parser) {
CompletableFuture<T> future = new CompletableFuture<>();
new TextInput<>(player, title, defaultValue, parser, future).open();
return future;
}
public static <T> CompletableFuture<T> input(MinionsGui gui, Component title, String defaultValue, Function<String, CompletableFuture<Result<T, Component>>> parser) {
CompletableFuture<T> future = new CompletableFuture<>();
new SimpleMinionsGui(gui, (onClose, me) -> {
TextInput<T> input = new TextInput<>(gui.getViewer(), title, defaultValue, parser, future);
future.handle((v, e) -> {
onClose.run();
return null;
});
input.open();
return input;
});
return future;
}
public static CompletableFuture<String> inputString(ServerPlayer player, Component title, String defaultValue) {
return inputSync(player, title, defaultValue, Result.Success::new);
}
public static CompletableFuture<String> inputString(MinionsGui gui, Component title, String defaultValue) {
return inputSync(gui, title, defaultValue, Result.Success::new);
}
public static CompletableFuture<Long> inputLong(ServerPlayer player, Component title, String defaultValue) {
return inputSync(player, title, defaultValue, string -> Result.wrapCustomError(() -> Long.valueOf(string), Component.translatable("minions.command.input.int.fail")));
}
public static CompletableFuture<Long> inputLong(MinionsGui gui, Component title, String defaultValue) {
return inputSync(gui, title, defaultValue, string -> Result.wrapCustomError(() -> Long.valueOf(string), Component.translatable("minions.command.input.int.fail")));
}
public static CompletableFuture<Double> inputDouble(ServerPlayer player, Component title, String defaultValue) {
return inputSync(player, title, defaultValue, string -> Result.wrapCustomError(() -> Double.valueOf(string), Component.translatable("minions.command.input.float.fail")));
}
public static CompletableFuture<Double> inputDouble(MinionsGui gui, Component title, String defaultValue) {
return inputSync(gui, title, defaultValue, string -> Result.wrapCustomError(() -> Double.valueOf(string), Component.translatable("minions.command.input.float.fail")));
}
@Override
public void onInput(String input) {
updateConfirmButton(input);
}
public void updateConfirmButton(String input) {
parser.apply(input).thenAccept(result -> {
this.result = result;
if(result.isSuccess()) {
setSlot(AnvilMenu.RESULT_SLOT, valid);
} else {
Component text = result.getErrorOrThrow();
setSlot(AnvilMenu.RESULT_SLOT, invalid.setName(text));
}
});
}
@Override
public void onClose() {
if(!future.isDone() && !isConfirm) {
future.cancel(false);
}
}
public void onConfirm() {
if(result != null) {
result.ifSuccess(success -> {
isConfirm = true;
close();
future.complete(success);
});
}
}
}
@@ -0,0 +1,222 @@
package io.github.skippyall.minions.gui.input
import eu.pb4.sgui.api.elements.GuiElementBuilder
import eu.pb4.sgui.api.gui.AnvilInputGui
import io.github.skippyall.minions.gui.MinionsGui
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.future.asCompletableFuture
import kotlinx.coroutines.launch
import net.minecraft.network.chat.Component
import net.minecraft.world.inventory.AnvilMenu
import net.minecraft.world.item.Items
import java.util.concurrent.CompletableFuture
class TextInput<T>(
parent: MinionsGui,
val title: Component,
val defaultValue: String,
val parser: suspend (String) -> Result<T, Component>
) : MinionsGui(parent) {
private val valid: GuiElementBuilder = GuiElementBuilder()
.setItem(Items.EMERALD_BLOCK)
.setName(Component.literal("OK"))
.setCallback(Runnable { this.onConfirm() })
private val invalid: GuiElementBuilder = GuiElementBuilder()
.setItem(Items.REDSTONE_BLOCK)
private lateinit var gui: AnvilInputGui
private var result: Result<T, Component>? = null
private var isConfirm = false
val job = Job()
init {
updateConfirmButton(defaultValue)
open()
}
override fun open() {
gui = object : AnvilInputGui(viewer, false) {
override fun onInput(input: String) {
updateConfirmButton(input)
}
override fun onPlayerClose(success: Boolean) {
onBackingClosed()
if (job.isActive && !isConfirm) {
job.cancel()
}
}
}
gui.setTitle(title)
gui.setDefaultInputValue(defaultValue)
gui.open()
}
override fun closeBacking() {
gui.close()
}
fun updateConfirmButton(input: String) {
scope.launch {
val result = parser(input)
this@TextInput.result = result
if (result.isSuccess()) {
gui.setSlot(AnvilMenu.RESULT_SLOT, valid)
} else {
val text = result.getErrorOrThrow()
gui.setSlot(AnvilMenu.RESULT_SLOT, invalid.setName(text))
}
}
}
fun onConfirm() {
result?.ifSuccess { _: T? ->
isConfirm = true
}
job.complete()
}
companion object {
@JvmStatic
suspend fun <T>input(
gui: MinionsGui,
title: Component,
defaultValue: String,
parser: suspend (String) -> Result<T, Component>,
): T? {
val input = TextInput(
parent = gui,
title = title,
defaultValue = defaultValue,
parser = parser,
)
input.job.join()
return input.result?.getOrDefault(null)
}
@JvmStatic
fun <T>inputFuture(
gui: MinionsGui,
title: Component,
defaultValue: String,
parser: (String) -> Result<T, Component>,
): CompletableFuture<T?> {
return gui.scope.async {
val input = TextInput(
parent = gui,
title = title,
defaultValue = defaultValue,
parser = parser,
)
input.job.join()
return@async input.result?.getOrDefault(null)
}.asCompletableFuture()
}
@JvmStatic
suspend fun inputString(
gui: MinionsGui,
title: Component,
defaultValue: String,
): String? {
return input<String>(
gui = gui,
title = title,
defaultValue = defaultValue,
parser = { result: String? -> Result.Success<String, Component>(result) },
)
}
@JvmStatic
fun inputStringFuture(
gui: MinionsGui,
title: Component,
defaultValue: String,
): CompletableFuture<String?> {
return gui.scope.async {
inputString(
gui,
title,
defaultValue
)
}.asCompletableFuture()
}
@JvmStatic
suspend fun inputLong(
gui: MinionsGui,
title: Component,
defaultValue: Long,
): Long? {
return input<Long>(
gui = gui,
title = title,
defaultValue = defaultValue.toString(),
parser = { string ->
Result.wrapCustomError<Long, Component>(
{ string.toLong() },
Component.translatable("minions.command.input.int.fail")
)
},
)
}
@JvmStatic
fun inputLongFuture(
gui: MinionsGui,
title: Component,
defaultValue: Long,
): CompletableFuture<Long?> {
return gui.scope.async {
inputLong(
gui,
title,
defaultValue
)
}.asCompletableFuture()
}
@JvmStatic
suspend fun inputDouble(
gui: MinionsGui,
title: Component,
defaultValue: Double,
): Double? {
return input<Double>(
gui = gui,
title = title,
defaultValue = defaultValue.toString(),
parser = { string ->
Result.wrapCustomError<Double, Component>(
{ string.toDouble() },
Component.translatable("minions.command.input.int.fail")
)
},
)
}
@JvmStatic
fun inputDoubleFuture(
gui: MinionsGui,
title: Component,
defaultValue: Double,
): CompletableFuture<Double?> {
return gui.scope.async {
inputDouble(
gui,
title,
defaultValue
)
}.asCompletableFuture()
}
}
}
@@ -23,7 +23,6 @@ import org.jetbrains.annotations.Nullable;
public class ArgumentGui extends MinionsGui { public class ArgumentGui extends MinionsGui {
private final GuiContext.ValueSupplier context; private final GuiContext.ValueSupplier context;
private final MinionFakePlayer minion;
private final ConfiguredInstruction<MinionRuntime> instruction; private final ConfiguredInstruction<MinionRuntime> instruction;
private final Parameter<?> parameter; private final Parameter<?> parameter;
@@ -34,7 +33,6 @@ public class ArgumentGui extends MinionsGui {
public ArgumentGui(MinionsGui parent, GuiContext.ValueSupplier context) { public ArgumentGui(MinionsGui parent, GuiContext.ValueSupplier context) {
super(parent); super(parent);
minion = context.getMinion();
instruction = context.getInstruction(); instruction = context.getInstruction();
this.parameter = context.getParameter(); this.parameter = context.getParameter();
this.context = context; this.context = context;
@@ -61,7 +59,7 @@ public class ArgumentGui extends MinionsGui {
protected void open() { protected void open() {
gui = new SimpleGui(MenuType.GENERIC_3x3, viewer, false) { gui = new SimpleGui(MenuType.GENERIC_3x3, viewer, false) {
@Override @Override
public void onClose() { public void onPlayerClose(boolean success) {
onBackingClosed(); onBackingClosed();
} }
}; };
@@ -71,6 +69,8 @@ public class ArgumentGui extends MinionsGui {
Component.translatable(TranslationUtil.getTranslationKey(parameter.type(), MinionRegistries.VALUE_TYPES)) Component.translatable(TranslationUtil.getTranslationKey(parameter.type(), MinionRegistries.VALUE_TYPES))
)); ));
gui.setSlot(2, backButton());
updateTypeConfiguration(); updateTypeConfiguration();
updateArgumentConfiguration(); updateArgumentConfiguration();
updateConverterConfiguration(); updateConverterConfiguration();
@@ -102,12 +102,7 @@ public class ArgumentGui extends MinionsGui {
.setName(Component.translatable("minions.gui.instruction.argument.configure.data")) .setName(Component.translatable("minions.gui.instruction.argument.configure.data"))
.addLoreLine(getArgument() != null ? getArgument().getDisplayText() : Component.translatable("minions.gui.not_set")) .addLoreLine(getArgument() != null ? getArgument().getDisplayText() : Component.translatable("minions.gui.not_set"))
.setCallback(() -> argumentType.openConfiguration(this, parameter.type(), getArgument()) .setCallback(() -> argumentType.openConfiguration(this, parameter.type(), getArgument())
.thenAccept(newArgument -> { .thenAccept(this::setArgument)
setArgument(newArgument);
if(child != null) {
child.close();
}
})
) )
); );
} }
@@ -149,7 +144,7 @@ public class ArgumentGui extends MinionsGui {
new GuiElementBuilder(GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_SUPPLIER_TYPES, type, viewer.registryAccess())) new GuiElementBuilder(GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_SUPPLIER_TYPES, type, viewer.registryAccess()))
.setCallback(() -> { .setCallback(() -> {
setArgumentType(type); setArgumentType(type);
me.close(); me.goBack();
}) })
); );
} }
@@ -13,6 +13,7 @@ import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
import io.github.skippyall.minions.program.instruction.ConfiguredInstructionListener; import io.github.skippyall.minions.program.instruction.ConfiguredInstructionListener;
import io.github.skippyall.minions.program.supplier.Parameter; import io.github.skippyall.minions.program.supplier.Parameter;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ClientboundSoundEntityPacket;
import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.MenuType;
@@ -42,14 +43,14 @@ public class ConfigureInstructionGui extends MinionsGui implements ConfiguredIns
protected void open() { protected void open() {
gui = new SimpleGui(MenuType.GENERIC_9x3, viewer, false) { gui = new SimpleGui(MenuType.GENERIC_9x3, viewer, false) {
@Override @Override
public void onClose() { public void onPlayerClose(boolean success) {
onBackingClosed(); onBackingClosed();
} }
}; };
gui.setTitle(Component.literal(name)); gui.setTitle(Component.literal(name));
gui.setSlot(7, new GuiElementBuilder(Items.ANVIL) gui.setSlot(6, new GuiElementBuilder(Items.ANVIL)
.setName(Component.translatable("minions.gui.instruction.configure.rename")) .setName(Component.translatable("minions.gui.instruction.configure.rename"))
.setCallback(() -> InstructionGui.inputInstructionName(this, context, name).thenAccept(newName -> { .setCallback(() -> InstructionGui.inputInstructionName(this, context, name).thenAccept(newName -> {
minion.getInstructionManager().setInstructionName(name, newName); minion.getInstructionManager().setInstructionName(name, newName);
@@ -57,15 +58,19 @@ public class ConfigureInstructionGui extends MinionsGui implements ConfiguredIns
})) }))
); );
gui.setSlot(8, new GuiElementBuilder(Items.LAVA_BUCKET) gui.setSlot(7, new GuiElementBuilder(Items.LAVA_BUCKET)
.setName(Component.translatable("minions.gui.instruction.configure.delete")) .setName(Component.translatable("minions.gui.instruction.configure.delete"))
.setCallback(() -> ChoiceInput.confirm(this, Component.translatable("minions.gui.instruction.configure.delete.confirm", name)) .setCallback(() -> ChoiceInput.confirm(this, Component.translatable("minions.gui.instruction.configure.delete.confirm", name))
.thenAccept(v -> { .thenAccept((confirmed) -> {
if(confirmed) {
minion.getInstructionManager().removeInstruction(name); minion.getInstructionManager().removeInstruction(name);
close(); goBack();
}
})) }))
); );
gui.setSlot(8, backButton());
updateSuppliers(); updateSuppliers();
gui.setSlot(13, InstructionGui.createInstructionElement(instruction.getInstruction(), viewer.registryAccess())); gui.setSlot(13, InstructionGui.createInstructionElement(instruction.getInstruction(), viewer.registryAccess()));
@@ -75,7 +80,7 @@ public class ConfigureInstructionGui extends MinionsGui implements ConfiguredIns
.addLoreLine(Component.translatable("minions.gui.instruction.configure.copy.description")) .addLoreLine(Component.translatable("minions.gui.instruction.configure.copy.description"))
.setCallback(() -> { .setCallback(() -> {
viewer.getInventory().placeItemBackInInventory(ClipboardItem.createInstructionReference(minion, name), true); viewer.getInventory().placeItemBackInInventory(ClipboardItem.createInstructionReference(minion, name), true);
viewer.playNotifySound(SoundEvents.NOTE_BLOCK_CHIME.value(), SoundSource.BLOCKS, 1, 1); viewer.connection.send(new ClientboundSoundEntityPacket(SoundEvents.NOTE_BLOCK_CHIME, SoundSource.BLOCKS, viewer, 1, 1, 0));
}) })
); );
@@ -44,7 +44,7 @@ public class ConverterGui extends MinionsGui {
protected void open() { protected void open() {
gui = new SimpleGui(MenuType.GENERIC_3x3, viewer, false) { gui = new SimpleGui(MenuType.GENERIC_3x3, viewer, false) {
@Override @Override
public void onClose() { public void onPlayerClose(boolean success) {
onBackingClosed(); onBackingClosed();
} }
}; };
@@ -53,15 +53,11 @@ public class ConverterGui extends MinionsGui {
updateTypeDisplay(); updateTypeDisplay();
updateConverterDisplay(); updateConverterDisplay();
gui.setSlot(8, backButton());
gui.open(); gui.open();
} }
@Override
protected void reopen() {
gui.open();
}
private void updateTypeDisplay() { private void updateTypeDisplay() {
gui.setSlot(3, new GuiElementBuilder(GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_CONVERTER_TYPES, valueConverterType, viewer.registryAccess())) gui.setSlot(3, new GuiElementBuilder(GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_CONVERTER_TYPES, valueConverterType, viewer.registryAccess()))
.setCallback(this::configureType) .setCallback(this::configureType)
@@ -106,7 +102,7 @@ public class ConverterGui extends MinionsGui {
GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_CONVERTER_TYPES, type, viewer.registryAccess()) GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_CONVERTER_TYPES, type, viewer.registryAccess())
).setCallback(() -> { ).setCallback(() -> {
setType(type); setType(type);
me.close(); me.goBack();
}) })
); );
} }
@@ -114,12 +110,7 @@ public class ConverterGui extends MinionsGui {
private void configureData() { private void configureData() {
if(valueConverterType != null) { if(valueConverterType != null) {
valueConverterType.configure(this, from, to, converter) valueConverterType.configure(this, from, to, converter)
.thenAccept(newConverter -> { .thenAccept(this::setConverter);
setConverter(newConverter);
if(child != null) {
child.close();
}
});
} }
} }
@@ -34,7 +34,7 @@ public class ConverterListGui extends MinionsGui {
protected void open() { protected void open() {
gui = new SimpleGui(MenuType.GENERIC_9x3, viewer, false) { gui = new SimpleGui(MenuType.GENERIC_9x3, viewer, false) {
@Override @Override
public void onClose() { public void onPlayerClose(boolean success) {
onBackingClosed(); onBackingClosed();
} }
}; };
@@ -61,6 +61,8 @@ public class ConverterListGui extends MinionsGui {
}) })
); );
gui.setSlot(8, backButton());
gui.open(); gui.open();
} }
@@ -18,30 +18,31 @@ import io.github.skippyall.minions.program.supplier.ValueSupplier;
import io.github.skippyall.minions.registration.MinionComponentTypes; import io.github.skippyall.minions.registration.MinionComponentTypes;
import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.registration.MinionRegistries;
import io.github.skippyall.minions.util.TranslationUtil; import io.github.skippyall.minions.util.TranslationUtil;
import org.jetbrains.annotations.Nullable;
import java.util.NoSuchElementException;
import java.util.concurrent.CompletableFuture;
import net.minecraft.core.RegistryAccess; import net.minecraft.core.RegistryAccess;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import org.jetbrains.annotations.Nullable;
import java.util.NoSuchElementException;
import java.util.concurrent.CompletableFuture;
public class InstructionGui { public class InstructionGui {
public static MinionsGui openInstructionMainMenu(MinionsGui parent, GuiContext.Minion context) { public static void openInstructionMainMenu(MinionsGui parent, GuiContext.Minion context) {
return new SimpleMinionsGui(parent, (onClose, me) -> { new SimpleMinionsGui(parent, (onClose, me) -> {
ServerPlayer player = parent.getViewer(); ServerPlayer player = parent.viewer;
SimpleGui gui = new SimpleGui(MenuType.GENERIC_3x3, player, false) { SimpleGui gui = new SimpleGui(MenuType.GENERIC_3x3, player, false) {
@Override @Override
public void onClose() { public void onPlayerClose(boolean success) {
onClose.run(); onClose.run();
} }
}; };
gui.setTitle(Component.translatable("minions.gui.instruction.title")); gui.setTitle(Component.translatable("minions.gui.instruction.title"));
gui.setSlot(2, me.backButton());
gui.setSlot(3, new GuiElementBuilder() gui.setSlot(3, new GuiElementBuilder()
.setItem(Items.BOOK) .setItem(Items.BOOK)
.setName(Component.translatable("minions.gui.instruction.list")) .setName(Component.translatable("minions.gui.instruction.list"))
@@ -60,7 +61,7 @@ public class InstructionGui {
public static void createNewInstruction(MinionsGui parent, GuiContext.Minion context) { public static void createNewInstruction(MinionsGui parent, GuiContext.Minion context) {
MinionFakePlayer minion = context.getMinion(); MinionFakePlayer minion = context.getMinion();
ServerPlayer viewer = parent.getViewer(); ServerPlayer viewer = parent.viewer;
selectInstructionModuleMenu(parent, context).thenAccept(instructionType -> selectInstructionModuleMenu(parent, context).thenAccept(instructionType ->
inputInstructionName(parent, context, "Instruction").thenAccept(name -> { inputInstructionName(parent, context, "Instruction").thenAccept(name -> {
if (!minion.isRemoved() && !minion.hasDisconnected()) { if (!minion.isRemoved() && !minion.hasDisconnected()) {
@@ -72,7 +73,7 @@ public class InstructionGui {
} }
public static CompletableFuture<String> inputInstructionName(MinionsGui parent, GuiContext.Minion context, String defaultValue) { public static CompletableFuture<String> inputInstructionName(MinionsGui parent, GuiContext.Minion context, String defaultValue) {
return TextInput.inputSync(parent, Component.translatable("minions.gui.instruction.enter_name"), defaultValue, name -> { return TextInput.inputFuture(parent, Component.translatable("minions.gui.instruction.enter_name"), defaultValue, name -> {
if (context.getMinion().getInstructionManager().hasInstruction(name)) { if (context.getMinion().getInstructionManager().hasInstruction(name)) {
return new Result.Error<>(Component.translatable("minions.gui.instruction.name_already_used")); return new Result.Error<>(Component.translatable("minions.gui.instruction.name_already_used"));
} }
@@ -91,7 +92,7 @@ public class InstructionGui {
public static CompletableFuture<InstructionType<MinionRuntime>> selectInstructionModuleMenu(MinionsGui parent, GuiContext.Minion context) { public static CompletableFuture<InstructionType<MinionRuntime>> selectInstructionModuleMenu(MinionsGui parent, GuiContext.Minion context) {
MinionFakePlayer minion = context.getMinion(); MinionFakePlayer minion = context.getMinion();
ServerPlayer viewer = parent.getViewer(); ServerPlayer viewer = parent.viewer;
if (minion.getModuleInventory().getModules().isEmpty()) { if (minion.getModuleInventory().getModules().isEmpty()) {
viewer.sendSystemMessage(Component.translatable("minions.gui.instruction.no_modules")); viewer.sendSystemMessage(Component.translatable("minions.gui.instruction.no_modules"));
@@ -101,9 +102,9 @@ public class InstructionGui {
CompletableFuture<InstructionType<MinionRuntime>> future = new CompletableFuture<>(); CompletableFuture<InstructionType<MinionRuntime>> future = new CompletableFuture<>();
new SimpleMinionsGui(parent, (closeHandler, me) -> { new SimpleMinionsGui(parent, (closeHandler, me) -> {
SimpleGui gui = new SimpleGui(MenuType.GENERIC_9x3, viewer, false) { SimpleGui gui = new SimpleGui(MenuType.GENERIC_9x4, viewer, false) {
@Override @Override
public void onClose() { public void onPlayerClose(boolean success) {
if (!future.isDone()) { if (!future.isDone()) {
future.cancel(false); future.cancel(false);
} }
@@ -112,11 +113,13 @@ public class InstructionGui {
}; };
gui.setTitle(Component.translatable("minions.gui.instruction.select_instruction")); gui.setTitle(Component.translatable("minions.gui.instruction.select_instruction"));
gui.setSlot(8, me.backButton());
for (int i = 0; i < minion.getModuleInventory().getContainerSize(); i++) { for (int i = 0; i < minion.getModuleInventory().getContainerSize(); i++) {
ItemStack moduleItem = minion.getModuleInventory().getItem(i); ItemStack moduleItem = minion.getModuleInventory().getItem(i);
MinionModule module = moduleItem.get(MinionComponentTypes.MODULE); MinionModule module = moduleItem.get(MinionComponentTypes.MODULE);
if (module != null && !module.instructions().isEmpty()) { if (module != null && !module.instructions().isEmpty()) {
gui.addSlot(new GuiElementBuilder(moduleItem) gui.setSlot(i + 9, new GuiElementBuilder(moduleItem)
.setCallback(() -> selectInstructionMenu(parent, context, module) .setCallback(() -> selectInstructionMenu(parent, context, module)
.thenApply(future::complete) .thenApply(future::complete)
) )
@@ -134,9 +137,9 @@ public class InstructionGui {
CompletableFuture<InstructionType<MinionRuntime>> future = new CompletableFuture<>(); CompletableFuture<InstructionType<MinionRuntime>> future = new CompletableFuture<>();
new SimpleMinionsGui(parent, (closeHandler, me) -> { new SimpleMinionsGui(parent, (closeHandler, me) -> {
SimpleGui gui = new SimpleGui(MenuType.GENERIC_9x3, parent.getViewer(), false) { SimpleGui gui = new SimpleGui(MenuType.GENERIC_9x4, parent.viewer, false) {
@Override @Override
public void onClose() { public void onPlayerClose(boolean success) {
if (!future.isDone()) { if (!future.isDone()) {
future.cancel(false); future.cancel(false);
} }
@@ -145,10 +148,13 @@ public class InstructionGui {
}; };
gui.setTitle(Component.translatable("minions.gui.instruction.select_instruction")); gui.setTitle(Component.translatable("minions.gui.instruction.select_instruction"));
gui.setSlot(8, me.backButton());
int slot = 9;
for (InstructionType<MinionRuntime> instructionType : module.instructions()) { for (InstructionType<MinionRuntime> instructionType : module.instructions()) {
gui.addSlot(createInstructionElement(instructionType, parent.getViewer().registryAccess()) gui.setSlot(slot, createInstructionElement(instructionType, parent.viewer.registryAccess())
.setCallback(() -> future.complete(instructionType)) .setCallback(() -> future.complete(instructionType))
); );
slot++;
} }
gui.open(); gui.open();
@@ -33,19 +33,16 @@ public class InstructionListGui extends MinionsGui implements MinionListener {
@Override @Override
protected void open() { protected void open() {
minion.addMinionListener(this); minion.addMinionListener(this);
gui = new SimpleGui(MenuType.GENERIC_9x3, viewer, false) { gui = new SimpleGui(MenuType.GENERIC_9x4, viewer, false) {
@Override @Override
public void onClose() { public void onPlayerClose(boolean success) {
onBackingClosed(); onBackingClosed();
} }
}; };
gui.setTitle(Component.translatable("minions.gui.instruction.title")); gui.setTitle(Component.translatable("minions.gui.instruction.title"));
resetInstructionList();
gui.open();
}
@Override gui.setSlot(8, backButton());
protected void reopen() { resetInstructionList();
gui.open(); gui.open();
} }
@@ -56,7 +53,7 @@ public class InstructionListGui extends MinionsGui implements MinionListener {
} }
private void resetInstructionList() { private void resetInstructionList() {
int i = 0; int i = 9;
for (String instructionName : minion.getInstructionManager().getInstructionNames()) { for (String instructionName : minion.getInstructionManager().getInstructionNames()) {
ConfiguredInstruction<MinionRuntime> instruction = minion.getInstructionManager().getInstruction(instructionName); ConfiguredInstruction<MinionRuntime> instruction = minion.getInstructionManager().getInstruction(instructionName);
gui.setSlot(i, new GuiElementBuilder(GuiDisplay.getGuiDisplayFor(MinionRegistries.INSTRUCTION_TYPES, instruction.getInstruction(), viewer.registryAccess()).createItemStack()) gui.setSlot(i, new GuiElementBuilder(GuiDisplay.getGuiDisplayFor(MinionRegistries.INSTRUCTION_TYPES, instruction.getInstruction(), viewer.registryAccess()).createItemStack())
@@ -23,7 +23,7 @@ public class GuiContextImpl implements GuiContext {
private final MinionFakePlayer minion; private final MinionFakePlayer minion;
public MinionImpl(GuiContext context, MinionFakePlayer minion) { public MinionImpl(GuiContext context, MinionFakePlayer minion) {
super(context); super(context instanceof DelegatingGuiContextImpl<?> impl ? impl.context : context);
this.minion = minion; this.minion = minion;
} }
@@ -38,7 +38,7 @@ public class GuiContextImpl implements GuiContext {
private String name; private String name;
public InstructionImpl(GuiContext.Minion context, ConfiguredInstruction<MinionRuntime> instruction, String name) { public InstructionImpl(GuiContext.Minion context, ConfiguredInstruction<MinionRuntime> instruction, String name) {
super(context); super(context instanceof DelegatingMinionImpl<?> impl ? impl.context : context);
this.instruction = instruction; this.instruction = instruction;
this.name = name; this.name = name;
} }
@@ -63,7 +63,7 @@ public class GuiContextImpl implements GuiContext {
private final Parameter<?> parameter; private final Parameter<?> parameter;
public ValueSupplierImpl(GuiContext.Instruction context, Parameter<?> parameter) { public ValueSupplierImpl(GuiContext.Instruction context, Parameter<?> parameter) {
super(context); super(context instanceof DelegatingInstructionImpl<?> impl ? impl.context : context);
this.parameter = parameter; this.parameter = parameter;
} }
@@ -31,7 +31,7 @@ public class MinionGui extends MinionsGui implements MinionListener {
protected void open() { protected void open() {
gui = new SimpleGui(MenuType.GENERIC_3x3, viewer, false) { gui = new SimpleGui(MenuType.GENERIC_3x3, viewer, false) {
@Override @Override
public void onClose() { public void onPlayerClose(boolean success) {
onBackingClosed(); onBackingClosed();
} }
}; };
@@ -65,11 +65,6 @@ public class MinionGui extends MinionsGui implements MinionListener {
gui.open(); gui.open();
} }
@Override
protected void reopen() {
gui.open();
}
@Override @Override
protected void closeBacking() { protected void closeBacking() {
gui.close(); gui.close();
@@ -29,7 +29,7 @@ public class MinionInventoryGui extends MinionsGui {
protected void open() { protected void open() {
gui = new SimpleGui(MenuType.GENERIC_9x6, viewer, false) { gui = new SimpleGui(MenuType.GENERIC_9x6, viewer, false) {
@Override @Override
public void onClose() { public void onPlayerClose(boolean success) {
onBackingClosed(); onBackingClosed();
} }
}; };
@@ -45,18 +45,20 @@ public class MinionInventoryGui extends MinionsGui {
gui.setSlot(5, new ItemStack(Items.LEATHER_BOOTS)); gui.setSlot(5, new ItemStack(Items.LEATHER_BOOTS));
gui.setSlot(6, new ItemStack(Items.SHIELD)); gui.setSlot(6, new ItemStack(Items.SHIELD));
gui.setSlotRedirect(2 + 9, new ArmorSlot(minion.getInventory(), minion, EquipmentSlot.HEAD, EquipmentSlot.HEAD.getIndex(Inventory.INVENTORY_SIZE), 0, 0, null)); gui.setSlot(8, backButton());
gui.setSlotRedirect(3 + 9, new ArmorSlot(minion.getInventory(), minion, EquipmentSlot.CHEST, EquipmentSlot.CHEST.getIndex(Inventory.INVENTORY_SIZE), 0, 0, null));
gui.setSlotRedirect(4 + 9, new ArmorSlot(minion.getInventory(), minion, EquipmentSlot.LEGS, EquipmentSlot.LEGS.getIndex(Inventory.INVENTORY_SIZE), 0, 0, null)); gui.setSlot(2 + 9, new ArmorSlot(minion.getInventory(), minion, EquipmentSlot.HEAD, EquipmentSlot.HEAD.getIndex(Inventory.INVENTORY_SIZE), 0, 0, null));
gui.setSlotRedirect(5 + 9, new ArmorSlot(minion.getInventory(), minion, EquipmentSlot.FEET, EquipmentSlot.FEET.getIndex(Inventory.INVENTORY_SIZE), 0, 0, null)); gui.setSlot(3 + 9, new ArmorSlot(minion.getInventory(), minion, EquipmentSlot.CHEST, EquipmentSlot.CHEST.getIndex(Inventory.INVENTORY_SIZE), 0, 0, null));
gui.setSlotRedirect(6 + 9, new Slot(minion.getInventory(), Inventory.SLOT_OFFHAND, 0, 0)); gui.setSlot(4 + 9, new ArmorSlot(minion.getInventory(), minion, EquipmentSlot.LEGS, EquipmentSlot.LEGS.getIndex(Inventory.INVENTORY_SIZE), 0, 0, null));
gui.setSlot(5 + 9, new ArmorSlot(minion.getInventory(), minion, EquipmentSlot.FEET, EquipmentSlot.FEET.getIndex(Inventory.INVENTORY_SIZE), 0, 0, null));
gui.setSlot(6 + 9, new Slot(minion.getInventory(), Inventory.SLOT_OFFHAND, 0, 0));
for (int i = Inventory.SELECTION_SIZE; i < Inventory.INVENTORY_SIZE; i++) { for (int i = Inventory.SELECTION_SIZE; i < Inventory.INVENTORY_SIZE; i++) {
gui.setSlotRedirect(i + 9, new Slot(minion.getInventory(), i, 0, 0)); gui.setSlot(i + 9, new Slot(minion.getInventory(), i, 0, 0));
} }
for (int i = 0; i < Inventory.SELECTION_SIZE; i++) { for (int i = 0; i < Inventory.SELECTION_SIZE; i++) {
gui.setSlotRedirect(i + 45, new Slot(minion.getInventory(), i, 0, 0)); gui.setSlot(i + 45, new Slot(minion.getInventory(), i, 0, 0));
} }
gui.open(); gui.open();
} }
@@ -1,15 +1,15 @@
package io.github.skippyall.minions.gui.minion; package io.github.skippyall.minions.gui.minion;
import eu.pb4.sgui.api.gui.GuiInterface; import eu.pb4.sgui.api.gui.GuiLike;
import io.github.skippyall.minions.gui.MinionsGui; import io.github.skippyall.minions.gui.MinionsGui;
import java.util.function.BiFunction; import java.util.function.BiFunction;
public class SimpleMinionsGui extends MinionsGui { public class SimpleMinionsGui extends MinionsGui {
private GuiInterface gui; private GuiLike gui;
private final BiFunction<Runnable, SimpleMinionsGui, GuiInterface> guiFactory; private final BiFunction<Runnable, SimpleMinionsGui, GuiLike> guiFactory;
public SimpleMinionsGui(MinionsGui parent, BiFunction<Runnable, SimpleMinionsGui, GuiInterface> guiFactory) { public SimpleMinionsGui(MinionsGui parent, BiFunction<Runnable, SimpleMinionsGui, GuiLike> guiFactory) {
super(parent); super(parent);
this.guiFactory = guiFactory; this.guiFactory = guiFactory;
open(); open();
@@ -1,13 +1,15 @@
package io.github.skippyall.minions.listener; package io.github.skippyall.minions.listener;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import net.minecraft.core.Registry;
import net.minecraft.resources.Identifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CopyOnWriteArraySet;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation;
public class SerializableListenerManager<T extends SerializableListenerManager.SerializableListener> extends ListenerManager<T> { public class SerializableListenerManager<T extends SerializableListenerManager.SerializableListener> extends ListenerManager<T> {
public SerializableListenerManager() { public SerializableListenerManager() {
@@ -20,7 +22,7 @@ public class SerializableListenerManager<T extends SerializableListenerManager.S
public static <T extends SerializableListener> Codec<SerializableListenerManager<T>> getCodec(Registry<Codec<? extends T>> registry) { public static <T extends SerializableListener> Codec<SerializableListenerManager<T>> getCodec(Registry<Codec<? extends T>> registry) {
return registry.byNameCodec().<T>dispatch( return registry.byNameCodec().<T>dispatch(
listener -> listener.getCodecId().map(registry::getValue).orElse(Codec.unit(null)), listener -> listener.getCodecId().map(registry::getValue).orElse(MapCodec.unitCodec(null)),
codec -> codec.fieldOf("data") codec -> codec.fieldOf("data")
).listOf().xmap( ).listOf().xmap(
list -> new SerializableListenerManager<>(new CopyOnWriteArraySet<>(list)), list -> new SerializableListenerManager<>(new CopyOnWriteArraySet<>(list)),
@@ -37,7 +39,7 @@ public class SerializableListenerManager<T extends SerializableListenerManager.S
} }
public interface SerializableListener { public interface SerializableListener {
default Optional<ResourceLocation> getCodecId() { default Optional<Identifier> getCodecId() {
return Optional.empty(); return Optional.empty();
} }
} }
@@ -2,10 +2,11 @@ package io.github.skippyall.minions.minion;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.registration.MinionRegistries;
import net.minecraft.resources.Identifier;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import net.minecraft.resources.ResourceLocation;
public class MinionConfig { public class MinionConfig {
public static final Codec<MinionConfig> CODEC = Codec.<Option<?>, Object>dispatchedMap( public static final Codec<MinionConfig> CODEC = Codec.<Option<?>, Object>dispatchedMap(
@@ -43,11 +44,11 @@ public class MinionConfig {
return Objects.hashCode(values); return Objects.hashCode(values);
} }
public static Option<Boolean> booleanOption(ResourceLocation key, boolean defaultValue) { public static Option<Boolean> booleanOption(Identifier key, boolean defaultValue) {
return new Option<>(key, defaultValue, Codec.BOOL); return new Option<>(key, defaultValue, Codec.BOOL);
} }
public record Option<T>(ResourceLocation key, T defaultValue, Codec<T> codec) { public record Option<T>(Identifier key, T defaultValue, Codec<T> codec) {
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (!(o instanceof Option<?> option)) return false; if (!(o instanceof Option<?> option)) return false;
@@ -1,13 +1,14 @@
package io.github.skippyall.minions.minion; package io.github.skippyall.minions.minion;
import eu.pb4.polymer.core.api.item.PolymerItem; import eu.pb4.polymer.core.api.item.PolymerItem;
import eu.pb4.polymer.core.api.item.PolymerItemUtils;
import io.github.skippyall.minions.gui.MinionLookGui; import io.github.skippyall.minions.gui.MinionLookGui;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.registration.MinionComponentTypes; import io.github.skippyall.minions.registration.MinionComponentTypes;
import net.fabricmc.fabric.api.networking.v1.context.PacketContext;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.component.DataComponents; import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
@@ -23,7 +24,6 @@ import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec2;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.nucleoid.packettweaker.PacketContext;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -33,7 +33,7 @@ public class MinionItem extends Item implements PolymerItem {
} }
@Override @Override
public @Nullable ResourceLocation getPolymerItemModel(ItemStack stack, PacketContext context) { public @Nullable Identifier getPolymerItemModel(ItemStack stack, PacketContext context, HolderLookup.Provider lookup) {
return null; return null;
} }
@@ -43,25 +43,25 @@ public class MinionItem extends Item implements PolymerItem {
} }
@Override @Override
public ItemStack getPolymerItemStack(ItemStack stack, TooltipFlag tooltipType, PacketContext player) { public ItemStack getPolymerItemStack(ItemStack stack, TooltipFlag tooltipType, PacketContext player, HolderLookup.Provider lookup) {
ItemStack out = PolymerItemUtils.createItemStack(stack, tooltipType, player); ItemStack out = PolymerItem.super.getPolymerItemStack(stack, tooltipType, player, lookup);
out.set(DataComponents.ENCHANTMENT_GLINT_OVERRIDE, true); out.set(DataComponents.ENCHANTMENT_GLINT_OVERRIDE, true);
return out; return out;
} }
@Override @Override
public void appendHoverText(ItemStack stack, TooltipContext context, TooltipDisplay component, Consumer<Component> tooltip, TooltipFlag type) { public void appendHoverText(ItemStack stack, TooltipContext context, TooltipDisplay component, Consumer<Component> tooltip, TooltipFlag type) {
MinionData data = null /*getData(stack)*/; //MinionData data = getData(stack);
if(data != null) { //if(data != null) {
tooltip.accept(Component.translatable("minions.minion_item.tooltip", data.name())); // tooltip.accept(Component.translatable("minions.minion_item.tooltip", data.name()));
} //}
} }
@Override @Override
public InteractionResult use(Level world, Player user, InteractionHand hand) { public InteractionResult use(Level world, Player user, InteractionHand hand) {
if(user instanceof ServerPlayer serverPlayer) { if(user instanceof ServerPlayer serverPlayer) {
ItemStack stack = user.getItemInHand(hand); ItemStack stack = user.getItemInHand(hand);
MinionLookGui.open(serverPlayer, stack); new MinionLookGui(serverPlayer, stack);
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
} }
@@ -70,7 +70,7 @@ public class MinionItem extends Item implements PolymerItem {
@Override @Override
public InteractionResult useOn(UseOnContext context) { public InteractionResult useOn(UseOnContext context) {
if(!context.getLevel().isClientSide) { if(!context.getLevel().isClientSide()) {
MinionData data = getDataOrDefault(context.getLevel().getServer(), context.getItemInHand()); MinionData data = getDataOrDefault(context.getLevel().getServer(), context.getItemInHand());
MinionFakePlayer.spawnMinion(data, (ServerLevel) context.getLevel(), context.getClickedPos().getCenter().add(0,0.5,0), new Vec2(0, 0)); MinionFakePlayer.spawnMinion(data, (ServerLevel) context.getLevel(), context.getClickedPos().getCenter().add(0,0.5,0), new Vec2(0, 0));
} }
@@ -1,6 +1,8 @@
package io.github.skippyall.minions.minion; package io.github.skippyall.minions.minion;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import io.github.skippyall.minions.Minions;
import net.minecraft.resources.Identifier;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.saveddata.SavedData; import net.minecraft.world.level.saveddata.SavedData;
@@ -14,7 +16,12 @@ import java.util.UUID;
public class MinionPersistentState extends SavedData { public class MinionPersistentState extends SavedData {
public static final Codec<MinionPersistentState> CODEC = MinionData.CODEC.listOf().xmap(MinionPersistentState::new, MinionPersistentState::getMinionDataList); public static final Codec<MinionPersistentState> CODEC = MinionData.CODEC.listOf().xmap(MinionPersistentState::new, MinionPersistentState::getMinionDataList);
public static SavedDataType<MinionPersistentState> TYPE = new SavedDataType<>("minion", MinionPersistentState::new, MinionPersistentState.CODEC, null); public static SavedDataType<MinionPersistentState> TYPE = new SavedDataType<>(
Identifier.fromNamespaceAndPath(Minions.MOD_ID, "minion"),
MinionPersistentState::new,
MinionPersistentState.CODEC,
null
);
private final Map<UUID, MinionData> minionData = new HashMap<>(); private final Map<UUID, MinionData> minionData = new HashMap<>();
@@ -22,10 +22,7 @@ public class MinionProfileUtils {
uuidMinion = UUID.randomUUID(); uuidMinion = UUID.randomUUID();
} }
GameProfile newProfile = new GameProfile(uuidMinion, username); GameProfile newProfile = new GameProfile(uuidMinion, username, skin != null ? skin : PropertyMap.EMPTY);
if (skin != null) {
newProfile.getProperties().putAll(skin);
}
LOGGER.info("Minion Profile: {}", newProfile); LOGGER.info("Minion Profile: {}", newProfile);
return newProfile; return newProfile;
} }
@@ -8,13 +8,14 @@ import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
import io.github.skippyall.minions.program.instruction.InstructionType; import io.github.skippyall.minions.program.instruction.InstructionType;
import io.github.skippyall.minions.program.supplier.ValueSupplierType; import io.github.skippyall.minions.program.supplier.ValueSupplierType;
import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.registration.MinionRegistries;
import net.minecraft.core.Registry;
import net.minecraft.world.level.storage.ValueInput;
import net.minecraft.world.level.storage.ValueOutput;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import net.minecraft.core.Registry;
import net.minecraft.world.level.storage.ValueInput;
import net.minecraft.world.level.storage.ValueOutput;
public class MinionRuntime implements InstructionRuntime<MinionRuntime> { public class MinionRuntime implements InstructionRuntime<MinionRuntime> {
private final MinionFakePlayer minion; private final MinionFakePlayer minion;
@@ -115,7 +116,7 @@ public class MinionRuntime implements InstructionRuntime<MinionRuntime> {
for (ValueInput inner : list) { for (ValueInput inner : list) {
Optional<String> name = inner.getString("name"); Optional<String> name = inner.getString("name");
if(name.isEmpty()) { if(name.isEmpty()) {
Minions.LOGGER.error("Tried deserializing configured instruction without a name of minion \"{}\":", minion.getGameProfile().getName()); Minions.LOGGER.error("Tried deserializing configured instruction without a name of minion \"{}\":", minion.getGameProfile().name());
continue; continue;
} }
@@ -123,7 +124,7 @@ public class MinionRuntime implements InstructionRuntime<MinionRuntime> {
ConfiguredInstruction<MinionRuntime> instruction = ConfiguredInstruction.load(inner, this); ConfiguredInstruction<MinionRuntime> instruction = ConfiguredInstruction.load(inner, this);
configuredInstructions.put(name.get(), instruction); configuredInstructions.put(name.get(), instruction);
} catch (Exception e) { } catch (Exception e) {
Minions.LOGGER.error("Could not deserialize configured instruction \"{}\" of minion \"{}\":", name.get(), minion.getGameProfile().getName(), e); Minions.LOGGER.error("Could not deserialize configured instruction \"{}\" of minion \"{}\":", name.get(), minion.getGameProfile().name(), e);
} }
} }
} }
@@ -3,10 +3,6 @@ package io.github.skippyall.minions.minion.fakeplayer;
import io.github.skippyall.minions.mixins.EntityAccessor; import io.github.skippyall.minions.mixins.EntityAccessor;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.minecraft.commands.arguments.EntityAnchorArgument; import net.minecraft.commands.arguments.EntityAnchorArgument;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@@ -18,11 +14,11 @@ import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.animal.horse.AbstractHorse; import net.minecraft.world.entity.animal.equine.AbstractHorse;
import net.minecraft.world.entity.decoration.ItemFrame; import net.minecraft.world.entity.decoration.ItemFrame;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.vehicle.Boat; import net.minecraft.world.entity.vehicle.boat.Boat;
import net.minecraft.world.entity.vehicle.Minecart; import net.minecraft.world.entity.vehicle.minecart.Minecart;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
@@ -31,6 +27,11 @@ import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class EntityPlayerActionPack public class EntityPlayerActionPack
{ {
private final MinionFakePlayer player; private final MinionFakePlayer player;
@@ -215,7 +216,7 @@ public class EntityPlayerActionPack
if (closest instanceof AbstractHorse && onlyRideables) if (closest instanceof AbstractHorse && onlyRideables)
((AbstractHorse) closest).mobInteract(player, InteractionHand.MAIN_HAND); ((AbstractHorse) closest).mobInteract(player, InteractionHand.MAIN_HAND);
else else
player.startRiding(closest, !onlyRideables); player.startRiding(closest, !onlyRideables, true);
return this; return this;
} }
public EntityPlayerActionPack dismount() public EntityPlayerActionPack dismount()
@@ -352,13 +353,13 @@ public class EntityPlayerActionPack
boolean handWasEmpty = player.getItemInHand(hand).isEmpty(); boolean handWasEmpty = player.getItemInHand(hand).isEmpty();
boolean itemFrameEmpty = (entity instanceof ItemFrame) && ((ItemFrame) entity).getItem().isEmpty(); boolean itemFrameEmpty = (entity instanceof ItemFrame) && ((ItemFrame) entity).getItem().isEmpty();
Vec3 relativeHitPos = entityHit.getLocation().subtract(entity.getX(), entity.getY(), entity.getZ()); Vec3 relativeHitPos = entityHit.getLocation().subtract(entity.getX(), entity.getY(), entity.getZ());
if (entity.interactAt(player, relativeHitPos, hand).consumesAction()) if (entity.interact(player, hand, relativeHitPos).consumesAction())
{ {
ap.itemUseCooldown = 3; ap.itemUseCooldown = 3;
return true; return true;
} }
// fix for SS itemframe always returns CONSUME even if no action is performed // fix for SS itemframe always returns CONSUME even if no action is performed
if (player.interactOn(entity, hand).consumesAction() && !(handWasEmpty && itemFrameEmpty)) if (player.interactOn(entity, hand, relativeHitPos).consumesAction() && !(handWasEmpty && itemFrameEmpty))
{ {
ap.itemUseCooldown = 3; ap.itemUseCooldown = 3;
return true; return true;
@@ -485,7 +486,8 @@ public class EntityPlayerActionPack
{ {
if (action.limit == 1) if (action.limit == 1)
{ {
if (player.onGround()) player.jumpFromGround(); // onGround if (player.onGround()) player.jumpFromGround();
else if (!player.onClimbable()) player.tryToStartFallFlying();
} }
else else
{ {
@@ -1,11 +1,14 @@
//code from https://github.com/gnembon/fabric-carpet //code from https://github.com/gnembon/fabric-carpet
package io.github.skippyall.minions.minion.fakeplayer; package io.github.skippyall.minions.minion.fakeplayer;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.embedded.EmbeddedChannel; import io.netty.channel.embedded.EmbeddedChannel;
import net.minecraft.network.Connection; import net.minecraft.network.Connection;
import net.minecraft.network.PacketListener; import net.minecraft.network.PacketListener;
import net.minecraft.network.ProtocolInfo; import net.minecraft.network.ProtocolInfo;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.PacketFlow; import net.minecraft.network.protocol.PacketFlow;
import org.jspecify.annotations.Nullable;
public class FakeClientConnection extends Connection { public class FakeClientConnection extends Connection {
public FakeClientConnection(PacketFlow p) public FakeClientConnection(PacketFlow p)
@@ -16,6 +19,11 @@ public class FakeClientConnection extends Connection {
((ClientConnectionInterface)this).setChannel(new EmbeddedChannel()); ((ClientConnectionInterface)this).setChannel(new EmbeddedChannel());
} }
@Override
public void send(Packet<?> packet, @Nullable ChannelFutureListener listener, boolean flush) {
}
@Override @Override
public void setReadOnly() public void setReadOnly()
{ {
@@ -3,6 +3,7 @@ package io.github.skippyall.minions.minion.fakeplayer;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.PropertyMap; import com.mojang.authlib.properties.PropertyMap;
import io.github.skippyall.minions.Minions;
import io.github.skippyall.minions.gui.minion.MinionGui; import io.github.skippyall.minions.gui.minion.MinionGui;
import io.github.skippyall.minions.listener.SerializableListenerManager; import io.github.skippyall.minions.listener.SerializableListenerManager;
import io.github.skippyall.minions.minion.MinionData; import io.github.skippyall.minions.minion.MinionData;
@@ -15,6 +16,7 @@ import io.github.skippyall.minions.module.ModuleInventory;
import io.github.skippyall.minions.registration.MinionConfigOptions; import io.github.skippyall.minions.registration.MinionConfigOptions;
import io.github.skippyall.minions.registration.MinionItems; import io.github.skippyall.minions.registration.MinionItems;
import io.github.skippyall.minions.registration.SpecialAbilities; import io.github.skippyall.minions.registration.SpecialAbilities;
import net.fabricmc.fabric.impl.networking.context.PacketContextImpl;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.network.DisconnectionDetails; import net.minecraft.network.DisconnectionDetails;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
@@ -29,6 +31,7 @@ import net.minecraft.server.level.ClientInformation;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.CommonListenerCookie; import net.minecraft.server.network.CommonListenerCookie;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageSource;
@@ -37,18 +40,20 @@ import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractBoat; import net.minecraft.world.entity.vehicle.boat.AbstractBoat;
import net.minecraft.world.food.FoodData; import net.minecraft.world.food.FoodData;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.GameType; import net.minecraft.world.level.GameType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.portal.TeleportTransition; import net.minecraft.world.level.portal.TeleportTransition;
import net.minecraft.world.level.storage.TagValueInput;
import net.minecraft.world.level.storage.ValueInput; import net.minecraft.world.level.storage.ValueInput;
import net.minecraft.world.level.storage.ValueOutput; import net.minecraft.world.level.storage.ValueOutput;
import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -82,7 +87,17 @@ public class MinionFakePlayer extends ServerPlayer {
if(pos != null && rot != null) { if(pos != null && rot != null) {
instance.fixStartingPosition = () -> instance.snapTo(pos.x, pos.y, pos.z, rot.x, rot.y); instance.fixStartingPosition = () -> instance.snapTo(pos.x, pos.y, pos.z, rot.x, rot.y);
} }
server.getPlayerList().placeNewPlayer(new FakeClientConnection(PacketFlow.SERVERBOUND), instance, new CommonListenerCookie(profile, 0, instance.clientInformation(), false)); FakeClientConnection connection = new FakeClientConnection(PacketFlow.SERVERBOUND);
//noinspection UnstableApiUsage
connection.getPacketContext().set(PacketContextImpl.REGISTRY_ACCESS, server.registryAccess());
//noinspection UnstableApiUsage
connection.getPacketContext().set(PacketContextImpl.SERVER_INSTANCE, server);
//noinspection UnstableApiUsage
connection.getPacketContext().set(PacketContextImpl.GAME_PROFILE, profile);
server.getPlayerList().placeNewPlayer(connection, instance, new CommonListenerCookie(profile, 0, instance.clientInformation(), false));
loadPlayerData(instance);
instance.stopRiding(); // otherwise the created fake player will be on the vehicle
System.out.println(instance.position()); System.out.println(instance.position());
if(pos != null && rot != null) { if(pos != null && rot != null) {
instance.teleportTo(level, pos.x, pos.y, pos.z, Set.of(), rot.x, rot.y, true); instance.teleportTo(level, pos.x, pos.y, pos.z, Set.of(), rot.x, rot.y, true);
@@ -102,6 +117,19 @@ public class MinionFakePlayer extends ServerPlayer {
instance.listeners().forEach(listener -> listener.onMinionSpawn(instance)); instance.listeners().forEach(listener -> listener.onMinionSpawn(instance));
} }
private static void loadPlayerData(MinionFakePlayer player)
{
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(player.problemPath(), Minions.LOGGER))
{
Optional<ValueInput> optional = player.level().getServer().getPlayerList().loadPlayerData(player.nameAndId()).map((compoundTag) -> TagValueInput.create(scopedCollector, player.registryAccess(), compoundTag));
optional.ifPresent( valueInput -> {
player.load(valueInput);
player.loadAndSpawnEnderPearls(valueInput);
player.loadAndSpawnParentVehicle(valueInput);
});
}
}
public static MinionFakePlayer respawnFake(MinecraftServer server, ServerLevel level, GameProfile profile, ClientInformation cli) public static MinionFakePlayer respawnFake(MinecraftServer server, ServerLevel level, GameProfile profile, ClientInformation cli)
{ {
return new MinionFakePlayer(server, level, profile, cli); return new MinionFakePlayer(server, level, profile, cli);
@@ -153,19 +181,18 @@ public class MinionFakePlayer extends ServerPlayer {
return canSpawnMobs(); return canSpawnMobs();
} }
public MinecraftServer getServer() {
return level().getServer();
}
@Override @Override
public InteractionResult interact(Player player, InteractionHand hand) { public InteractionResult interact(Player player, InteractionHand hand, Vec3 location) {
if(player instanceof ServerPlayer spe) { if(player instanceof ServerPlayer spe) {
new MinionGui(spe, this); new MinionGui(spe, this);
} }
return InteractionResult.CONSUME; return InteractionResult.CONSUME;
} }
@Override
public InteractionResult interactAt(Player player, Vec3 hitPos, InteractionHand hand) {
return interact(player, hand);
}
@Override @Override
public void onEquipItem(final EquipmentSlot slot, final ItemStack previous, final ItemStack stack) public void onEquipItem(final EquipmentSlot slot, final ItemStack previous, final ItemStack stack)
{ {
@@ -213,8 +240,8 @@ public class MinionFakePlayer extends ServerPlayer {
} }
@Override @Override
public boolean startRiding(Entity entityToRide, boolean force) { public boolean startRiding(Entity entityToRide, boolean force, boolean sendEventAndTriggers) {
if (super.startRiding(entityToRide, force)) { if (super.startRiding(entityToRide, force, sendEventAndTriggers)) {
// from ClientPacketListener.handleSetEntityPassengersPacket // from ClientPacketListener.handleSetEntityPassengersPacket
if (entityToRide instanceof AbstractBoat) { if (entityToRide instanceof AbstractBoat) {
this.yRotO = entityToRide.getYRot(); this.yRotO = entityToRide.getYRot();
@@ -4,13 +4,13 @@ package io.github.skippyall.minions.minion.fakeplayer;
import net.minecraft.network.Connection; import net.minecraft.network.Connection;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.contents.TranslatableContents; import net.minecraft.network.chat.contents.TranslatableContents;
import net.minecraft.network.protocol.Packet;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.CommonListenerCookie; import net.minecraft.server.network.CommonListenerCookie;
import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.world.entity.PositionMoveRotation; import net.minecraft.world.entity.PositionMoveRotation;
import net.minecraft.world.entity.Relative; import net.minecraft.world.entity.Relative;
import java.util.Set; import java.util.Set;
public class NetHandlerPlayServerFake extends ServerGamePacketListenerImpl public class NetHandlerPlayServerFake extends ServerGamePacketListenerImpl
@@ -20,11 +20,6 @@ public class NetHandlerPlayServerFake extends ServerGamePacketListenerImpl
super(minecraftServer, connection, serverPlayer, i); super(minecraftServer, connection, serverPlayer, i);
} }
@Override
public void send(final Packet<?> packetIn)
{
}
@Override @Override
public void disconnect(Component message) public void disconnect(Component message)
{ {
@@ -1,8 +1,6 @@
//code from https://github.com/gnembon/fabric-carpet //code from https://github.com/gnembon/fabric-carpet
package io.github.skippyall.minions.minion.fakeplayer; package io.github.skippyall.minions.minion.fakeplayer;
import java.util.Optional;
import java.util.function.Predicate;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.ClipContext; import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
@@ -12,6 +10,9 @@ import net.minecraft.world.phys.EntityHitResult;
import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import java.util.Optional;
import java.util.function.Predicate;
public class Tracer public class Tracer
{ {
public static HitResult rayTrace(Entity source, float partialTicks, double reach, boolean fluids) public static HitResult rayTrace(Entity source, float partialTicks, double reach, boolean fluids)
@@ -8,7 +8,7 @@ import io.github.skippyall.minions.program.supplier.Parameter;
import io.github.skippyall.minions.program.supplier.ParameterValueList; import io.github.skippyall.minions.program.supplier.ParameterValueList;
import io.github.skippyall.minions.registration.ValueTypes; import io.github.skippyall.minions.registration.ValueTypes;
import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.ClickType; import net.minecraft.world.inventory.ContainerInput;
import net.minecraft.world.inventory.Slot; import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.storage.ValueInput; import net.minecraft.world.level.storage.ValueInput;
@@ -93,7 +93,7 @@ public class SwapItemExecution implements InstructionExecution<MinionRuntime> {
AbstractContainerMenu screenHandler = getScreen(minion, screen); AbstractContainerMenu screenHandler = getScreen(minion, screen);
ItemStack previousCursor = screenHandler.getCarried(); ItemStack previousCursor = screenHandler.getCarried();
screenHandler.setCarried(cursor); screenHandler.setCarried(cursor);
screenHandler.clicked(slotIndex, 0, ClickType.SWAP, minion); screenHandler.clicked(slotIndex, 0, ContainerInput.SWAP, minion);
cursor = screenHandler.getCarried(); cursor = screenHandler.getCarried();
screenHandler.setCarried(previousCursor); screenHandler.setCarried(previousCursor);
} }
@@ -3,9 +3,10 @@ package io.github.skippyall.minions.minion.program.instruction.move;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import io.github.skippyall.minions.gui.Displayable; import io.github.skippyall.minions.gui.Displayable;
import io.github.skippyall.minions.gui.GuiDisplay; import io.github.skippyall.minions.gui.GuiDisplay;
import java.util.UUID;
import net.minecraft.util.StringRepresentable; import net.minecraft.util.StringRepresentable;
import java.util.UUID;
public enum TurnDirection implements StringRepresentable, Displayable { public enum TurnDirection implements StringRepresentable, Displayable {
LEFT("left", -1, 0), LEFT("left", -1, 0),
UP("up", 0, -1), UP("up", 0, -1),
@@ -16,15 +16,15 @@ import io.github.skippyall.minions.registration.MinionComponentTypes;
import io.github.skippyall.minions.registration.MinionItems; import io.github.skippyall.minions.registration.MinionItems;
import io.github.skippyall.minions.registration.ValueSuppliers; import io.github.skippyall.minions.registration.ValueSuppliers;
import io.github.skippyall.minions.registration.ValueTypes; import io.github.skippyall.minions.registration.ValueTypes;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture;
public class AnalogInputSupplier implements ValueSupplier<Long, MinionRuntime> { public class AnalogInputSupplier implements ValueSupplier<Long, MinionRuntime> {
public static final Codec<AnalogInputSupplier> CODEC = RecordCodecBuilder.create(instance -> public static final Codec<AnalogInputSupplier> CODEC = RecordCodecBuilder.create(instance ->
@@ -63,7 +63,7 @@ public class AnalogInputSupplier implements ValueSupplier<Long, MinionRuntime> {
@Override @Override
public Component getDisplayText() { public Component getDisplayText() {
return Component.translatable("value_supplier.minions.analog_input.display", analogInputPos.toShortString(), analogInputWorld.location().toString()); return Component.translatable("value_supplier.minions.analog_input.display", analogInputPos.toShortString(), analogInputWorld.identifier().toString());
} }
public static class AnalogInputSupplierType extends ValueSupplierType<MinionRuntime> { public static class AnalogInputSupplierType extends ValueSupplierType<MinionRuntime> {
@@ -79,19 +79,21 @@ public class AnalogInputSupplier implements ValueSupplier<Long, MinionRuntime> {
public <T> CompletableFuture<ValueSupplier<?, MinionRuntime>> openConfiguration(MinionsGui parent, ValueType<T> valueType, @Nullable ValueSupplier<?, MinionRuntime> previous) { public <T> CompletableFuture<ValueSupplier<?, MinionRuntime>> openConfiguration(MinionsGui parent, ValueType<T> valueType, @Nullable ValueSupplier<?, MinionRuntime> previous) {
CompletableFuture<ValueSupplier<?, MinionRuntime>> future = new CompletableFuture<>(); CompletableFuture<ValueSupplier<?, MinionRuntime>> future = new CompletableFuture<>();
new SimpleMinionsGui(parent, (onClose, me) -> { new SimpleMinionsGui(parent, (onClose, me) -> {
SimpleGui gui = new SimpleGui(MenuType.GENERIC_3x3, parent.getViewer(), false) { SimpleGui gui = new SimpleGui(MenuType.GENERIC_3x3, parent.viewer, false) {
@Override @Override
public void onClose() { public void onPlayerClose(boolean success) {
onClose.run(); onClose.run();
} }
}; };
gui.setTitle(Component.translatable("value_supplier.minions.analog_input")); gui.setTitle(Component.translatable("value_supplier.minions.analog_input"));
gui.setSlot(2, me.backButton());
gui.setSlot(4, new GuiElementBuilder(MinionItems.REFERENCE_ITEM) gui.setSlot(4, new GuiElementBuilder(MinionItems.REFERENCE_ITEM)
.setCallback(() -> { .setCallback(() -> {
ItemStack cursor = parent.getViewer().containerMenu.getCarried(); ItemStack cursor = parent.viewer.containerMenu.getCarried();
if (cursor.is(MinionItems.REFERENCE_ITEM) && cursor.get(MinionComponentTypes.REFERENCE) instanceof BlockPosClipboard pos) { if (cursor.is(MinionItems.REFERENCE_ITEM) && cursor.get(MinionComponentTypes.REFERENCE) instanceof BlockPosClipboard pos) {
future.complete(new AnalogInputSupplier(pos.world(), pos.pos())); future.complete(new AnalogInputSupplier(pos.world(), pos.pos()));
me.goBack();
} }
}) })
.setItemName(Component.translatable("value_supplier.minions.analog_input.config.click_with_reference")) .setItemName(Component.translatable("value_supplier.minions.analog_input.config.click_with_reference"))
@@ -1,20 +1,19 @@
package io.github.skippyall.minions.minion.skin; package io.github.skippyall.minions.minion.skin;
import com.google.common.collect.ImmutableMultimap;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property; import com.mojang.authlib.properties.Property;
import com.mojang.authlib.properties.PropertyMap; import com.mojang.authlib.properties.PropertyMap;
import io.github.skippyall.minions.Minions; import io.github.skippyall.minions.Minions;
import java.util.HashMap; import io.github.skippyall.minions.gui.MinionsGui;
import java.util.List; import net.fabricmc.fabric.api.entity.FakePlayer;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.Identifier;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.dialog.ActionButton; import net.minecraft.server.dialog.ActionButton;
import net.minecraft.server.dialog.CommonButtonData; import net.minecraft.server.dialog.CommonButtonData;
import net.minecraft.server.dialog.CommonDialogData; import net.minecraft.server.dialog.CommonDialogData;
@@ -24,20 +23,26 @@ import net.minecraft.server.dialog.Input;
import net.minecraft.server.dialog.NoticeDialog; import net.minecraft.server.dialog.NoticeDialog;
import net.minecraft.server.dialog.action.CustomAll; import net.minecraft.server.dialog.action.CustomAll;
import net.minecraft.server.dialog.input.TextInput; import net.minecraft.server.dialog.input.TextInput;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.item.component.ResolvableProfile;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
public class Base64SkinProvider implements SkinProvider { public class Base64SkinProvider implements SkinProvider {
public static final ResourceKey<Dialog> DIALOG = ResourceKey.create(Registries.DIALOG, ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, "base_64_input")); public static final ResourceKey<Dialog> DIALOG = ResourceKey.create(Registries.DIALOG, Identifier.fromNamespaceAndPath(Minions.MOD_ID, "base_64_input"));
public static final ResourceLocation CUSTOM_DIALOG_ACTION = ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, "base_64_submit"); public static final Identifier CUSTOM_DIALOG_ACTION = Identifier.fromNamespaceAndPath(Minions.MOD_ID, "base_64_submit");
private static long dialogIdCounter = 0; private static long dialogIdCounter = 0;
private static Map<Long, CompletableFuture<Optional<PropertyMap>>> futures = new HashMap<>(); private static Map<Long, CompletableFuture<ResolvableProfile>> futures = new HashMap<>();
@Override @Override
public CompletableFuture<Optional<PropertyMap>> openSkinMenu(ServerPlayer player) { public CompletableFuture<ResolvableProfile> openSkinMenu(MinionsGui parent) {
dialogIdCounter++; dialogIdCounter++;
player.openDialog(getDialog()); parent.viewer.openDialog(getDialog());
CompletableFuture<Optional<PropertyMap>> future = new CompletableFuture<>(); CompletableFuture<ResolvableProfile> future = new CompletableFuture<>();
futures.put(dialogIdCounter, future); futures.put(dialogIdCounter, future);
return future; return future;
} }
@@ -48,10 +53,11 @@ public class Base64SkinProvider implements SkinProvider {
Optional<String> base64 = compound.getString("base_64"); Optional<String> base64 = compound.getString("base_64");
if(id.isPresent() && base64.isPresent() && !base64.get().isBlank()) { if(id.isPresent() && base64.isPresent() && !base64.get().isBlank()) {
if(futures.containsKey(id.get())) { if(futures.containsKey(id.get())) {
PropertyMap map = new PropertyMap(); PropertyMap map = new PropertyMap(ImmutableMultimap.of(
map.put("textures", new Property("textures", base64.get().strip())); "textures", new Property("textures", base64.get().strip())
));
futures.get(id.get()).complete(Optional.of(map)); futures.get(id.get()).complete(ResolvableProfile.createResolved(new GameProfile(FakePlayer.DEFAULT_UUID, "", map)));
futures.remove(id.get()); futures.remove(id.get());
} }
} }
@@ -1,20 +1,17 @@
package io.github.skippyall.minions.minion.skin; package io.github.skippyall.minions.minion.skin;
import com.mojang.authlib.GameProfile; import io.github.skippyall.minions.gui.MinionsGui;
import com.mojang.authlib.properties.PropertyMap;
import io.github.skippyall.minions.gui.input.TextInput; import io.github.skippyall.minions.gui.input.TextInput;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.item.component.ResolvableProfile;
import net.minecraft.world.level.block.entity.SkullBlockEntity;
import java.util.concurrent.CompletableFuture;
public class NameSkinProvider implements SkinProvider { public class NameSkinProvider implements SkinProvider {
@Override @Override
public CompletableFuture<Optional<PropertyMap>> openSkinMenu(ServerPlayer player) { public CompletableFuture<ResolvableProfile> openSkinMenu(MinionsGui parent) {
return TextInput.inputString(player, Component.translatable("minions.gui.look.skin.name.title"), "") return TextInput.inputStringFuture(parent, Component.translatable("minions.gui.look.skin.name.title"), "")
.thenCompose(SkullBlockEntity::fetchGameProfile) .thenApply(name -> name != null ? ResolvableProfile.createUnresolved(name) : null);
.thenApply(gameProfile -> gameProfile.map(GameProfile::getProperties));
} }
@Override @Override
@@ -1,13 +1,13 @@
package io.github.skippyall.minions.minion.skin; package io.github.skippyall.minions.minion.skin;
import com.mojang.authlib.properties.PropertyMap; import io.github.skippyall.minions.gui.MinionsGui;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.item.component.ResolvableProfile;
import java.util.concurrent.CompletableFuture;
public interface SkinProvider { public interface SkinProvider {
CompletableFuture<Optional<PropertyMap>> openSkinMenu(ServerPlayer player); CompletableFuture<ResolvableProfile> openSkinMenu(MinionsGui parent);
Component getDisplayName(); Component getDisplayName();
} }
@@ -1,21 +1,17 @@
package io.github.skippyall.minions.minion.skin; package io.github.skippyall.minions.minion.skin;
import com.mojang.authlib.GameProfile; import io.github.skippyall.minions.gui.MinionsGui;
import com.mojang.authlib.properties.PropertyMap;
import io.github.skippyall.minions.gui.input.TextInput; import io.github.skippyall.minions.gui.input.TextInput;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.item.component.ResolvableProfile;
import net.minecraft.world.level.block.entity.SkullBlockEntity;
import java.util.concurrent.CompletableFuture;
public class UUIDSkinProvider implements SkinProvider { public class UUIDSkinProvider implements SkinProvider {
@Override @Override
public CompletableFuture<Optional<PropertyMap>> openSkinMenu(ServerPlayer player) { public CompletableFuture<ResolvableProfile> openSkinMenu(MinionsGui parent) {
return TextInput.inputString(player, Component.translatable("minions.gui.look.skin.uuid.title"), "") return TextInput.inputStringFuture(parent, Component.translatable("minions.gui.look.skin.uuid.title"), "")
.thenCompose(uuidString -> SkullBlockEntity.fetchGameProfile(UUID.fromString(uuidString))) .thenApply(name -> name != null ? ResolvableProfile.createUnresolved(name) : null);
.thenApply(gameProfile -> gameProfile.map(GameProfile::getProperties));
} }
@Override @Override
@@ -1,8 +1,9 @@
package io.github.skippyall.minions.mixinhelper; package io.github.skippyall.minions.mixinhelper;
import java.util.function.Predicate;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import java.util.function.Predicate;
public class EntityViewMixinHelper { public class EntityViewMixinHelper {
public static final ThreadLocal<Predicate<Entity>> ADDITIONAL_PREDICATE = ThreadLocal.withInitial(() -> entity -> true); public static final ThreadLocal<Predicate<Entity>> ADDITIONAL_PREDICATE = ThreadLocal.withInitial(() -> entity -> true);
} }
@@ -1,10 +1,10 @@
package io.github.skippyall.minions.mixins; package io.github.skippyall.minions.mixins;
import net.minecraft.world.entity.Entity;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker; import org.spongepowered.asm.mixin.gen.Invoker;
import java.util.stream.Stream; import java.util.stream.Stream;
import net.minecraft.world.entity.Entity;
@Mixin(Entity.class) @Mixin(Entity.class)
public interface EntityAccessor { public interface EntityAccessor {
@@ -12,5 +12,5 @@ public interface EntityAccessor {
boolean minions$canAddPassenger(Entity other); boolean minions$canAddPassenger(Entity other);
@Invoker("getIndirectPassengersStream") @Invoker("getIndirectPassengersStream")
Stream<Entity> minions$streamIntoPassengers(); Stream<Entity> minions$getIndirectPassengersStream();
} }
@@ -1,14 +1,14 @@
package io.github.skippyall.minions.mixins; package io.github.skippyall.minions.mixins;
import io.github.skippyall.minions.mixinhelper.EntityViewMixinHelper; import io.github.skippyall.minions.mixinhelper.EntityViewMixinHelper;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.EntityGetter;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.ModifyArg;
import java.util.function.Predicate; import java.util.function.Predicate;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.EntityGetter;
@Mixin(EntityGetter.class) @Mixin(EntityGetter.class)
public interface EntityGetterMixin { public interface EntityGetterMixin {
@@ -22,6 +22,6 @@ public abstract class EntityMixin {
@Inject(method = "isLocalInstanceAuthoritative", at = @At("HEAD"), cancellable = true) @Inject(method = "isLocalInstanceAuthoritative", at = @At("HEAD"), cancellable = true)
private void isFakePlayer(CallbackInfoReturnable<Boolean> cir) private void isFakePlayer(CallbackInfoReturnable<Boolean> cir)
{ {
if (getControllingPassenger() instanceof MinionFakePlayer) cir.setReturnValue(!level.isClientSide); if (getControllingPassenger() instanceof MinionFakePlayer) cir.setReturnValue(!level.isClientSide());
} }
} }
@@ -5,7 +5,7 @@ import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.minion.skin.Base64SkinProvider; import io.github.skippyall.minions.minion.skin.Base64SkinProvider;
import io.github.skippyall.minions.registration.MinionConfigOptions; import io.github.skippyall.minions.registration.MinionConfigOptions;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@@ -29,7 +29,7 @@ public class MinecraftServerMixin {
} }
@Inject(method = "handleCustomClickAction", at = @At("HEAD"), cancellable = true) @Inject(method = "handleCustomClickAction", at = @At("HEAD"), cancellable = true)
private void onCustomClickAction(ResourceLocation id, Optional<Tag> payload, CallbackInfo ci) { private void onCustomClickAction(Identifier id, Optional<Tag> payload, CallbackInfo ci) {
if(id.equals(Base64SkinProvider.CUSTOM_DIALOG_ACTION)) { if(id.equals(Base64SkinProvider.CUSTOM_DIALOG_ACTION)) {
Base64SkinProvider.onCustomDialogAction(payload); Base64SkinProvider.onCustomDialogAction(payload);
ci.cancel(); ci.cancel();
@@ -18,23 +18,20 @@ import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.CommonListenerCookie; import net.minecraft.server.network.CommonListenerCookie;
import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.server.players.PlayerList; import net.minecraft.server.players.PlayerList;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.level.storage.ValueInput;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Mixin(PlayerList.class) @Mixin(PlayerList.class)
public class PlayerListMixin { public class PlayerListMixin {
@Inject(method = "load", at = @At(value = "RETURN", shift = At.Shift.BEFORE)) @Inject(method = "placeNewPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;level()Lnet/minecraft/server/level/ServerLevel;"))
private void fixStartingPos(ServerPlayer player, ProblemReporter errorReporter, CallbackInfoReturnable<Optional<ValueInput>> cir) private void fixStartingPos(Connection connection, ServerPlayer player, CommonListenerCookie cookie, CallbackInfo ci)
{ {
if (player instanceof MinionFakePlayer) if (player instanceof MinionFakePlayer)
{ {
@@ -16,7 +16,7 @@ public abstract class PlayerMixin {
* To make sure player attacks are able to knockback fake players * To make sure player attacks are able to knockback fake players
*/ */
@ModifyExpressionValue( @ModifyExpressionValue(
method = "attack", method = "causeExtraKnockback",
at = @At( at = @At(
value = "FIELD", value = "FIELD",
target = "Lnet/minecraft/world/entity/Entity;hurtMarked:Z", target = "Lnet/minecraft/world/entity/Entity;hurtMarked:Z",
@@ -1,3 +1,4 @@
//code from https://github.com/gnembon/fabric-carpet
package io.github.skippyall.minions.mixins; package io.github.skippyall.minions.mixins;
import com.llamalad7.mixinextras.injector.ModifyReturnValue; import com.llamalad7.mixinextras.injector.ModifyReturnValue;
@@ -22,7 +23,7 @@ public abstract class TickRateManagerMixin {
return !isActualPlayer(entity) && // not carrying players return !isActualPlayer(entity) && // not carrying players
((EntityAccessor) entity) ((EntityAccessor) entity)
.minions$streamIntoPassengers() .minions$getIndirectPassengersStream()
.noneMatch(TickRateManagerMixin::isActualPlayer); .noneMatch(TickRateManagerMixin::isActualPlayer);
} }
@@ -18,9 +18,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(value = DistanceManager.FixedPlayerDistanceChunkTracker.class) @Mixin(value = DistanceManager.FixedPlayerDistanceChunkTracker.class)
public abstract class DistanceManager$FixedPlayerDistanceChunkTrackerMixin extends ChunkTrackerMixin implements ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor { public abstract class DistanceManager$FixedPlayerDistanceChunkTrackerMixin extends ChunkTrackerMixin implements ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor {
@Final
@Shadow @Shadow
DistanceManager field_17462; @Final
DistanceManager this$0;
@Shadow @Shadow
@Final @Final
@@ -40,7 +40,7 @@ public abstract class DistanceManager$FixedPlayerDistanceChunkTrackerMixin exten
@Override @Override
public boolean minions$isRealPlayerInChunk(long chunkPos) { public boolean minions$isRealPlayerInChunk(long chunkPos) {
ObjectSet<ServerPlayer> players = ((ChunkLevelManagerAccessor)field_17462).minions$getPlayers(chunkPos); ObjectSet<ServerPlayer> players = ((ChunkLevelManagerAccessor)this$0).minions$getPlayers(chunkPos);
boolean contains = false; boolean contains = false;
if(players != null) { if(players != null) {
contains = players.stream().anyMatch(player -> { contains = players.stream().anyMatch(player -> {
@@ -56,14 +56,14 @@ public abstract class DistanceManager$FixedPlayerDistanceChunkTrackerMixin exten
@Inject(method = "runAllUpdates", at = @At("HEAD")) @Inject(method = "runAllUpdates", at = @At("HEAD"))
public void minions$sync(CallbackInfo info) { public void minions$sync(CallbackInfo info) {
if (minions$target) { if (minions$target) {
((ChunkLevelManagerAccessor)field_17462).minions$getMinionless().runAllUpdates(); ((ChunkLevelManagerAccessor)this$0).minions$getMinionless().runAllUpdates();
} }
} }
@Override @Override
public void minions$updateLevel(long chunkPos, int distance, boolean decrease, CallbackInfo info) { public void minions$updateLevel(long chunkPos, int distance, boolean decrease, CallbackInfo info) {
if (minions$target && (distance == Integer.MAX_VALUE || minions$isRealPlayerInChunk(chunkPos))) { if (minions$target && (distance == Integer.MAX_VALUE || minions$isRealPlayerInChunk(chunkPos))) {
((ChunkLevelManagerAccessor)field_17462).minions$getMinionless().update(chunkPos, distance, decrease); ((ChunkLevelManagerAccessor)this$0).minions$getMinionless().update(chunkPos, distance, decrease);
} }
} }
@@ -5,6 +5,10 @@ import io.github.skippyall.minions.mixinhelper.antimobcap.ChunkLevelManager$Dist
import io.github.skippyall.minions.mixinhelper.antimobcap.ChunkLevelManagerAccessor; import io.github.skippyall.minions.mixinhelper.antimobcap.ChunkLevelManagerAccessor;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.objects.ObjectSet; import it.unimi.dsi.fastutil.objects.ObjectSet;
import net.minecraft.core.SectionPos;
import net.minecraft.server.level.DistanceManager;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.TicketStorage;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@@ -14,10 +18,6 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import net.minecraft.core.SectionPos;
import net.minecraft.server.level.DistanceManager;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.TicketStorage;
@Mixin(DistanceManager.class) @Mixin(DistanceManager.class)
public class DistanceManagerMixin implements ChunkLevelManagerAccessor { public class DistanceManagerMixin implements ChunkLevelManagerAccessor {
@@ -10,7 +10,7 @@ import org.spongepowered.asm.mixin.injection.ModifyArg;
@Mixin(Grave.class) @Mixin(Grave.class)
public class GraveMixin { public class GraveMixin {
@ModifyArg(method = "createBlock", at = @At(value = "INVOKE", target = "Leu/pb4/graves/grave/Grave;<init>(JLcom/mojang/authlib/GameProfile;BLnet/minecraft/world/entity/HumanoidArm;Lnet/minecraft/core/BlockPos;Lnet/minecraft/resources/ResourceLocation;Leu/pb4/graves/grave/GraveType;JJILnet/minecraft/network/chat/Component;Ljava/util/Collection;Ljava/util/Collection;ZI)V")) @ModifyArg(method = "createBlock", at = @At(value = "INVOKE", target = "Leu/pb4/graves/grave/Grave;<init>(JLcom/mojang/authlib/GameProfile;BLnet/minecraft/world/entity/HumanoidArm;Lnet/minecraft/core/BlockPos;Lnet/minecraft/resources/Identifier;Leu/pb4/graves/grave/GraveType;JJILnet/minecraft/network/chat/Component;Ljava/util/Collection;Ljava/util/Collection;ZI)V"))
private static boolean createGrave(boolean profile, @Local(argsOnly = true) ServerPlayer player) { private static boolean createGrave(boolean profile, @Local(argsOnly = true) ServerPlayer player) {
if(player instanceof MinionFakePlayer) { if(player instanceof MinionFakePlayer) {
return false; return false;
@@ -4,9 +4,6 @@ import io.github.skippyall.minions.minion.MinionRuntime;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.program.instruction.InstructionType; import io.github.skippyall.minions.program.instruction.InstructionType;
import io.github.skippyall.minions.registration.MinionComponentTypes; import io.github.skippyall.minions.registration.MinionComponentTypes;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.ContainerHelper; import net.minecraft.world.ContainerHelper;
@@ -16,6 +13,10 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.storage.ValueInput; import net.minecraft.world.level.storage.ValueInput;
import net.minecraft.world.level.storage.ValueOutput; import net.minecraft.world.level.storage.ValueOutput;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class ModuleInventory extends SimpleContainer { public class ModuleInventory extends SimpleContainer {
private final Set<MinionModule> modules = new HashSet<>(); private final Set<MinionModule> modules = new HashSet<>();
private final Set<InstructionType<MinionRuntime>> instructions = new HashSet<>(); private final Set<InstructionType<MinionRuntime>> instructions = new HashSet<>();
@@ -3,18 +3,18 @@ package io.github.skippyall.minions.polymer;
import eu.pb4.polymer.networking.api.PolymerNetworking; import eu.pb4.polymer.networking.api.PolymerNetworking;
import eu.pb4.polymer.networking.api.server.PolymerServerNetworking; import eu.pb4.polymer.networking.api.server.PolymerServerNetworking;
import io.github.skippyall.minions.Minions; import io.github.skippyall.minions.Minions;
import net.fabricmc.fabric.api.networking.v1.context.PacketContext;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.minecraft.server.network.ServerGamePacketListenerImpl;
import xyz.nucleoid.packettweaker.PacketContext;
public class VersionSync { public class VersionSync {
public static final int NETWORK_VERSION = 1; public static final int NETWORK_VERSION = 1;
public static boolean isOnClient(PacketContext context) { public static boolean isOnClient(PacketContext context) {
if(context.getPlayer() != null) { if(context != null && context.get(PacketContext.CONNECTION).getPacketListener() instanceof ServerGamePacketListenerImpl gamePacketListener) {
return isOnClient(context.getPlayer().connection); return isOnClient(gamePacketListener);
} }
return false; return false;
} }
@@ -25,7 +25,7 @@ public class VersionSync {
public static class VersionSyncPayload implements CustomPacketPayload { public static class VersionSyncPayload implements CustomPacketPayload {
public static final CustomPacketPayload.Type<VersionSyncPayload> PACKET_ID = new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, "version_sync")); public static final CustomPacketPayload.Type<VersionSyncPayload> PACKET_ID = new CustomPacketPayload.Type<>(Identifier.fromNamespaceAndPath(Minions.MOD_ID, "version_sync"));
@Override @Override
public Type<? extends CustomPacketPayload> type() { public Type<? extends CustomPacketPayload> type() {
@@ -34,6 +34,6 @@ public class VersionSync {
} }
public static void register() { public static void register() {
PolymerNetworking.registerS2CVersioned(VersionSyncPayload.PACKET_ID, NETWORK_VERSION, StreamCodec.unit(null)); PolymerNetworking.registerClientboundVersioned(VersionSyncPayload.PACKET_ID, NETWORK_VERSION, StreamCodec.unit(null));
} }
} }
@@ -3,10 +3,10 @@ package io.github.skippyall.minions.program.consumer;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import io.github.skippyall.minions.program.InstructionRuntime; import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.value.ValueType; import io.github.skippyall.minions.program.value.ValueType;
import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import net.minecraft.server.level.ServerPlayer;
public abstract class ValueConsumerType<R extends InstructionRuntime<R>> { public abstract class ValueConsumerType<R extends InstructionRuntime<R>> {
public abstract <T> Codec<? extends ValueConsumer<T,R>> getCodec(ValueType<T> type); public abstract <T> Codec<? extends ValueConsumer<T,R>> getCodec(ValueType<T> type);
@@ -9,10 +9,10 @@ import io.github.skippyall.minions.program.value.ValueType;
import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.registration.MinionRegistries;
import io.github.skippyall.minions.registration.ValueConverters; import io.github.skippyall.minions.registration.ValueConverters;
import io.github.skippyall.minions.util.TranslationUtil; import io.github.skippyall.minions.util.TranslationUtil;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import net.minecraft.network.chat.Component;
public class CastConverter<F,T> implements ValueConverter<F,T> { public class CastConverter<F,T> implements ValueConverter<F,T> {
private static final MapCodec<CastConverter<?,?>> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( private static final MapCodec<CastConverter<?,?>> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
@@ -4,13 +4,13 @@ import com.mojang.serialization.Codec;
import io.github.skippyall.minions.gui.input.Result; import io.github.skippyall.minions.gui.input.Result;
import io.github.skippyall.minions.program.value.TypedValue; import io.github.skippyall.minions.program.value.TypedValue;
import io.github.skippyall.minions.program.value.ValueType; import io.github.skippyall.minions.program.value.ValueType;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.Objects; import java.util.Objects;
import net.minecraft.network.chat.Component;
public class ConverterList { public class ConverterList {
public static final Codec<ConverterList> CODEC = ValueConverter.CODEC.listOf().xmap(ConverterList::new, l -> l.converters); public static final Codec<ConverterList> CODEC = ValueConverter.CODEC.listOf().xmap(ConverterList::new, l -> l.converters);
@@ -7,10 +7,10 @@ import io.github.skippyall.minions.program.value.ValueType;
import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.registration.MinionRegistries;
import io.github.skippyall.minions.registration.ValueConverters; import io.github.skippyall.minions.registration.ValueConverters;
import io.github.skippyall.minions.registration.ValueTypes; import io.github.skippyall.minions.registration.ValueTypes;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import net.minecraft.network.chat.Component;
public class EqualityConverter<F> implements ValueConverter<F, Boolean> { public class EqualityConverter<F> implements ValueConverter<F, Boolean> {
public static final MapCodec<EqualityConverter<?>> CODEC = MinionRegistries.VALUE_TYPES.byNameCodec().dispatchMap( public static final MapCodec<EqualityConverter<?>> CODEC = MinionRegistries.VALUE_TYPES.byNameCodec().dispatchMap(
@@ -3,7 +3,6 @@ package io.github.skippyall.minions.program.instruction;
import io.github.skippyall.minions.program.InstructionRuntime; import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.consumer.ValueConsumerList; import io.github.skippyall.minions.program.consumer.ValueConsumerList;
import io.github.skippyall.minions.program.supplier.ParameterValueList; import io.github.skippyall.minions.program.supplier.ParameterValueList;
import io.github.skippyall.minions.program.supplier.ValueSupplierList;
import net.minecraft.world.level.storage.ValueInput; import net.minecraft.world.level.storage.ValueInput;
import net.minecraft.world.level.storage.ValueOutput; import net.minecraft.world.level.storage.ValueOutput;
@@ -3,10 +3,11 @@ package io.github.skippyall.minions.program.instruction;
import io.github.skippyall.minions.program.InstructionRuntime; import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.supplier.Parameter; import io.github.skippyall.minions.program.supplier.Parameter;
import io.github.skippyall.minions.program.supplier.ParameterValueList; import io.github.skippyall.minions.program.supplier.ParameterValueList;
import net.minecraft.world.level.storage.ValueInput;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
import net.minecraft.world.level.storage.ValueInput;
/** /**
* Defines the semantics of an instruction and creates {@link InstructionExecution} * Defines the semantics of an instruction and creates {@link InstructionExecution}
@@ -9,6 +9,7 @@ import io.github.skippyall.minions.program.conversion.Casts;
import io.github.skippyall.minions.program.conversion.ConverterList; import io.github.skippyall.minions.program.conversion.ConverterList;
import io.github.skippyall.minions.program.instruction.InstructionType; import io.github.skippyall.minions.program.instruction.InstructionType;
import io.github.skippyall.minions.program.value.TypedValue; import io.github.skippyall.minions.program.value.TypedValue;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
@@ -17,7 +18,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Consumer; import java.util.function.Consumer;
import net.minecraft.network.chat.Component;
public class ValueSupplierList<R extends InstructionRuntime<R>> { public class ValueSupplierList<R extends InstructionRuntime<R>> {
private final Map<Parameter<?>, ValueSupplierEntry<?,R>> arguments = new HashMap<>(); private final Map<Parameter<?>, ValueSupplierEntry<?,R>> arguments = new HashMap<>();
@@ -2,10 +2,11 @@ package io.github.skippyall.minions.program.value;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import io.github.skippyall.minions.gui.MinionsGui; import io.github.skippyall.minions.gui.MinionsGui;
import net.minecraft.network.chat.Component;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Function; import java.util.function.Function;
import net.minecraft.network.chat.Component;
public record SimpleValueType<T>(Codec<T> codec, T defaultValue, Function<Object, T> checkedCast, BiFunction<MinionsGui, T, CompletableFuture<T>> valueDialogOpener, Function<T, Component> textDisplay) implements ValueType<T> { public record SimpleValueType<T>(Codec<T> codec, T defaultValue, Function<Object, T> checkedCast, BiFunction<MinionsGui, T, CompletableFuture<T>> valueDialogOpener, Function<T, Component> textDisplay) implements ValueType<T> {
@Override @Override
@@ -2,10 +2,10 @@ package io.github.skippyall.minions.program.value;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import io.github.skippyall.minions.gui.MinionsGui; import io.github.skippyall.minions.gui.MinionsGui;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import net.minecraft.network.chat.Component;
public interface ValueType<T> { public interface ValueType<T> {
CompletableFuture<T> openValueDialog(MinionsGui gui, T previousValue); CompletableFuture<T> openValueDialog(MinionsGui gui, T previousValue);
@@ -6,11 +6,11 @@ import io.github.skippyall.minions.clipboard.BlockPosClipboard;
import io.github.skippyall.minions.clipboard.Clipboard; import io.github.skippyall.minions.clipboard.Clipboard;
import io.github.skippyall.minions.clipboard.InstructionClipboard; import io.github.skippyall.minions.clipboard.InstructionClipboard;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
public class ClipboardTypes { public class ClipboardTypes {
private static void register(String id, MapCodec<? extends Clipboard> codec) { private static void register(String id, MapCodec<? extends Clipboard> codec) {
Registry.register(MinionRegistries.CLIPBOARD_TYPES, ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, id), codec); Registry.register(MinionRegistries.CLIPBOARD_TYPES, Identifier.fromNamespaceAndPath(Minions.MOD_ID, id), codec);
} }
static void register() { static void register() {
@@ -3,10 +3,10 @@ package io.github.skippyall.minions.registration;
import io.github.skippyall.minions.Minions; import io.github.skippyall.minions.Minions;
import io.github.skippyall.minions.docs.ReferenceEntry; import io.github.skippyall.minions.docs.ReferenceEntry;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
public class DocsEntryTypes { public class DocsEntryTypes {
public static void register() { public static void register() {
Registry.register(MinionRegistries.DOCS_ENTRY_TYPES, ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, "reference_entry"), ReferenceEntry.CODEC); Registry.register(MinionRegistries.DOCS_ENTRY_TYPES, Identifier.fromNamespaceAndPath(Minions.MOD_ID, "reference_entry"), ReferenceEntry.CODEC);
} }
} }
@@ -3,13 +3,13 @@ package io.github.skippyall.minions.registration;
import io.github.skippyall.minions.Minions; import io.github.skippyall.minions.Minions;
import io.github.skippyall.minions.gui.GuiDisplay; import io.github.skippyall.minions.gui.GuiDisplay;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
public class GuiDisplayTypes { public class GuiDisplayTypes {
static void register() { static void register() {
Registry.register(MinionRegistries.GUI_DISPLAY_TYPE, ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, "item"), GuiDisplay.ItemBased.CODEC); Registry.register(MinionRegistries.GUI_DISPLAY_TYPE, Identifier.fromNamespaceAndPath(Minions.MOD_ID, "item"), GuiDisplay.ItemBased.CODEC);
Registry.register(MinionRegistries.GUI_DISPLAY_TYPE, ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, "model"), GuiDisplay.ModelBased.CODEC); Registry.register(MinionRegistries.GUI_DISPLAY_TYPE, Identifier.fromNamespaceAndPath(Minions.MOD_ID, "model"), GuiDisplay.ModelBased.CODEC);
Registry.register(MinionRegistries.GUI_DISPLAY_TYPE, ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, "head"), GuiDisplay.HeadBased.CODEC); Registry.register(MinionRegistries.GUI_DISPLAY_TYPE, Identifier.fromNamespaceAndPath(Minions.MOD_ID, "head"), GuiDisplay.HeadBased.CODEC);
Registry.register(MinionRegistries.GUI_DISPLAY_TYPE, ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, "stack"), GuiDisplay.StackBased.CODEC); Registry.register(MinionRegistries.GUI_DISPLAY_TYPE, Identifier.fromNamespaceAndPath(Minions.MOD_ID, "stack"), GuiDisplay.StackBased.CODEC);
} }
} }
@@ -13,11 +13,12 @@ import io.github.skippyall.minions.minion.program.instruction.move.WalkExecution
import io.github.skippyall.minions.program.instruction.InstructionExecution; import io.github.skippyall.minions.program.instruction.InstructionExecution;
import io.github.skippyall.minions.program.instruction.InstructionType; import io.github.skippyall.minions.program.instruction.InstructionType;
import io.github.skippyall.minions.program.supplier.Parameter; import io.github.skippyall.minions.program.supplier.Parameter;
import net.minecraft.core.Registry;
import net.minecraft.resources.Identifier;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation;
public class Instructions { public class Instructions {
public static final InstructionType<MinionRuntime> WALK = register( public static final InstructionType<MinionRuntime> WALK = register(
@@ -64,7 +65,7 @@ public class Instructions {
); );
private static InstructionType<MinionRuntime> register(String id, Supplier<InstructionExecution<MinionRuntime>> factory, Collection<Parameter<?>> parameters, Collection<Parameter<?>> returnParameters) { private static InstructionType<MinionRuntime> register(String id, Supplier<InstructionExecution<MinionRuntime>> factory, Collection<Parameter<?>> parameters, Collection<Parameter<?>> returnParameters) {
ResourceLocation identifier = ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, id); Identifier identifier = Identifier.fromNamespaceAndPath(Minions.MOD_ID, id);
return Registry.register(MinionRegistries.INSTRUCTION_TYPES, identifier, new InstructionType<>(factory, parameters, returnParameters)); return Registry.register(MinionRegistries.INSTRUCTION_TYPES, identifier, new InstructionType<>(factory, parameters, returnParameters));
} }
@@ -9,15 +9,15 @@ import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityT
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.resources.Identifier;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.material.PushReaction; import net.minecraft.world.level.material.PushReaction;
public class MinionBlocks { public class MinionBlocks {
public static final ResourceLocation MINION_TRIGGER_ID = ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, "minion_trigger"); public static final Identifier MINION_TRIGGER_ID = Identifier.fromNamespaceAndPath(Minions.MOD_ID, "minion_trigger");
public static final MinionTriggerBlock MINION_TRIGGER_BLOCK = Registry.register( public static final MinionTriggerBlock MINION_TRIGGER_BLOCK = Registry.register(
BuiltInRegistries.BLOCK, BuiltInRegistries.BLOCK,
MINION_TRIGGER_ID, MINION_TRIGGER_ID,
@@ -36,7 +36,7 @@ public class MinionBlocks {
FabricBlockEntityTypeBuilder.create(MinionTriggerBlockEntity::new, MINION_TRIGGER_BLOCK).build() FabricBlockEntityTypeBuilder.create(MinionTriggerBlockEntity::new, MINION_TRIGGER_BLOCK).build()
); );
public static final ResourceLocation ANALOG_INPUT_BLOCK_ID = ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, "analog_input"); public static final Identifier ANALOG_INPUT_BLOCK_ID = Identifier.fromNamespaceAndPath(Minions.MOD_ID, "analog_input");
public static final AnalogInputBlock ANALOG_INPUT_BLOCK = Registry.register( public static final AnalogInputBlock ANALOG_INPUT_BLOCK = Registry.register(
BuiltInRegistries.BLOCK, BuiltInRegistries.BLOCK,
ANALOG_INPUT_BLOCK_ID, ANALOG_INPUT_BLOCK_ID,
@@ -4,12 +4,12 @@ import eu.pb4.polymer.core.api.other.PolymerComponent;
import io.github.skippyall.minions.Minions; import io.github.skippyall.minions.Minions;
import io.github.skippyall.minions.clipboard.Clipboard; import io.github.skippyall.minions.clipboard.Clipboard;
import io.github.skippyall.minions.module.MinionModule; import io.github.skippyall.minions.module.MinionModule;
import net.fabricmc.fabric.api.item.v1.ComponentTooltipAppenderRegistry; import net.fabricmc.fabric.api.item.v1.ItemComponentTooltipProviderRegistry;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.core.UUIDUtil; import net.minecraft.core.UUIDUtil;
import net.minecraft.core.component.DataComponentType; import net.minecraft.core.component.DataComponentType;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import java.util.UUID; import java.util.UUID;
public class MinionComponentTypes { public class MinionComponentTypes {
@@ -18,12 +18,12 @@ public class MinionComponentTypes {
public static final DataComponentType<Clipboard> REFERENCE = register("reference", DataComponentType.<Clipboard>builder().persistent(Clipboard.CODEC).build()); public static final DataComponentType<Clipboard> REFERENCE = register("reference", DataComponentType.<Clipboard>builder().persistent(Clipboard.CODEC).build());
private static <T extends DataComponentType<?>> T register(String name, T type) { private static <T extends DataComponentType<?>> T register(String name, T type) {
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, name), type); Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, Identifier.fromNamespaceAndPath(Minions.MOD_ID, name), type);
PolymerComponent.registerDataComponent(type); PolymerComponent.registerDataComponent(type);
return type; return type;
} }
public static void register() { public static void register() {
ComponentTooltipAppenderRegistry.addFirst(MinionComponentTypes.REFERENCE); ItemComponentTooltipProviderRegistry.addFirst(MinionComponentTypes.REFERENCE);
} }
} }
@@ -3,7 +3,7 @@ package io.github.skippyall.minions.registration;
import io.github.skippyall.minions.Minions; import io.github.skippyall.minions.Minions;
import io.github.skippyall.minions.minion.MinionConfig; import io.github.skippyall.minions.minion.MinionConfig;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import static io.github.skippyall.minions.minion.MinionConfig.booleanOption; import static io.github.skippyall.minions.minion.MinionConfig.booleanOption;
@@ -20,8 +20,8 @@ public class MinionConfigOptions {
return Registry.register(MinionRegistries.MINION_CONFIG_OPTIONS, option.key(), option); return Registry.register(MinionRegistries.MINION_CONFIG_OPTIONS, option.key(), option);
} }
private static ResourceLocation id(String name) { private static Identifier id(String name) {
return ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, name); return Identifier.fromNamespaceAndPath(Minions.MOD_ID, name);
} }
public static void register() {} public static void register() {}
@@ -1,35 +1,37 @@
package io.github.skippyall.minions.registration; package io.github.skippyall.minions.registration;
import eu.pb4.polymer.core.api.item.PolymerItemGroupUtils; import eu.pb4.polymer.core.api.item.PolymerCreativeModeTabUtils;
import io.github.skippyall.minions.Minions; import io.github.skippyall.minions.Minions;
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; import net.fabricmc.fabric.api.creativetab.v1.FabricCreativeModeTab;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class MinionCreativeTab { public class MinionCreativeTab {
public static CreativeModeTab group; public static CreativeModeTab group;
private static final List<ItemStack> items = new ArrayList<>(); private static final List<Item> items = new ArrayList<>();
public static void add(Item entry) { public static void add(Item entry) {
items.add(entry.getDefaultInstance()); items.add(entry);
} }
public static void collectEntries(CreativeModeTab.ItemDisplayParameters displayContext, CreativeModeTab.Output entries) { public static void collectEntries(CreativeModeTab.ItemDisplayParameters displayContext, CreativeModeTab.Output entries) {
entries.acceptAll(items); for(Item item : items) {
entries.accept(item);
}
} }
public static void registerGroup() { public static void registerGroup() {
group = FabricItemGroup.builder() group = FabricCreativeModeTab.builder()
.title(Component.translatable("minions.generic.mod_name")) .title(Component.translatable("minions.generic.mod_name"))
.icon(MinionItems.MINION_ITEM::getDefaultInstance) .icon(MinionItems.MINION_ITEM::getDefaultInstance)
.displayItems(MinionCreativeTab::collectEntries) .displayItems(MinionCreativeTab::collectEntries)
.build(); .build();
PolymerItemGroupUtils.registerPolymerItemGroup(ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, "main"), group); PolymerCreativeModeTabUtils.registerPolymerCreativeModeTab(Identifier.fromNamespaceAndPath(Minions.MOD_ID, "main"), group);
} }
} }
@@ -9,60 +9,61 @@ import io.github.skippyall.minions.minion.MinionRuntime;
import io.github.skippyall.minions.module.MinionModule; import io.github.skippyall.minions.module.MinionModule;
import io.github.skippyall.minions.module.SpecialAbility; import io.github.skippyall.minions.module.SpecialAbility;
import io.github.skippyall.minions.program.instruction.InstructionType; import io.github.skippyall.minions.program.instruction.InstructionType;
import java.util.List;
import java.util.function.Function;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.core.component.DataComponents; import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.resources.Identifier;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey; import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageType; import net.minecraft.world.damagesource.DamageType;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.item.component.DamageResistant; import net.minecraft.world.item.component.DamageResistant;
import java.util.List;
import java.util.function.Function;
import static io.github.skippyall.minions.Minions.MOD_ID; import static io.github.skippyall.minions.Minions.MOD_ID;
public class MinionItems { public class MinionItems {
public static final TagKey<DamageType> MINION_ITEM_RESISTS = TagKey.create(Registries.DAMAGE_TYPE, ResourceLocation.fromNamespaceAndPath(MOD_ID, "minion_item_resists")); public static final TagKey<DamageType> MINION_ITEM_RESISTS = TagKey.create(Registries.DAMAGE_TYPE, Identifier.fromNamespaceAndPath(MOD_ID, "minion_item_resists"));
public static final MinionItem MINION_ITEM = registerItem( public static final MinionItem MINION_ITEM = registerItem(
ResourceLocation.fromNamespaceAndPath(MOD_ID, "minion"), Identifier.fromNamespaceAndPath(MOD_ID, "minion"),
settings -> new MinionItem(settings.component(DataComponents.DAMAGE_RESISTANT, new DamageResistant(MINION_ITEM_RESISTS))) settings -> new MinionItem(settings.delayedComponent(DataComponents.DAMAGE_RESISTANT, context -> new DamageResistant(context.getOrThrow(MINION_ITEM_RESISTS))))
); );
public static final SimplePolymerItem BASIC_UPGRADE_BASE = registerItem( public static final SimplePolymerItem BASIC_UPGRADE_BASE = registerItem(
ResourceLocation.fromNamespaceAndPath(MOD_ID, "basic_upgrade_base"), Identifier.fromNamespaceAndPath(MOD_ID, "basic_upgrade_base"),
settings -> new SimplePolymerItem(settings, Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE) settings -> new SimplePolymerItem(settings, Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE)
); );
public static final SimplePolymerItem ADVANCED_UPGRADE_BASE = registerItem( public static final SimplePolymerItem ADVANCED_UPGRADE_BASE = registerItem(
ResourceLocation.fromNamespaceAndPath(MOD_ID, "advanced_upgrade_base"), Identifier.fromNamespaceAndPath(MOD_ID, "advanced_upgrade_base"),
settings -> new SimplePolymerItem(settings, Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE) settings -> new SimplePolymerItem(settings, Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE)
); );
public static final SimplePolymerItem MOVE_MODULE = registerModule( public static final SimplePolymerItem MOVE_MODULE = registerModule(
ResourceLocation.fromNamespaceAndPath(MOD_ID, "move_module"), Identifier.fromNamespaceAndPath(MOD_ID, "move_module"),
Items.IRON_BOOTS, Items.IRON_BOOTS,
List.of(Instructions.WALK, Instructions.WALK_CONTINUOUS, Instructions.TURN, Instructions.TURN_VECTOR) List.of(Instructions.WALK, Instructions.WALK_CONTINUOUS, Instructions.TURN, Instructions.TURN_VECTOR)
); );
public static final SimplePolymerItem ATTACK_MODULE = registerModule( public static final SimplePolymerItem ATTACK_MODULE = registerModule(
ResourceLocation.fromNamespaceAndPath(MOD_ID, "attack_module"), Identifier.fromNamespaceAndPath(MOD_ID, "attack_module"),
Items.IRON_PICKAXE, Items.IRON_PICKAXE,
List.of(Instructions.ATTACK, Instructions.MINE_BLOCK) List.of(Instructions.ATTACK, Instructions.MINE_BLOCK)
); );
public static final SimplePolymerItem INTERACT_MODULE = registerModule( public static final SimplePolymerItem INTERACT_MODULE = registerModule(
ResourceLocation.fromNamespaceAndPath(MOD_ID, "interact_module"), Identifier.fromNamespaceAndPath(MOD_ID, "interact_module"),
Items.LEVER, Items.LEVER,
List.of(Instructions.USE) List.of(Instructions.USE)
); );
public static final SimplePolymerItem MOB_SPAWNING_MODULE = registerModule( public static final SimplePolymerItem MOB_SPAWNING_MODULE = registerModule(
ResourceLocation.fromNamespaceAndPath(MOD_ID, "mob_spawning_module"), Identifier.fromNamespaceAndPath(MOD_ID, "mob_spawning_module"),
Items.SPAWNER, Items.SPAWNER,
List.of(), List.of(),
List.of(SpecialAbilities.MOB_SPAWNING) List.of(SpecialAbilities.MOB_SPAWNING)
@@ -75,9 +76,9 @@ public class MinionItems {
new Item.Properties().useBlockDescriptionPrefix() new Item.Properties().useBlockDescriptionPrefix()
); );
public static final ClipboardItem REFERENCE_ITEM = registerItem(ResourceLocation.fromNamespaceAndPath(MOD_ID, "clipboard"), ClipboardItem::new); public static final ClipboardItem REFERENCE_ITEM = registerItem(Identifier.fromNamespaceAndPath(MOD_ID, "clipboard"), ClipboardItem::new);
public static <T extends Item> T registerItem(ResourceLocation identifier, Function<Item.Properties, T> constructor, Item.Properties settings) { public static <T extends Item> T registerItem(Identifier identifier, Function<Item.Properties, T> constructor, Item.Properties settings) {
T item = constructor.apply(settings.setId(ResourceKey.create(Registries.ITEM, identifier))); T item = constructor.apply(settings.setId(ResourceKey.create(Registries.ITEM, identifier)));
MinionCreativeTab.add(item); MinionCreativeTab.add(item);
@@ -85,11 +86,11 @@ public class MinionItems {
return Registry.register(BuiltInRegistries.ITEM, identifier, item); return Registry.register(BuiltInRegistries.ITEM, identifier, item);
} }
public static <T extends Item> T registerItem(ResourceLocation identifier, Function<Item.Properties, T> constructor) { public static <T extends Item> T registerItem(Identifier identifier, Function<Item.Properties, T> constructor) {
return registerItem(identifier, constructor, new Item.Properties()); return registerItem(identifier, constructor, new Item.Properties());
} }
public static SimplePolymerItem registerModule(ResourceLocation identifier, Item vanillaItem, List<InstructionType<MinionRuntime>> instructionTypes, List<SpecialAbility> specialAbilities) { public static SimplePolymerItem registerModule(Identifier identifier, Item vanillaItem, List<InstructionType<MinionRuntime>> instructionTypes, List<SpecialAbility> specialAbilities) {
return registerItem( return registerItem(
identifier, identifier,
settings -> new SimplePolymerItem(settings, vanillaItem), settings -> new SimplePolymerItem(settings, vanillaItem),
@@ -97,7 +98,7 @@ public class MinionItems {
); );
} }
public static SimplePolymerItem registerModule(ResourceLocation identifier, Item vanillaItem, List<InstructionType<MinionRuntime>> instructionTypes) { public static SimplePolymerItem registerModule(Identifier identifier, Item vanillaItem, List<InstructionType<MinionRuntime>> instructionTypes) {
return registerModule( return registerModule(
identifier, identifier,
vanillaItem, vanillaItem,
@@ -3,10 +3,10 @@ package io.github.skippyall.minions.registration;
import io.github.skippyall.minions.Minions; import io.github.skippyall.minions.Minions;
import io.github.skippyall.minions.block.miniontrigger.MinionTriggerMinionListener; import io.github.skippyall.minions.block.miniontrigger.MinionTriggerMinionListener;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
public class MinionListeners { public class MinionListeners {
public static void register() { public static void register() {
Registry.register(MinionRegistries.MINION_LISTENER_CODECS, ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, "minion_trigger"), MinionTriggerMinionListener.CODEC); Registry.register(MinionRegistries.MINION_LISTENER_CODECS, Identifier.fromNamespaceAndPath(Minions.MOD_ID, "minion_trigger"), MinionTriggerMinionListener.CODEC);
} }
} }
@@ -22,8 +22,8 @@ import net.fabricmc.fabric.api.event.registry.DynamicRegistries;
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
import net.fabricmc.fabric.api.event.registry.RegistryAttribute; import net.fabricmc.fabric.api.event.registry.RegistryAttribute;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.Identifier;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
public class MinionRegistries { public class MinionRegistries {
public static final Registry<ValueType<?>> VALUE_TYPES = registry("value_type"); public static final Registry<ValueType<?>> VALUE_TYPES = registry("value_type");
@@ -45,11 +45,11 @@ public class MinionRegistries {
public static final ResourceKey<Registry<ReferenceEntry>> DOCS_ENTRY = key("docs_entry"); public static final ResourceKey<Registry<ReferenceEntry>> DOCS_ENTRY = key("docs_entry");
private static <T> Registry<T> registry(String id) { private static <T> Registry<T> registry(String id) {
return FabricRegistryBuilder.<T>createSimple(key(id)).attribute(RegistryAttribute.OPTIONAL).buildAndRegister(); return FabricRegistryBuilder.<T>create(key(id)).attribute(RegistryAttribute.OPTIONAL).buildAndRegister();
} }
private static <T> ResourceKey<Registry<T>> key(String name) { private static <T> ResourceKey<Registry<T>> key(String name) {
return ResourceKey.createRegistryKey(ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, name)); return ResourceKey.createRegistryKey(Identifier.fromNamespaceAndPath(Minions.MOD_ID, name));
} }
public static void register() { public static void register() {
@@ -6,7 +6,7 @@ import io.github.skippyall.minions.minion.skin.NameSkinProvider;
import io.github.skippyall.minions.minion.skin.SkinProvider; import io.github.skippyall.minions.minion.skin.SkinProvider;
import io.github.skippyall.minions.minion.skin.UUIDSkinProvider; import io.github.skippyall.minions.minion.skin.UUIDSkinProvider;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
public class SkinProviders { public class SkinProviders {
public static NameSkinProvider NAME = register(new NameSkinProvider(), "name"); public static NameSkinProvider NAME = register(new NameSkinProvider(), "name");
@@ -14,7 +14,7 @@ public class SkinProviders {
public static Base64SkinProvider BASE64 = register(new Base64SkinProvider(), "base64"); public static Base64SkinProvider BASE64 = register(new Base64SkinProvider(), "base64");
public static <T extends SkinProvider> T register(T skinProvider, String path) { public static <T extends SkinProvider> T register(T skinProvider, String path) {
return Registry.register(MinionRegistries.SKIN_PROVIDERS, ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, path), skinProvider); return Registry.register(MinionRegistries.SKIN_PROVIDERS, Identifier.fromNamespaceAndPath(Minions.MOD_ID, path), skinProvider);
} }
public static void register() { public static void register() {
@@ -4,13 +4,13 @@ import io.github.skippyall.minions.Minions;
import io.github.skippyall.minions.module.MobSpawningAbility; import io.github.skippyall.minions.module.MobSpawningAbility;
import io.github.skippyall.minions.module.SpecialAbility; import io.github.skippyall.minions.module.SpecialAbility;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
public class SpecialAbilities { public class SpecialAbilities {
public static final MobSpawningAbility MOB_SPAWNING = register("mob_spawning", new MobSpawningAbility()); public static final MobSpawningAbility MOB_SPAWNING = register("mob_spawning", new MobSpawningAbility());
private static <T extends SpecialAbility> T register(String name, T type) { private static <T extends SpecialAbility> T register(String name, T type) {
Registry.register(MinionRegistries.SPECIAL_ABILITIES, ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, name), type); Registry.register(MinionRegistries.SPECIAL_ABILITIES, Identifier.fromNamespaceAndPath(Minions.MOD_ID, name), type);
return type; return type;
} }
@@ -5,14 +5,14 @@ import io.github.skippyall.minions.program.conversion.CastConverter;
import io.github.skippyall.minions.program.conversion.EqualityConverter; import io.github.skippyall.minions.program.conversion.EqualityConverter;
import io.github.skippyall.minions.program.conversion.ValueConverterType; import io.github.skippyall.minions.program.conversion.ValueConverterType;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
public class ValueConverters { public class ValueConverters {
public static final EqualityConverter.EqualityConverterType EQUALITY_CONVERTER = register("equality", new EqualityConverter.EqualityConverterType()); public static final EqualityConverter.EqualityConverterType EQUALITY_CONVERTER = register("equality", new EqualityConverter.EqualityConverterType());
public static final CastConverter.Type CAST_CONVERTER = register("cast", new CastConverter.Type()); public static final CastConverter.Type CAST_CONVERTER = register("cast", new CastConverter.Type());
private static <T extends ValueConverterType<?>> T register(String name, T type) { private static <T extends ValueConverterType<?>> T register(String name, T type) {
return Registry.register(MinionRegistries.VALUE_CONVERTER_TYPES, ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, name), type); return Registry.register(MinionRegistries.VALUE_CONVERTER_TYPES, Identifier.fromNamespaceAndPath(Minions.MOD_ID, name), type);
} }
public static void register() {} public static void register() {}
@@ -6,14 +6,14 @@ import io.github.skippyall.minions.minion.program.supplier.AnalogInputSupplier;
import io.github.skippyall.minions.program.supplier.FixedValueSupplierType; import io.github.skippyall.minions.program.supplier.FixedValueSupplierType;
import io.github.skippyall.minions.program.supplier.ValueSupplierType; import io.github.skippyall.minions.program.supplier.ValueSupplierType;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
public class ValueSuppliers { public class ValueSuppliers {
public static final FixedValueSupplierType<MinionRuntime> FIXED_VALUE_SUPPLIER_TYPE = register("fixed", new FixedValueSupplierType<>()); public static final FixedValueSupplierType<MinionRuntime> FIXED_VALUE_SUPPLIER_TYPE = register("fixed", new FixedValueSupplierType<>());
public static final AnalogInputSupplier.AnalogInputSupplierType ANALOG_INPUT = register("analog_input", new AnalogInputSupplier.AnalogInputSupplierType()); public static final AnalogInputSupplier.AnalogInputSupplierType ANALOG_INPUT = register("analog_input", new AnalogInputSupplier.AnalogInputSupplierType());
public static <T extends ValueSupplierType<MinionRuntime>> T register(String id, T type) { public static <T extends ValueSupplierType<MinionRuntime>> T register(String id, T type) {
return Registry.register(MinionRegistries.VALUE_SUPPLIER_TYPES, ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, id), type); return Registry.register(MinionRegistries.VALUE_SUPPLIER_TYPES, Identifier.fromNamespaceAndPath(Minions.MOD_ID, id), type);
} }
public static void register() {} public static void register() {}
@@ -6,10 +6,11 @@ import io.github.skippyall.minions.gui.input.TextInput;
import io.github.skippyall.minions.minion.program.instruction.move.TurnDirection; import io.github.skippyall.minions.minion.program.instruction.move.TurnDirection;
import io.github.skippyall.minions.program.value.SimpleValueType; import io.github.skippyall.minions.program.value.SimpleValueType;
import io.github.skippyall.minions.program.value.ValueType; import io.github.skippyall.minions.program.value.ValueType;
import java.util.concurrent.CompletableFuture;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import java.util.concurrent.CompletableFuture;
public class ValueTypes { public class ValueTypes {
public static ValueType<Long> LONG = register( public static ValueType<Long> LONG = register(
@@ -18,10 +19,10 @@ public class ValueTypes {
Codec.LONG, Codec.LONG,
0L, 0L,
o -> o instanceof Long l ? l : null, o -> o instanceof Long l ? l : null,
(parent, oldValue) -> TextInput.inputLong( (parent, oldValue) -> TextInput.inputLongFuture(
parent, parent,
Component.literal("Integer"), Component.literal("Integer"),
String.valueOf(oldValue) oldValue
), ),
value -> Component.literal(value.toString()) value -> Component.literal(value.toString())
) )
@@ -33,10 +34,10 @@ public class ValueTypes {
Codec.DOUBLE, Codec.DOUBLE,
0D, 0D,
o -> o instanceof Double d ? d : null, o -> o instanceof Double d ? d : null,
(parent, oldValue) -> TextInput.inputDouble( (parent, oldValue) -> TextInput.inputDoubleFuture(
parent, parent,
Component.literal("Number"), Component.literal("Number"),
String.valueOf(oldValue) oldValue
), ),
value -> Component.literal(value.toString()) value -> Component.literal(value.toString())
) )
@@ -60,11 +61,11 @@ public class ValueTypes {
Codec.STRING, Codec.STRING,
"", "",
o -> o instanceof String s ? s : null, o -> o instanceof String s ? s : null,
((parent, oldValue) -> TextInput.inputString( ((parent, oldValue) -> TextInput.inputStringFuture(
parent, parent,
Component.literal("Text"), Component.literal("Text"),
oldValue) oldValue
), )),
value -> Component.literal("\"" + value + "\"") value -> Component.literal("\"" + value + "\"")
) )
); );
@@ -85,7 +86,7 @@ public class ValueTypes {
String id, String id,
T type T type
) { ) {
ResourceLocation identifier = ResourceLocation.fromNamespaceAndPath(Minions.MOD_ID, id); Identifier identifier = Identifier.fromNamespaceAndPath(Minions.MOD_ID, id);
Registry.register( Registry.register(
MinionRegistries.VALUE_TYPES, MinionRegistries.VALUE_TYPES,
identifier, identifier,
@@ -1,11 +1,11 @@
package io.github.skippyall.minions.util; package io.github.skippyall.minions.util;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
public class ModelIdUtil { public class ModelIdUtil {
public static ResourceLocation getItemModelId(Item item) { public static Identifier getItemModelId(Item item) {
return BuiltInRegistries.ITEM.getKey(item); return BuiltInRegistries.ITEM.getKey(item);
} }
} }

Some files were not shown because too many files have changed in this diff Show More