mirror of
https://github.com/Minestom/Minestom.git
synced 2025-02-04 22:41:26 +01:00
Registry Updates (Villagers, Entity) (#2465)
* Add VillagerType and VillagerProfession generators and implementation, add a few new entity registry fields * Fix NBT serialization and remove unused code * Bump DataGen version and change VillagerType to GenericEnumGenerator
This commit is contained in:
parent
10e69be65e
commit
c44fe9db46
@ -36,6 +36,8 @@ public class Generators {
|
||||
resource("consume_effects.json"), outputFolder).packagePrivate().generate();
|
||||
new GenericEnumGenerator("net.minestom.server.command", "ArgumentParserType",
|
||||
resource("command_arguments.json"), outputFolder).generate();
|
||||
new GenericEnumGenerator("net.minestom.server.entity", "VillagerType",
|
||||
resource("villager_types.json"), outputFolder).generate();
|
||||
|
||||
var generator = new CodeGenerator(outputFolder);
|
||||
|
||||
@ -49,6 +51,8 @@ public class Generators {
|
||||
generator.generate(resource("custom_statistics.json"), "net.minestom.server.statistic", "StatisticType", "StatisticTypeImpl", "StatisticTypes");
|
||||
generator.generate(resource("attributes.json"), "net.minestom.server.entity.attribute", "Attribute", "AttributeImpl", "Attributes");
|
||||
generator.generate(resource("feature_flags.json"), "net.minestom.server", "FeatureFlag", "FeatureFlagImpl", "FeatureFlags");
|
||||
generator.generate(resource("villager_professions.json"), "net.minestom.server.entity", "VillagerProfession", "VillagerProfessionImpl", "VillagerProfessions");
|
||||
|
||||
|
||||
// Dynamic registries
|
||||
generator.generateKeys(resource("chat_types.json"), "net.minestom.server.message", "ChatType", "ChatTypes");
|
||||
@ -65,17 +69,7 @@ public class Generators {
|
||||
|
||||
// Generate fluids
|
||||
new FluidGenerator(resource("fluids.json"), outputFolder).generate();
|
||||
|
||||
// TODO: Generate villager professions
|
||||
// new VillagerProfessionGenerator(
|
||||
// new File(inputFolder, targetVersion + "_villager_professions.json"),
|
||||
// outputFolder
|
||||
// ).generate();
|
||||
// TODO: Generate villager types
|
||||
// new VillagerTypeGenerator(
|
||||
// new File(inputFolder, targetVersion + "_villager_types.json"),
|
||||
// outputFolder
|
||||
// ).generate();
|
||||
|
||||
LOGGER.info("Finished generating code");
|
||||
}
|
||||
|
||||
|
@ -1,212 +0,0 @@
|
||||
package net.minestom.codegen.entity;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.squareup.javapoet.*;
|
||||
import net.minestom.codegen.MinestomCodeGenerator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
|
||||
public final class VillagerProfessionGenerator extends MinestomCodeGenerator {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(VillagerProfessionGenerator.class);
|
||||
private final InputStream villagerProfessionsFile;
|
||||
private final File outputFolder;
|
||||
|
||||
|
||||
public VillagerProfessionGenerator(@Nullable InputStream villagerProfessionsFile, @NotNull File outputFolder) {
|
||||
this.villagerProfessionsFile = villagerProfessionsFile;
|
||||
this.outputFolder = outputFolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate() {
|
||||
if (villagerProfessionsFile == null) {
|
||||
LOGGER.error("Failed to find villager_professions.json.");
|
||||
LOGGER.error("Stopped code generation for villager professions.");
|
||||
return;
|
||||
}
|
||||
if (!outputFolder.exists() && !outputFolder.mkdirs()) {
|
||||
LOGGER.error("Output folder for code generation does not exist and could not be created.");
|
||||
return;
|
||||
}
|
||||
// Important classes we use alot
|
||||
ClassName namespaceIDClassName = ClassName.get("net.minestom.server.utils", "NamespaceID");
|
||||
ClassName rawVillagerProfessionDataClassName = ClassName.get("net.minestom.server.raw_data", "RawVillagerProfessionData");
|
||||
ClassName registryClassName = ClassName.get("net.minestom.server.registry", "Registry");
|
||||
|
||||
JsonArray villagerProfessions = GSON.fromJson(new InputStreamReader(villagerProfessionsFile), JsonArray.class);
|
||||
ClassName villagerProfessionClassName = ClassName.get("net.minestom.server.entity.metadata.villager", "VillagerProfession");
|
||||
|
||||
// Particle
|
||||
TypeSpec.Builder villagerProfessionClass = TypeSpec.classBuilder(villagerProfessionClassName)
|
||||
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
|
||||
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
|
||||
villagerProfessionClass.addField(
|
||||
FieldSpec.builder(namespaceIDClassName, "id")
|
||||
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
|
||||
);
|
||||
villagerProfessionClass.addField(
|
||||
FieldSpec.builder(rawVillagerProfessionDataClassName, "villagerProfessionData")
|
||||
.addModifiers(Modifier.PRIVATE, Modifier.VOLATILE)
|
||||
.addAnnotation(NotNull.class)
|
||||
.build()
|
||||
);
|
||||
villagerProfessionClass.addMethod(
|
||||
MethodSpec.constructorBuilder()
|
||||
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
|
||||
.addParameter(ParameterSpec.builder(rawVillagerProfessionDataClassName, "villagerProfessionData").addAnnotation(NotNull.class).build())
|
||||
.addStatement("this.id = id")
|
||||
.addStatement("this.villagerProfessionData = villagerProfessionData")
|
||||
.addModifiers(Modifier.PROTECTED)
|
||||
.build()
|
||||
);
|
||||
// Override key method (adventure)
|
||||
villagerProfessionClass.addMethod(
|
||||
MethodSpec.methodBuilder("key")
|
||||
.returns(ClassName.get("net.kyori.adventure.key", "Key"))
|
||||
.addAnnotation(Override.class)
|
||||
.addAnnotation(NotNull.class)
|
||||
.addStatement("return this.id")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.build()
|
||||
);
|
||||
// getId method
|
||||
villagerProfessionClass.addMethod(
|
||||
MethodSpec.methodBuilder("getId")
|
||||
.returns(namespaceIDClassName)
|
||||
.addAnnotation(NotNull.class)
|
||||
.addStatement("return this.id")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.build()
|
||||
);
|
||||
// getVillagerProfessionData method
|
||||
villagerProfessionClass.addMethod(
|
||||
MethodSpec.methodBuilder("getVillagerProfessionData")
|
||||
.returns(rawVillagerProfessionDataClassName)
|
||||
.addAnnotation(NotNull.class)
|
||||
.addStatement("return this.villagerProfessionData")
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
||||
.build()
|
||||
);
|
||||
// setVillagerProfessionData method
|
||||
villagerProfessionClass.addMethod(
|
||||
MethodSpec.methodBuilder("setVillagerProfessionData")
|
||||
.addParameter(ParameterSpec.builder(rawVillagerProfessionDataClassName, "villagerProfessionData").addAnnotation(NotNull.class).build())
|
||||
.addStatement("this.villagerProfessionData = villagerProfessionData")
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
||||
.build()
|
||||
);
|
||||
// getNumericalId
|
||||
villagerProfessionClass.addMethod(
|
||||
MethodSpec.methodBuilder("getNumericalId")
|
||||
.returns(TypeName.INT)
|
||||
.addStatement("return $T.VILLAGER_PROFESSION_REGISTRY.getId(this)", registryClassName)
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.build()
|
||||
);
|
||||
// fromId Method
|
||||
villagerProfessionClass.addMethod(
|
||||
MethodSpec.methodBuilder("fromId")
|
||||
.returns(villagerProfessionClassName)
|
||||
.addAnnotation(Nullable.class)
|
||||
.addParameter(TypeName.INT, "id")
|
||||
.addStatement("return $T.VILLAGER_PROFESSION_REGISTRY.get((short) id)", registryClassName)
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||
.build()
|
||||
);
|
||||
// fromId Method
|
||||
villagerProfessionClass.addMethod(
|
||||
MethodSpec.methodBuilder("fromId")
|
||||
.returns(villagerProfessionClassName)
|
||||
.addAnnotation(NotNull.class)
|
||||
.addParameter(ClassName.get("net.kyori.adventure.key", "Key"), "id")
|
||||
.addStatement("return $T.VILLAGER_PROFESSION_REGISTRY.get(id)", registryClassName)
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||
.build()
|
||||
);
|
||||
// toString method
|
||||
villagerProfessionClass.addMethod(
|
||||
MethodSpec.methodBuilder("toString")
|
||||
.addAnnotation(NotNull.class)
|
||||
.addAnnotation(Override.class)
|
||||
.returns(String.class)
|
||||
// this resolves to [Namespace]
|
||||
.addStatement("return \"[\" + this.id + \"]\"")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.build()
|
||||
);
|
||||
// values method
|
||||
villagerProfessionClass.addMethod(
|
||||
MethodSpec.methodBuilder("values")
|
||||
.addAnnotation(NotNull.class)
|
||||
.returns(ParameterizedTypeName.get(ClassName.get(List.class), villagerProfessionClassName))
|
||||
.addStatement("return $T.VILLAGER_PROFESSION_REGISTRY.values()", registryClassName)
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||
.build()
|
||||
);
|
||||
CodeBlock.Builder staticBlock = CodeBlock.builder();
|
||||
// Use data
|
||||
for (JsonElement vp : villagerProfessions) {
|
||||
JsonObject villagerProfession = vp.getAsJsonObject();
|
||||
|
||||
String villagerProfessionName = villagerProfession.get("name").getAsString();
|
||||
JsonElement workSound = villagerProfession.get("workSound");
|
||||
if (workSound == null) {
|
||||
villagerProfessionClass.addField(
|
||||
FieldSpec.builder(
|
||||
villagerProfessionClassName,
|
||||
villagerProfessionName
|
||||
).initializer(
|
||||
"new $T($T.from($S), new $T(() -> null))",
|
||||
villagerProfessionClassName,
|
||||
namespaceIDClassName,
|
||||
villagerProfession.get("id").getAsString(),
|
||||
|
||||
rawVillagerProfessionDataClassName
|
||||
).addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).build()
|
||||
);
|
||||
} else {
|
||||
villagerProfessionClass.addField(
|
||||
FieldSpec.builder(
|
||||
villagerProfessionClassName,
|
||||
villagerProfessionName
|
||||
).initializer(
|
||||
"new $T($T.from($S), new $T(() -> $T.SOUND_EVENT_REGISTRY.get($S)))",
|
||||
villagerProfessionClassName,
|
||||
namespaceIDClassName,
|
||||
villagerProfession.get("id").getAsString(),
|
||||
|
||||
rawVillagerProfessionDataClassName,
|
||||
registryClassName,
|
||||
workSound.getAsString()
|
||||
).addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).build()
|
||||
);
|
||||
}
|
||||
|
||||
// Add to static init.
|
||||
staticBlock.addStatement("$T.VILLAGER_PROFESSION_REGISTRY.register($N)", registryClassName, villagerProfessionName);
|
||||
}
|
||||
|
||||
villagerProfessionClass.addStaticBlock(staticBlock.build());
|
||||
|
||||
// Write files to outputFolder
|
||||
writeFiles(
|
||||
List.of(
|
||||
JavaFile.builder("net.minestom.server.entity.metadata.villager", villagerProfessionClass.build())
|
||||
.indent(" ")
|
||||
.skipJavaLangImports(true)
|
||||
.build()
|
||||
),
|
||||
outputFolder
|
||||
);
|
||||
}
|
||||
}
|
@ -1,164 +0,0 @@
|
||||
package net.minestom.codegen.entity;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.squareup.javapoet.*;
|
||||
import net.minestom.codegen.MinestomCodeGenerator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
|
||||
public final class VillagerTypeGenerator extends MinestomCodeGenerator {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(VillagerTypeGenerator.class);
|
||||
private final InputStream villagerTypesFile;
|
||||
private final File outputFolder;
|
||||
|
||||
public VillagerTypeGenerator(@Nullable InputStream villagerTypesFile, @NotNull File outputFolder) {
|
||||
this.villagerTypesFile = villagerTypesFile;
|
||||
this.outputFolder = outputFolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate() {
|
||||
if (villagerTypesFile == null) {
|
||||
LOGGER.error("Failed to find villager_types.json.");
|
||||
LOGGER.error("Stopped code generation for villager types.");
|
||||
return;
|
||||
}
|
||||
if (!outputFolder.exists() && !outputFolder.mkdirs()) {
|
||||
LOGGER.error("Output folder for code generation does not exist and could not be created.");
|
||||
return;
|
||||
}
|
||||
// Important classes we use alot
|
||||
ClassName namespaceIDClassName = ClassName.get("net.minestom.server.utils", "NamespaceID");
|
||||
ClassName registryClassName = ClassName.get("net.minestom.server.registry", "Registry");
|
||||
|
||||
JsonArray villagerTypes = GSON.fromJson(new InputStreamReader(villagerTypesFile), JsonArray.class);
|
||||
ClassName villagerTypeClassName = ClassName.get("net.minestom.server.entity.metadata.villager", "VillagerType");
|
||||
|
||||
// Particle
|
||||
TypeSpec.Builder villagerTypeClass = TypeSpec.classBuilder(villagerTypeClassName)
|
||||
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
|
||||
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
|
||||
villagerTypeClass.addField(
|
||||
FieldSpec.builder(namespaceIDClassName, "id")
|
||||
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
|
||||
);
|
||||
villagerTypeClass.addMethod(
|
||||
MethodSpec.constructorBuilder()
|
||||
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
|
||||
.addStatement("this.id = id")
|
||||
.addModifiers(Modifier.PROTECTED)
|
||||
.build()
|
||||
);
|
||||
// Override key method (adventure)
|
||||
villagerTypeClass.addMethod(
|
||||
MethodSpec.methodBuilder("key")
|
||||
.returns(ClassName.get("net.kyori.adventure.key", "Key"))
|
||||
.addAnnotation(Override.class)
|
||||
.addAnnotation(NotNull.class)
|
||||
.addStatement("return this.id")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.build()
|
||||
);
|
||||
// getId method
|
||||
villagerTypeClass.addMethod(
|
||||
MethodSpec.methodBuilder("getId")
|
||||
.returns(namespaceIDClassName)
|
||||
.addAnnotation(NotNull.class)
|
||||
.addStatement("return this.id")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.build()
|
||||
);
|
||||
// getNumericalId
|
||||
villagerTypeClass.addMethod(
|
||||
MethodSpec.methodBuilder("getNumericalId")
|
||||
.returns(TypeName.INT)
|
||||
.addStatement("return $T.VILLAGER_TYPE_REGISTRY.getId(this)", registryClassName)
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.build()
|
||||
);
|
||||
// fromId Method
|
||||
villagerTypeClass.addMethod(
|
||||
MethodSpec.methodBuilder("fromId")
|
||||
.returns(villagerTypeClassName)
|
||||
.addAnnotation(Nullable.class)
|
||||
.addParameter(TypeName.INT, "id")
|
||||
.addStatement("return $T.VILLAGER_TYPE_REGISTRY.get((short) id)", registryClassName)
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||
.build()
|
||||
);
|
||||
// fromId Method
|
||||
villagerTypeClass.addMethod(
|
||||
MethodSpec.methodBuilder("fromId")
|
||||
.returns(villagerTypeClassName)
|
||||
.addAnnotation(NotNull.class)
|
||||
.addParameter(ClassName.get("net.kyori.adventure.key", "Key"), "id")
|
||||
.addStatement("return $T.VILLAGER_TYPE_REGISTRY.get(id)", registryClassName)
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||
.build()
|
||||
);
|
||||
// toString method
|
||||
villagerTypeClass.addMethod(
|
||||
MethodSpec.methodBuilder("toString")
|
||||
.addAnnotation(NotNull.class)
|
||||
.addAnnotation(Override.class)
|
||||
.returns(String.class)
|
||||
// this resolves to [Namespace]
|
||||
.addStatement("return \"[\" + this.id + \"]\"")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.build()
|
||||
);
|
||||
// values method
|
||||
villagerTypeClass.addMethod(
|
||||
MethodSpec.methodBuilder("values")
|
||||
.addAnnotation(NotNull.class)
|
||||
.returns(ParameterizedTypeName.get(ClassName.get(List.class), villagerTypeClassName))
|
||||
.addStatement("return $T.VILLAGER_TYPE_REGISTRY.values()", registryClassName)
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||
.build()
|
||||
);
|
||||
CodeBlock.Builder staticBlock = CodeBlock.builder();
|
||||
// Use data
|
||||
for (JsonElement vp : villagerTypes) {
|
||||
JsonObject villagerProfession = vp.getAsJsonObject();
|
||||
|
||||
String villagerProfessionName = villagerProfession.get("name").getAsString();
|
||||
|
||||
villagerTypeClass.addField(
|
||||
FieldSpec.builder(
|
||||
villagerTypeClassName,
|
||||
villagerProfessionName
|
||||
).initializer(
|
||||
"new $T($T.from($S))",
|
||||
villagerTypeClassName,
|
||||
namespaceIDClassName,
|
||||
villagerProfession.get("id").getAsString()
|
||||
).addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).build()
|
||||
);
|
||||
// Add to static init.
|
||||
staticBlock.addStatement("$T.VILLAGER_TYPE_REGISTRY.register($N)", registryClassName, villagerProfessionName);
|
||||
}
|
||||
|
||||
villagerTypeClass.addStaticBlock(staticBlock.build());
|
||||
|
||||
// Write files to outputFolder
|
||||
writeFiles(
|
||||
List.of(
|
||||
JavaFile.builder("net.minestom.server.entity.metadata.villager", villagerTypeClass.build())
|
||||
.indent(" ")
|
||||
.skipJavaLangImports(true)
|
||||
.build()
|
||||
),
|
||||
outputFolder
|
||||
);
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ metadata.format.version = "1.1"
|
||||
[versions]
|
||||
|
||||
# Important dependencies
|
||||
data = "1.21.3-rv1"
|
||||
data = "1.21.3-rv2"
|
||||
adventure = "4.17.0"
|
||||
jetbrainsAnnotations = "24.1.0"
|
||||
slf4j = "2.0.7"
|
||||
|
@ -0,0 +1,37 @@
|
||||
package net.minestom.server.entity;
|
||||
|
||||
/**
|
||||
* Code autogenerated, do not edit!
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
interface VillagerProfessions {
|
||||
VillagerProfession NONE = VillagerProfessionImpl.get("minecraft:none");
|
||||
|
||||
VillagerProfession ARMORER = VillagerProfessionImpl.get("minecraft:armorer");
|
||||
|
||||
VillagerProfession BUTCHER = VillagerProfessionImpl.get("minecraft:butcher");
|
||||
|
||||
VillagerProfession CARTOGRAPHER = VillagerProfessionImpl.get("minecraft:cartographer");
|
||||
|
||||
VillagerProfession CLERIC = VillagerProfessionImpl.get("minecraft:cleric");
|
||||
|
||||
VillagerProfession FARMER = VillagerProfessionImpl.get("minecraft:farmer");
|
||||
|
||||
VillagerProfession FISHERMAN = VillagerProfessionImpl.get("minecraft:fisherman");
|
||||
|
||||
VillagerProfession FLETCHER = VillagerProfessionImpl.get("minecraft:fletcher");
|
||||
|
||||
VillagerProfession LEATHERWORKER = VillagerProfessionImpl.get("minecraft:leatherworker");
|
||||
|
||||
VillagerProfession LIBRARIAN = VillagerProfessionImpl.get("minecraft:librarian");
|
||||
|
||||
VillagerProfession MASON = VillagerProfessionImpl.get("minecraft:mason");
|
||||
|
||||
VillagerProfession NITWIT = VillagerProfessionImpl.get("minecraft:nitwit");
|
||||
|
||||
VillagerProfession SHEPHERD = VillagerProfessionImpl.get("minecraft:shepherd");
|
||||
|
||||
VillagerProfession TOOLSMITH = VillagerProfessionImpl.get("minecraft:toolsmith");
|
||||
|
||||
VillagerProfession WEAPONSMITH = VillagerProfessionImpl.get("minecraft:weaponsmith");
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package net.minestom.server.entity;
|
||||
|
||||
import net.minestom.server.network.NetworkBuffer;
|
||||
import net.minestom.server.registry.StaticProtocolObject;
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import net.minestom.server.utils.nbt.BinaryTagSerializer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* AUTOGENERATED by GenericEnumGenerator
|
||||
*/
|
||||
public enum VillagerType implements StaticProtocolObject {
|
||||
DESERT(NamespaceID.from("minecraft:desert")),
|
||||
|
||||
JUNGLE(NamespaceID.from("minecraft:jungle")),
|
||||
|
||||
PLAINS(NamespaceID.from("minecraft:plains")),
|
||||
|
||||
SAVANNA(NamespaceID.from("minecraft:savanna")),
|
||||
|
||||
SNOW(NamespaceID.from("minecraft:snow")),
|
||||
|
||||
SWAMP(NamespaceID.from("minecraft:swamp")),
|
||||
|
||||
TAIGA(NamespaceID.from("minecraft:taiga"));
|
||||
|
||||
public static final NetworkBuffer.Type<VillagerType> NETWORK_TYPE = NetworkBuffer.Enum(VillagerType.class);
|
||||
|
||||
public static final BinaryTagSerializer<VillagerType> NBT_TYPE = BinaryTagSerializer.fromEnumKeyed(VillagerType.class);
|
||||
|
||||
private final NamespaceID namespace;
|
||||
|
||||
VillagerType(@NotNull NamespaceID namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public NamespaceID namespace() {
|
||||
return this.namespace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int id() {
|
||||
return this.ordinal();
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package net.minestom.server.entity;
|
||||
|
||||
import net.minestom.server.network.NetworkBuffer;
|
||||
import net.minestom.server.registry.Registry;
|
||||
import net.minestom.server.registry.StaticProtocolObject;
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import net.minestom.server.utils.nbt.BinaryTagSerializer;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public sealed interface VillagerProfession extends StaticProtocolObject, VillagerProfessions permits VillagerProfessionImpl {
|
||||
|
||||
NetworkBuffer.Type<VillagerProfession> NETWORK_TYPE = NetworkBuffer.VAR_INT.transform(VillagerProfession::fromId, VillagerProfession::id);
|
||||
BinaryTagSerializer<VillagerProfession> NBT_TYPE = BinaryTagSerializer.STRING.map(VillagerProfessionImpl::getSafe, VillagerProfession::name);
|
||||
|
||||
@Contract(pure = true)
|
||||
@NotNull Registry.VillagerProfessionEntry registry();
|
||||
|
||||
@Override
|
||||
default @NotNull NamespaceID namespace() {
|
||||
return registry().namespace();
|
||||
}
|
||||
|
||||
@Override
|
||||
default int id() {
|
||||
return registry().id();
|
||||
}
|
||||
|
||||
|
||||
static @Nullable VillagerProfession fromId(int id) {
|
||||
return VillagerProfessionImpl.getId(id);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package net.minestom.server.entity;
|
||||
|
||||
import net.minestom.server.registry.Registry;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public record VillagerProfessionImpl(Registry.VillagerProfessionEntry registry) implements VillagerProfession {
|
||||
private static final Registry.Container<VillagerProfession> CONTAINER = Registry.createStaticContainer(Registry.Resource.VILLAGER_PROFESSIONS,
|
||||
(namespace, properties) -> new VillagerProfessionImpl(Registry.villagerProfession(namespace, properties)));
|
||||
|
||||
static VillagerProfession get(@NotNull String namespace) {
|
||||
return CONTAINER.get(namespace);
|
||||
}
|
||||
|
||||
static VillagerProfession getSafe(@NotNull String namespace) {
|
||||
return CONTAINER.getSafe(namespace);
|
||||
}
|
||||
|
||||
static VillagerProfession getId(int id) {
|
||||
return CONTAINER.getId(id);
|
||||
}
|
||||
|
||||
static Collection<VillagerProfession> values() {
|
||||
return CONTAINER.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name();
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ package net.minestom.server.entity.metadata.monster.zombie;
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.MetadataDef;
|
||||
import net.minestom.server.entity.MetadataHolder;
|
||||
import net.minestom.server.entity.*;
|
||||
import net.minestom.server.entity.metadata.villager.VillagerMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ -22,14 +23,14 @@ public class ZombieVillagerMeta extends ZombieMeta {
|
||||
public VillagerMeta.VillagerData getVillagerData() {
|
||||
int[] data = metadata.get(MetadataDef.ZombieVillager.VILLAGER_DATA);
|
||||
if (data == null) {
|
||||
return new VillagerMeta.VillagerData(VillagerMeta.Type.PLAINS, VillagerMeta.Profession.NONE, VillagerMeta.Level.NOVICE);
|
||||
return new VillagerMeta.VillagerData(VillagerType.PLAINS, VillagerProfession.NONE, VillagerMeta.Level.NOVICE);
|
||||
}
|
||||
return new VillagerMeta.VillagerData(VillagerMeta.Type.VALUES[data[0]], VillagerMeta.Profession.VALUES[data[1]], VillagerMeta.Level.VALUES[data[2] - 1]);
|
||||
return new VillagerMeta.VillagerData(VillagerType.values()[data[0]], VillagerProfession.fromId(data[1]), VillagerMeta.Level.VALUES[data[2] - 1]);
|
||||
}
|
||||
|
||||
public void setVillagerData(VillagerMeta.VillagerData data) {
|
||||
int[] value = new int[]{data.getType().ordinal(), data.getProfession().ordinal(), data.getLevel().ordinal() + 1};
|
||||
metadata.set(MetadataDef.ZombieVillager.VILLAGER_DATA, value);
|
||||
public void setVillagerData(@NotNull VillagerMeta.VillagerData data) {
|
||||
int[] value = new int[]{data.villagerType().ordinal(), data.villagerProfession().id(), data.level().ordinal() + 1};
|
||||
metadata.set(MetadataDef.Villager.VARIANT, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package net.minestom.server.entity.metadata.villager;
|
||||
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.MetadataDef;
|
||||
import net.minestom.server.entity.MetadataHolder;
|
||||
import net.minestom.server.entity.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class VillagerMeta extends AbstractVillagerMeta {
|
||||
@ -14,88 +12,17 @@ public class VillagerMeta extends AbstractVillagerMeta {
|
||||
public VillagerData getVillagerData() {
|
||||
int[] data = metadata.get(MetadataDef.Villager.VARIANT);
|
||||
if (data == null) {
|
||||
return new VillagerData(Type.PLAINS, Profession.NONE, Level.NOVICE);
|
||||
return new VillagerData(VillagerType.PLAINS, VillagerProfession.NONE, Level.NOVICE);
|
||||
}
|
||||
return new VillagerData(Type.VALUES[data[0]], Profession.VALUES[data[1]], Level.VALUES[data[2] - 1]);
|
||||
return new VillagerData(VillagerType.values()[data[0]], VillagerProfession.fromId(data[1]), Level.VALUES[data[2] - 1]);
|
||||
}
|
||||
|
||||
public void setVillagerData(@NotNull VillagerData data) {
|
||||
int[] value = new int[]{data.type.ordinal(), data.profession.ordinal(), data.level.ordinal() + 1};
|
||||
int[] value = new int[]{data.villagerType.ordinal(), data.villagerProfession.id(), data.level.ordinal() + 1};
|
||||
metadata.set(MetadataDef.Villager.VARIANT, value);
|
||||
}
|
||||
|
||||
public static class VillagerData {
|
||||
|
||||
private Type type;
|
||||
private Profession profession;
|
||||
private Level level;
|
||||
|
||||
public VillagerData(@NotNull Type type, @NotNull Profession profession, @NotNull Level level) {
|
||||
this.type = type;
|
||||
this.profession = profession;
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public void setType(@NotNull Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Profession getProfession() {
|
||||
return this.profession;
|
||||
}
|
||||
|
||||
public void setProfession(@NotNull Profession profession) {
|
||||
this.profession = profession;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Level getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(@NotNull Level level) {
|
||||
this.level = level;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
DESERT,
|
||||
JUNGLE,
|
||||
PLAINS,
|
||||
SAVANNA,
|
||||
SNOW,
|
||||
SWAMP,
|
||||
TAIGA;
|
||||
|
||||
public final static Type[] VALUES = values();
|
||||
}
|
||||
|
||||
public enum Profession {
|
||||
NONE,
|
||||
ARMORER,
|
||||
BUTCHER,
|
||||
CARTOGRAPHER,
|
||||
CLERIC,
|
||||
FARMER,
|
||||
FISHERMAN,
|
||||
FLETCHER,
|
||||
LEATHERWORKER,
|
||||
LIBRARIAN,
|
||||
NITWIT,
|
||||
UNEMPLOYED,
|
||||
MASON,
|
||||
SHEPHERD,
|
||||
TOOLSMITH,
|
||||
WEAPONSMITH;
|
||||
|
||||
public final static Profession[] VALUES = values();
|
||||
}
|
||||
public record VillagerData(@NotNull VillagerType villagerType, @NotNull VillagerProfession villagerProfession, @NotNull Level level) { }
|
||||
|
||||
public enum Level {
|
||||
NOVICE,
|
||||
|
@ -70,6 +70,11 @@ public final class Registry {
|
||||
return new EntityEntry(namespace, main, null);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static VillagerProfessionEntry villagerProfession(String namespace, @NotNull Properties main) {
|
||||
return new VillagerProfessionEntry(namespace, main, null);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static FeatureFlagEntry featureFlag(String namespace, @NotNull Properties main) {
|
||||
return new FeatureFlagEntry(namespace, main, null);
|
||||
@ -236,7 +241,8 @@ public final class Registry {
|
||||
CHAT_TYPES("chat_types.json"),
|
||||
ENCHANTMENTS("enchantments.snbt"),
|
||||
PAINTING_VARIANTS("painting_variants.json"),
|
||||
JUKEBOX_SONGS("jukebox_songs.json");
|
||||
JUKEBOX_SONGS("jukebox_songs.json"),
|
||||
VILLAGER_PROFESSIONS("villager_professions.json");
|
||||
|
||||
private final String name;
|
||||
|
||||
@ -648,6 +654,9 @@ public final class Registry {
|
||||
private final double width;
|
||||
private final double height;
|
||||
private final double eyeHeight;
|
||||
private final int clientTrackingRange;
|
||||
private final boolean fireImmune;
|
||||
private final Map<String, List<Double>> entityOffsets;
|
||||
private final BoundingBox boundingBox;
|
||||
private final Properties custom;
|
||||
|
||||
@ -658,6 +667,8 @@ public final class Registry {
|
||||
this.drag = main.getDouble("drag", 0.02);
|
||||
this.acceleration = main.getDouble("acceleration", 0.08);
|
||||
this.spawnType = EntitySpawnType.valueOf(main.getString("packetType").toUpperCase(Locale.ROOT));
|
||||
this.fireImmune = main.getBoolean("fireImmune", false);
|
||||
this.clientTrackingRange = main.getInt("clientTrackingRange");
|
||||
|
||||
// Dimensions
|
||||
this.width = main.getDouble("width");
|
||||
@ -666,9 +677,14 @@ public final class Registry {
|
||||
this.boundingBox = new BoundingBox(this.width, this.height, this.width);
|
||||
|
||||
// Attachments
|
||||
this.entityOffsets = new HashMap<>();
|
||||
Properties attachments = main.section("attachments");
|
||||
if (attachments != null) {
|
||||
//todo
|
||||
var allAttachments = attachments.asMap().keySet();
|
||||
for (String key : allAttachments) {
|
||||
var offset = attachments.getNestedDoubleArray(key);
|
||||
this.entityOffsets.put(key, offset.getFirst()); // It's an array of an array with a single element, as of 1.21.3 we only need to grab a single array of 3 doubles
|
||||
}
|
||||
}
|
||||
|
||||
this.custom = custom;
|
||||
@ -710,6 +726,20 @@ public final class Registry {
|
||||
return eyeHeight;
|
||||
}
|
||||
|
||||
public boolean fireImmune() { return fireImmune; }
|
||||
|
||||
public int clientTrackingRange() { return clientTrackingRange; }
|
||||
|
||||
/**
|
||||
*
|
||||
* Gets the entity attachment by name. Typically, will be PASSENGER or VEHICLE, but some entities have custom attachments (e.g. WARDEN_CHEST, NAMETAG)
|
||||
* @param attachmentName The attachment to retrieve
|
||||
* @return A list of 3 doubles if the attachment is defined for this entity, or null if it is not defined
|
||||
*/
|
||||
public @Nullable List<Double> entityAttachment(@NotNull String attachmentName) {
|
||||
return entityOffsets.get(attachmentName);
|
||||
}
|
||||
|
||||
public @NotNull BoundingBox boundingBox() {
|
||||
return boundingBox;
|
||||
}
|
||||
@ -720,6 +750,41 @@ public final class Registry {
|
||||
}
|
||||
}
|
||||
|
||||
public static final class VillagerProfessionEntry implements Entry {
|
||||
private final NamespaceID namespace;
|
||||
private final int id;
|
||||
private final SoundEvent workSound;
|
||||
private final Properties custom;
|
||||
|
||||
public VillagerProfessionEntry(String namespace, Properties main, Properties custom) {
|
||||
this.namespace = NamespaceID.from(namespace);
|
||||
this.id = main.getInt("id");
|
||||
if (main.containsKey("workSound")) {
|
||||
this.workSound = SoundEvent.fromNamespaceId(main.getString("workSound"));
|
||||
} else {
|
||||
this.workSound = null;
|
||||
}
|
||||
this.custom = custom;
|
||||
}
|
||||
|
||||
public @NotNull NamespaceID namespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
public int id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public @Nullable SoundEvent workSound() {
|
||||
return workSound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties custom() {
|
||||
return custom;
|
||||
}
|
||||
}
|
||||
|
||||
public record FeatureFlagEntry(NamespaceID namespace, int id, Properties custom) implements Entry {
|
||||
public FeatureFlagEntry(String namespace, Properties main, Properties custom) {
|
||||
this(NamespaceID.from(namespace),
|
||||
@ -1007,6 +1072,12 @@ public final class Registry {
|
||||
return element != null ? (boolean) element : defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<List<Double>> getNestedDoubleArray(String name) {
|
||||
var element = element(name);
|
||||
return element != null ? (List<List<Double>>) element : List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(String name) {
|
||||
return element(name);
|
||||
@ -1068,6 +1139,8 @@ public final class Registry {
|
||||
|
||||
boolean getBoolean(String name);
|
||||
|
||||
List<List<Double>> getNestedDoubleArray(String name);
|
||||
|
||||
Properties section(String name);
|
||||
|
||||
boolean containsKey(String name);
|
||||
|
Loading…
Reference in New Issue
Block a user