Make Material an interface

This commit is contained in:
TheMode 2021-07-27 09:40:57 +02:00
parent 5b044a2d38
commit d685a7b136
19 changed files with 2494 additions and 3104 deletions

View File

@ -164,7 +164,7 @@ dependencies {
}
api "com.github.Minestom:DependencyGetter:v1.0.1"
implementation 'com.github.Minestom:MinestomDataGenerator:386c3ef9c0'
implementation 'com.github.Minestom:MinestomDataGenerator:9f8b6a3748'
// Adventure, for user-interface
api "net.kyori:adventure-api:$adventureVersion"

View File

@ -50,7 +50,7 @@ public final class BlockGenerator extends MinestomCodeGenerator {
FieldSpec.builder(blockCN, constantName)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.initializer(
// Blocks.STONE = Block.fromNamespaceId("minecraft:stone")
// Block.STONE = Block.fromNamespaceId("minecraft:stone")
"$T.fromNamespaceId($S)",
blockCN,
namespace

View File

@ -1,7 +1,5 @@
package net.minestom.codegen.item;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.squareup.javapoet.*;
import net.minestom.codegen.MinestomCodeGenerator;
@ -14,8 +12,8 @@ import javax.lang.model.element.Modifier;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.function.Supplier;
import java.util.List;
import java.util.Locale;
public final class MaterialGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(MaterialGenerator.class);
@ -34,308 +32,35 @@ public final class MaterialGenerator extends MinestomCodeGenerator {
LOGGER.error("Stopped code generation for items.");
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 blockClassName = ClassName.get("net.minestom.server.instance.block", "Block");
ClassName registriesClassName = ClassName.get("net.minestom.server.registry", "Registries");
ClassName blockCN = ClassName.get("net.minestom.server.instance.block", "Block");
ParameterizedTypeName blocksCNSupplier = ParameterizedTypeName.get(ClassName.get(Supplier.class), blockCN);
ClassName materialCN = ClassName.get("net.minestom.server.item", "Material");
JsonObject items = GSON.fromJson(new InputStreamReader(itemsFile), JsonObject.class);
ClassName itemClassName = ClassName.get("net.minestom.server.item", "Material");
// Item
TypeSpec.Builder itemClass = TypeSpec.enumBuilder(itemClassName)
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
itemClass.addField(
FieldSpec.builder(namespaceIDClassName, "id")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
);
itemClass.addField(
FieldSpec.builder(TypeName.BYTE, "maxDefaultStackSize")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
);
itemClass.addField(
FieldSpec.builder(blocksCNSupplier, "correspondingBlockSupplier")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
);
// static field
itemClass.addField(
FieldSpec.builder(ArrayTypeName.of(itemClassName), "VALUES")
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
.initializer("values()")
.build()
);
itemClass.addMethod(
MethodSpec.constructorBuilder()
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
.addParameter(TypeName.BYTE, "maxDefaultStackSize")
.addParameter(ParameterSpec.builder(blocksCNSupplier, "correspondingBlockSupplier").addAnnotation(NotNull.class).build())
.addStatement("this.id = id")
.addStatement("this.maxDefaultStackSize = maxDefaultStackSize")
.addStatement("this.correspondingBlockSupplier = correspondingBlockSupplier")
.addStatement("$T.materials.put(id, this)", registriesClassName)
.build()
);
// Override key method (adventure)
itemClass.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
itemClass.addMethod(
MethodSpec.methodBuilder("getId")
.returns(TypeName.SHORT)
.addStatement("return (short) ordinal()")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getNamespaceID method
itemClass.addMethod(
MethodSpec.methodBuilder("getNamespaceID")
.returns(namespaceIDClassName)
.addAnnotation(NotNull.class)
.addStatement("return this.id")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getName method
itemClass.addMethod(
MethodSpec.methodBuilder("getName")
.addAnnotation(NotNull.class)
.returns(ClassName.get(String.class))
.addStatement("return this.id.asString()")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getMaxDefaultStackSize
itemClass.addMethod(
MethodSpec.methodBuilder("getMaxDefaultStackSize")
.returns(TypeName.BYTE)
.addStatement("return this.maxDefaultStackSize")
.addModifiers(Modifier.PUBLIC)
.build()
);
// fromId Method
itemClass.addMethod(
MethodSpec.methodBuilder("fromId")
.returns(itemClassName)
.addAnnotation(Nullable.class)
.addParameter(TypeName.SHORT, "id")
.beginControlFlow("if(id >= 0 && id < VALUES.length)")
.addStatement("return VALUES[id]")
.endControlFlow()
.addStatement("return null")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.build()
);
// isFood method
itemClass.addMethod(
MethodSpec.methodBuilder("isFood")
.returns(TypeName.BOOLEAN)
.addStatement("return false")
.addModifiers(Modifier.PUBLIC)
.build()
);
// hasState method
itemClass.addMethod(
MethodSpec.methodBuilder("hasState")
.returns(TypeName.BOOLEAN)
.beginControlFlow("if (this == BOW || this == TRIDENT || this == CROSSBOW || this == SHIELD)")
.addStatement("return true")
.nextControlFlow("else")
.addStatement("return isFood()")
.endControlFlow()
.addModifiers(Modifier.PUBLIC)
.build()
);
// isBlock method
itemClass.addMethod(
MethodSpec.methodBuilder("isBlock")
.returns(TypeName.BOOLEAN)
.addStatement(
"return this.correspondingBlockSupplier.get() != null && this.correspondingBlockSupplier.get() != $T.AIR",
blockCN
)
.addModifiers(Modifier.PUBLIC)
.build()
);
// isArmor method
itemClass.addMethod(
MethodSpec.methodBuilder("isArmor")
.returns(TypeName.BOOLEAN)
.addStatement("return false")
.addModifiers(Modifier.PUBLIC)
.build()
);
// isHelmet method
itemClass.addMethod(
MethodSpec.methodBuilder("isHelmet")
.returns(TypeName.BOOLEAN)
.addStatement("return false")
.addModifiers(Modifier.PUBLIC)
.build()
);
// isChestplate method
itemClass.addMethod(
MethodSpec.methodBuilder("isChestplate")
.returns(TypeName.BOOLEAN)
.addStatement("return false")
.addModifiers(Modifier.PUBLIC)
.build()
);
// isLeggings method
itemClass.addMethod(
MethodSpec.methodBuilder("isLeggings")
.returns(TypeName.BOOLEAN)
.addStatement("return false")
.addModifiers(Modifier.PUBLIC)
.build()
);
// isBoots method
itemClass.addMethod(
MethodSpec.methodBuilder("isBoots")
.returns(TypeName.BOOLEAN)
.addStatement("return false")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getBlock method
itemClass.addMethod(
MethodSpec.methodBuilder("getBlock")
.addAnnotation(Nullable.class)
.returns(blockCN)
.addStatement("return this.correspondingBlockSupplier.get()")
.addModifiers(Modifier.PUBLIC)
.build()
);
// toString method
itemClass.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()
);
JsonObject items;
items = GSON.fromJson(new InputStreamReader(itemsFile), JsonObject.class);
ClassName materialsCN = ClassName.get("net.minestom.server.item", "MaterialConstants");
// BlockConstants class
TypeSpec.Builder blockConstantsClass = TypeSpec.interfaceBuilder(materialsCN)
// Add @SuppressWarnings("unused")
.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "$S", "unused").build())
.addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
// Use data
items.entrySet().forEach(entry -> {
final String itemNamespace = entry.getKey();
final String itemConstant = toConstant(itemNamespace);
JsonObject item = entry.getValue().getAsJsonObject();
TypeSpec.Builder enumConst;
if (!(item.get("blockId").getAsString().equals("minecraft:air"))) {
enumConst = TypeSpec.anonymousClassBuilder(
"$T.from($S), (byte) $L, () -> $T.$L",
namespaceIDClassName,
itemNamespace,
item.get("maxStackSize").getAsInt(),
// Supplier
blockClassName,
toConstant(item.get("blockId").getAsString())
);
} else {
enumConst = TypeSpec.anonymousClassBuilder(
"$T.from($S), (byte) $L, () -> null",
namespaceIDClassName,
itemNamespace,
item.get("maxStackSize").getAsInt()
);
}
if (item.get("edible").getAsBoolean()) {
enumConst.addMethod(
MethodSpec.methodBuilder("isFood")
.returns(TypeName.BOOLEAN)
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.addStatement("return true")
.build()
);
}
if (item.get("armorProperties") != null) {
JsonObject ap = item.get("armorProperties").getAsJsonObject();
enumConst.addMethod(
MethodSpec.methodBuilder("isArmor")
.returns(TypeName.BOOLEAN)
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.addStatement("return true")
.build()
);
if (ap.get("slot") != null) {
switch (ap.get("slot").getAsString()) {
case "head": {
enumConst.addMethod(
MethodSpec.methodBuilder("isHelmet")
.returns(TypeName.BOOLEAN)
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.addStatement("return true")
.build()
);
break;
}
case "chest": {
enumConst.addMethod(
MethodSpec.methodBuilder("isChestplate")
.returns(TypeName.BOOLEAN)
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.addStatement("return true")
.build()
);
break;
}
case "legs": {
enumConst.addMethod(
MethodSpec.methodBuilder("isLeggings")
.returns(TypeName.BOOLEAN)
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.addStatement("return true")
.build()
);
break;
}
case "feet": {
enumConst.addMethod(
MethodSpec.methodBuilder("isBoots")
.returns(TypeName.BOOLEAN)
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.addStatement("return true")
.build()
);
break;
}
}
}
}
itemClass.addEnumConstant(itemConstant, enumConst.build());
items.keySet().forEach(namespace -> {
final String constantName = namespace.replace("minecraft:", "").toUpperCase(Locale.ROOT);
blockConstantsClass.addField(
FieldSpec.builder(materialCN, constantName)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.initializer(
// Material.STONE = Material.fromNamespaceId("minecraft:stone")
"$T.fromNamespaceId($S)",
materialCN,
namespace
)
.build()
);
});
// Write files to outputFolder
writeFiles(
Collections.singletonList(
JavaFile.builder("net.minestom.server.item", itemClass.build())
List.of(
JavaFile.builder("net.minestom.server.item", blockConstantsClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,5 @@
package net.minestom.server.entity;
import net.minestom.server.event.item.EntityEquipEvent;
import net.minestom.server.item.attribute.AttributeSlot;
import org.jetbrains.annotations.NotNull;
@ -20,8 +19,7 @@ public enum EquipmentSlot {
return !isHand();
}
@NotNull
public static EquipmentSlot fromAttributeSlot(AttributeSlot attributeSlot) {
public static EquipmentSlot fromAttributeSlot(@NotNull AttributeSlot attributeSlot) {
switch (attributeSlot) {
case MAINHAND:
return MAIN_HAND;
@ -38,5 +36,4 @@ public enum EquipmentSlot {
}
throw new IllegalStateException("Something weird happened");
}
}

View File

@ -19,7 +19,7 @@ import java.util.concurrent.ConcurrentHashMap;
* Loads {@link Block blocks} from file.
*/
@ApiStatus.Internal
class BlockLoader {
final class BlockLoader {
// Maps do not need to be thread-safe as they are fully populated
// in the static initializer, should not be modified during runtime
@ -39,11 +39,11 @@ class BlockLoader {
return NAMESPACE_MAP.get(namespace);
}
static @Nullable Block getId(int id) {
static Block getId(int id) {
return BLOCK_ID_MAP.get(id);
}
static @Nullable Block getState(int stateId) {
static Block getState(int stateId) {
return BLOCK_STATE_MAP.get(stateId);
}
@ -59,23 +59,23 @@ class BlockLoader {
final JsonObject blockObject = entry.getValue().getAsJsonObject();
final JsonObject stateObject = blockObject.remove("states").getAsJsonObject();
retrieveState(blockObject, stateObject);
retrieveState(blockNamespace, blockObject, stateObject);
final int defaultState = blockObject.get("defaultStateId").getAsInt();
final Block defaultBlock = getState(defaultState);
final int id = blockObject.get("id").getAsInt();
BLOCK_ID_MAP.put(id, defaultBlock);
BLOCK_ID_MAP.put(defaultBlock.id(), defaultBlock);
NAMESPACE_MAP.put(blockNamespace, defaultBlock);
});
}
private static void retrieveState(JsonObject object, JsonObject stateObject) {
private static void retrieveState(String namespace, JsonObject object, JsonObject stateObject) {
PropertyEntry propertyEntry = new PropertyEntry();
stateObject.entrySet().forEach(stateEntry -> {
final String query = stateEntry.getKey();
JsonObject stateOverride = stateEntry.getValue().getAsJsonObject();
final int stateId = stateOverride.get("stateId").getAsInt();
final var propertyMap = BlockUtils.parseProperties(query);
final Block block = new BlockImpl(Registry.block(object, stateOverride), propertyEntry, propertyMap, null, null);
final Block block = new BlockImpl(Registry.block(namespace, object, stateOverride),
propertyEntry, propertyMap, null, null);
BLOCK_STATE_MAP.put(stateId, block);
propertyEntry.map.put(propertyMap, block);
});

View File

@ -0,0 +1,75 @@
package net.minestom.server.item;
import net.minestom.server.instance.block.Block;
import net.minestom.server.registry.ProtocolObject;
import net.minestom.server.registry.Registry;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
public interface Material extends ProtocolObject, MaterialConstants {
/**
* Returns the material registry.
*
* @return the material registry
*/
@Contract(pure = true)
@NotNull Registry.MaterialEntry registry();
@Override
default @NotNull NamespaceID namespace() {
return registry().namespace();
}
@Override
default int id() {
return registry().id();
}
default int maxStackSize() {
return registry().maxStackSize();
}
default boolean isFood() {
return registry().isFood();
}
default boolean isBlock() {
return registry().block() != null;
}
default Block block() {
return registry().block();
}
default boolean isArmor() {
return registry().isArmor();
}
default boolean hasState() {
if (this == BOW || this == TRIDENT || this == CROSSBOW || this == SHIELD) {
return true;
} else {
return isFood();
}
}
static @NotNull Collection<@NotNull Material> values() {
return MaterialLoader.values();
}
static Material fromNamespaceId(@NotNull String namespaceID) {
return MaterialLoader.get(namespaceID);
}
static Material fromNamespaceId(@NotNull NamespaceID namespaceID) {
return fromNamespaceId(namespaceID.asString());
}
static @Nullable Material fromId(int id) {
return MaterialLoader.getId(id);
}
}

View File

@ -0,0 +1,17 @@
package net.minestom.server.item;
import net.minestom.server.registry.Registry;
import org.jetbrains.annotations.NotNull;
final class MaterialImpl implements Material {
private final Registry.MaterialEntry registry;
MaterialImpl(Registry.MaterialEntry registry) {
this.registry = registry;
}
@Override
public @NotNull Registry.MaterialEntry registry() {
return registry;
}
}

View File

@ -0,0 +1,58 @@
package net.minestom.server.item;
import com.google.gson.JsonObject;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minestom.server.registry.Registry;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* Loads {@link net.minestom.server.item.Material materials} from file.
*/
@ApiStatus.Internal
final class MaterialLoader {
// Maps do not need to be thread-safe as they are fully populated
// in the static initializer, should not be modified during runtime
// Block namespace -> registry data
private static final Map<String, Material> NAMESPACE_MAP = new HashMap<>();
// Block id -> registry data
private static final Int2ObjectMap<Material> MATERIAL_ID_MAP = new Int2ObjectOpenHashMap<>();
static @Nullable Material get(@NotNull String namespace) {
if (namespace.indexOf(':') == -1) {
// Default to minecraft namespace
namespace = "minecraft:" + namespace;
}
return NAMESPACE_MAP.get(namespace);
}
static Material getId(int id) {
return MATERIAL_ID_MAP.get(id);
}
static Collection<Material> values() {
return Collections.unmodifiableCollection(NAMESPACE_MAP.values());
}
static {
// Load data from file
JsonObject blocks = Registry.load(Registry.Resource.ITEM);
blocks.entrySet().forEach(entry -> {
final String namespace = entry.getKey();
final JsonObject materialObject = entry.getValue().getAsJsonObject();
final Material material = new MaterialImpl(Registry.material(namespace, materialObject, null));
MATERIAL_ID_MAP.put(material.id(), material);
NAMESPACE_MAP.put(namespace, material);
});
}
}

View File

@ -181,7 +181,7 @@ public class CrossbowMeta extends ItemMeta implements ItemMetaBuilder.Provider<S
private @NotNull NBTCompound getItemCompound(@NotNull ItemStack itemStack) {
NBTCompound compound = itemStack.getMeta().toNBT();
compound.setByte("Count", (byte) itemStack.getAmount());
compound.setString("id", itemStack.getMaterial().getName());
compound.setString("id", itemStack.getMaterial().name());
return compound;
}
}

View File

@ -31,7 +31,7 @@ public class VanillaStackingRule implements StackingRule {
@Override
public int getMaxSize(@NotNull ItemStack itemStack) {
return itemStack.getMaterial().getMaxDefaultStackSize();
return itemStack.getMaterial().maxStackSize();
}
@Override

View File

@ -109,7 +109,7 @@ public class BlockPlacementListener {
return;
}
final Block placedBlock = useMaterial.getBlock();
final Block placedBlock = useMaterial.block();
final Set<Entity> entities = instance.getChunkEntities(chunk);
// Check if the player is trying to place a block in an entity
boolean intersect = player.getBoundingBox().intersectWithBlock(placementPosition);

View File

@ -1,5 +1,6 @@
package net.minestom.server.listener;
import net.minestom.server.entity.EquipmentSlot;
import net.minestom.server.entity.Player;
import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.PlayerItemAnimationEvent;
@ -30,21 +31,10 @@ public class UseItemListener {
final Material material = itemStack.getMaterial();
// Equip armor with right click
if (material.isArmor()) {
ItemStack currentlyEquipped;
if (material.isHelmet()) {
currentlyEquipped = playerInventory.getHelmet();
playerInventory.setHelmet(itemStack);
} else if (material.isChestplate()) {
currentlyEquipped = playerInventory.getChestplate();
playerInventory.setChestplate(itemStack);
} else if (material.isLeggings()) {
currentlyEquipped = playerInventory.getLeggings();
playerInventory.setLeggings(itemStack);
} else {
currentlyEquipped = playerInventory.getBoots();
playerInventory.setBoots(itemStack);
}
final EquipmentSlot equipmentSlot = material.registry().equipmentSlot();
if (equipmentSlot != null) {
final ItemStack currentlyEquipped = playerInventory.getEquipment(equipmentSlot);
playerInventory.setEquipment(equipmentSlot, itemStack);
playerInventory.setItemInHand(hand, currentlyEquipped);
}

View File

@ -132,7 +132,7 @@ public class TagsPacket implements ServerPacket {
writer.writeVarInt(values.size());
// entries
for (NamespaceID name : values) {
writer.writeVarInt(Registries.getMaterial(name).ordinal());
writer.writeVarInt(Registries.getMaterial(name).id());
}
}
break;

View File

@ -4,6 +4,8 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.minestom.server.entity.EquipmentSlot;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.Material;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.ApiStatus;
@ -17,8 +19,12 @@ import java.util.function.Supplier;
public class Registry {
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
public static BlockEntry block(@NotNull JsonObject jsonObject, JsonObject override) {
return new BlockEntry(jsonObject, override);
public static BlockEntry block(String namespace, @NotNull JsonObject jsonObject, JsonObject override) {
return new BlockEntry(namespace, jsonObject, override);
}
public static MaterialEntry material(String namespace, @NotNull JsonObject jsonObject, JsonObject override) {
return new MaterialEntry(namespace, jsonObject, override);
}
public static JsonObject load(Resource resource) {
@ -28,7 +34,8 @@ public class Registry {
}
public enum Resource {
BLOCK("blocks");
BLOCK("blocks"),
ITEM("items");
private final String name;
@ -52,9 +59,9 @@ public class Registry {
private final String blockEntity;
private final Supplier<Material> materialSupplier;
private BlockEntry(JsonObject main, JsonObject override) {
private BlockEntry(String namespace, JsonObject main, JsonObject override) {
super(main, override);
this.namespace = NamespaceID.from(getString("namespaceId"));
this.namespace = NamespaceID.from(namespace);
this.id = getInt("id");
this.stateId = getInt("stateId");
this.hardness = getDouble("hardness");
@ -129,6 +136,81 @@ public class Registry {
}
}
public static class MaterialEntry extends Entry {
private final NamespaceID namespace;
private final int id;
private final int maxStackSize;
private final boolean isFood;
private final Supplier<Block> blockSupplier;
private final EquipmentSlot equipmentSlot;
private MaterialEntry(String namespace, JsonObject main, JsonObject override) {
super(main, override);
this.namespace = NamespaceID.from(namespace);
this.id = getInt("id");
this.maxStackSize = getInt("maxStackSize", 64);
this.isFood = getBoolean("edible", false);
{
final String blockNamespace = getString("correspondingBlock", null);
this.blockSupplier = blockNamespace != null ? () -> Block.fromNamespaceId(blockNamespace) : () -> null;
}
{
final var armorProperties = element("armorProperties");
if (armorProperties != null) {
final String slot = armorProperties.getAsJsonObject().get("slot").getAsString();
switch (slot) {
case "feet":
this.equipmentSlot = EquipmentSlot.BOOTS;
break;
case "legs":
this.equipmentSlot = EquipmentSlot.LEGGINGS;
break;
case "chest":
this.equipmentSlot = EquipmentSlot.CHESTPLATE;
break;
case "head":
this.equipmentSlot = EquipmentSlot.HELMET;
break;
default:
this.equipmentSlot = null;
break;
}
}else{
this.equipmentSlot = null;
}
}
}
public @NotNull NamespaceID namespace() {
return namespace;
}
public int id() {
return id;
}
public int maxStackSize() {
return maxStackSize;
}
public boolean isFood() {
return isFood;
}
public @Nullable Block block() {
return blockSupplier.get();
}
public boolean isArmor() {
return equipmentSlot != null;
}
public @Nullable EquipmentSlot equipmentSlot() {
return equipmentSlot;
}
}
public static class Entry {
private final JsonObject main, override;
@ -174,7 +256,7 @@ public class Registry {
}
protected JsonElement element(String name) {
if (override.has(name)) {
if (override != null && override.has(name)) {
return override.get(name);
}
return main.get(name);

View File

@ -93,7 +93,7 @@ public final class NBTUtils {
nbt.set("tag", tag);
nbt.setByte("Slot", (byte) i);
nbt.setByte("Count", (byte) stack.getAmount());
nbt.setString("id", stack.getMaterial().getName());
nbt.setString("id", stack.getMaterial().name());
list.add(nbt);
}

View File

@ -269,7 +269,7 @@ public class BinaryWriter extends OutputStream {
writeBoolean(false);
} else {
writeBoolean(true);
writeVarInt(itemStack.getMaterial().getId());
writeVarInt(itemStack.getMaterial().id());
writeByte((byte) itemStack.getAmount());
write(itemStack.getMeta());
}

View File

@ -50,7 +50,7 @@ public class CampfireHandler implements BlockHandler {
NBTCompound compound = new NBTCompound()
.setByte("Count", (byte) item.getAmount())
.setByte("Slot", (byte) 1)
.setString("id", item.getMaterial().getNamespaceID().asString());
.setString("id", item.getMaterial().name());
items.add(compound);
}
writer.setTag(internal, items);