chore: more components

This commit is contained in:
mworzala 2024-04-12 11:00:16 -04:00
parent 54bef46d36
commit 79f78a4ecf
No known key found for this signature in database
GPG Key ID: B148F922E64797C7
40 changed files with 313 additions and 256 deletions

View File

@ -32,6 +32,15 @@ import java.util.List;
public class Main {
public static void main(String[] args) {
try {
Class.forName("net.minestom.server.item.ItemComponent");
Class.forName("net.minestom.server.item.ItemStack");
} catch (Exception e) {
e.printStackTrace();
System.err.println("Failed to load Minestom classes, make sure you are using the correct dependencies");
return;
}
System.setProperty("minestom.experiment.pose-updates", "true");
MinecraftServer.setCompressionThreshold(0);

View File

@ -28,9 +28,9 @@ import net.minestom.server.instance.LightingChunk;
import net.minestom.server.instance.block.Block;
import net.minestom.server.inventory.ContainerInventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.item.ItemComponent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.item.metadata.BundleMeta;
import net.minestom.server.monitoring.BenchmarkManager;
import net.minestom.server.monitoring.TickMonitor;
import net.minestom.server.utils.MathUtils;
@ -38,8 +38,8 @@ import net.minestom.server.utils.time.TimeUnit;
import net.minestom.server.world.DimensionType;
import java.time.Duration;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicReference;
@ -100,17 +100,17 @@ public class PlayerInit {
player.setPermissionLevel(4);
ItemStack itemStack = ItemStack.builder(Material.STONE)
.amount(64)
.meta(itemMetaBuilder ->
itemMetaBuilder.canPlaceOn(Set.of(Block.STONE))
.canDestroy(Set.of(Block.DIAMOND_ORE)))
// .meta(itemMetaBuilder ->
// itemMetaBuilder.canPlaceOn(Set.of(Block.STONE))
// .canDestroy(Set.of(Block.DIAMOND_ORE)))
.build();
player.getInventory().addItemStack(itemStack);
ItemStack bundle = ItemStack.builder(Material.BUNDLE)
.meta(BundleMeta.class, bundleMetaBuilder -> {
bundleMetaBuilder.addItem(ItemStack.of(Material.DIAMOND, 5));
bundleMetaBuilder.addItem(ItemStack.of(Material.RABBIT_FOOT, 5));
})
.set(ItemComponent.BUNDLE_CONTENTS, List.of(
ItemStack.of(Material.DIAMOND, 5),
ItemStack.of(Material.RABBIT_FOOT, 5)
))
.build();
player.getInventory().addItemStack(bundle);

View File

@ -71,7 +71,8 @@ public class ArgumentItemStack extends Argument<ItemStack> {
throw new ArgumentSyntaxException("Item NBT is invalid", input, INVALID_NBT);
}
return ItemStack.fromNBT(material, compound);
// return ItemStack.fromNBT(material, compound); //todo
return ItemStack.of(material);
}
}

View File

@ -1,6 +1,5 @@
package net.minestom.server.entity;
import net.minestom.server.item.attribute.AttributeSlot;
import net.minestom.server.utils.inventory.PlayerInventoryUtils;
import org.jetbrains.annotations.NotNull;
@ -40,14 +39,4 @@ public enum EquipmentSlot {
return ARMORS;
}
public static @NotNull EquipmentSlot fromAttributeSlot(@NotNull AttributeSlot attributeSlot) {
return switch (attributeSlot) {
case MAINHAND -> MAIN_HAND;
case OFFHAND -> OFF_HAND;
case FEET -> BOOTS;
case LEGS -> LEGGINGS;
case CHEST -> CHESTPLATE;
case HEAD -> HELMET;
};
}
}

View File

@ -5,7 +5,7 @@ import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.entity.EntityItemMergeEvent;
import net.minestom.server.instance.EntityTracker;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.StackingRule;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.time.Cooldown;
import net.minestom.server.utils.time.TimeUnit;
import org.jetbrains.annotations.NotNull;
@ -77,13 +77,12 @@ public class ItemEntity extends Entity {
if (getDistanceSquared(itemEntity) > mergeRange * mergeRange) return;
final ItemStack itemStackEntity = itemEntity.getItemStack();
final StackingRule stackingRule = StackingRule.get();
final boolean canStack = stackingRule.canBeStacked(itemStack, itemStackEntity);
final boolean canStack = itemStack.isSimilar(itemStackEntity);
if (!canStack) return;
final int totalAmount = stackingRule.getAmount(itemStack) + stackingRule.getAmount(itemStackEntity);
if (!stackingRule.canApply(itemStack, totalAmount)) return;
final ItemStack result = stackingRule.apply(itemStack, totalAmount);
final int totalAmount = itemStack.amount() + itemStackEntity.amount();
if (!MathUtils.isBetween(totalAmount, 0, itemStack.maxStackSize())) return;
final ItemStack result = itemStack.withAmount(totalAmount);
EntityItemMergeEvent entityItemMergeEvent = new EntityItemMergeEvent(this, itemEntity, result);
EventDispatcher.callCancellable(entityItemMergeEvent, () -> {
setItemStack(entityItemMergeEvent.getResult());

View File

@ -53,7 +53,7 @@ public final class Metadata {
}
public static Entry<ItemStack> ItemStack(@NotNull ItemStack value) {
return new MetadataImpl.EntryImpl<>(TYPE_ITEM_STACK, value, NetworkBuffer.ITEM);
return new MetadataImpl.EntryImpl<>(TYPE_ITEM_STACK, value, ItemStack.NETWORK_TYPE);
}
public static Entry<Boolean> Boolean(boolean value) {

View File

@ -46,11 +46,11 @@ import net.minestom.server.event.player.*;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.EntityTracker;
import net.minestom.server.instance.Instance;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.instance.block.Block;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.PlayerInventory;
import net.minestom.server.item.ItemComponent;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.item.ItemComponent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.item.component.WrittenBookContent;
@ -447,7 +447,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
refreshActiveHand(false, isOffHand, false);
final ItemStack foodItem = itemUpdateStateEvent.getItemStack();
final boolean isFood = foodItem.material().isFood();
final boolean isFood = foodItem.has(ItemComponent.FOOD);
if (isFood) {
PlayerEatEvent playerEatEvent = new PlayerEatEvent(this, foodItem, eatingHand);
@ -2196,7 +2196,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
return null;
final ItemStack updatedItem = getItemInHand(hand);
final boolean isFood = updatedItem.material().isFood();
final boolean isFood = updatedItem.has(ItemComponent.FOOD);
if (isFood && !allowFood)
return null;

View File

@ -115,7 +115,7 @@ public final class AttributeInstance {
final Collection<AttributeModifier> modifiers = getModifiers();
double base = getBaseValue();
for (var modifier : modifiers.stream().filter(mod -> mod.getOperation() == AttributeOperation.ADDITION).toArray(AttributeModifier[]::new)) {
for (var modifier : modifiers.stream().filter(mod -> mod.getOperation() == AttributeOperation.ADD_VALUE).toArray(AttributeModifier[]::new)) {
base += modifier.getAmount();
}

View File

@ -3,11 +3,11 @@ package net.minestom.server.entity.attribute;
import org.jetbrains.annotations.Nullable;
public enum AttributeOperation {
ADDITION(0),
ADD_VALUE(0),
MULTIPLY_BASE(1),
MULTIPLY_TOTAL(2);
private static final AttributeOperation[] VALUES = new AttributeOperation[]{ADDITION, MULTIPLY_BASE, MULTIPLY_TOTAL};
private static final AttributeOperation[] VALUES = new AttributeOperation[]{ADD_VALUE, MULTIPLY_BASE, MULTIPLY_TOTAL};
private final int id;
AttributeOperation(int id) {

View File

@ -158,7 +158,7 @@ public class InstanceContainer extends Instance {
this, block, pp.getBlockFace(), blockPosition,
new Vec(pp.getCursorX(), pp.getCursorY(), pp.getCursorZ()),
pp.getPlayer().getPosition(),
pp.getPlayer().getItemInHand(pp.getHand()).meta(),
pp.getPlayer().getItemInHand(pp.getHand()),
pp.getPlayer().isSneaking()
);
} else {

View File

@ -4,7 +4,7 @@ import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.item.ItemMeta;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -61,7 +61,7 @@ public abstract class BlockPlacementRule {
@NotNull Point placePosition,
@Nullable Point cursorPosition,
@Nullable Pos playerPosition,
@Nullable ItemMeta usedItemMeta,
@Nullable ItemStack usedItemStack,
boolean isPlayerShifting
) {
}

View File

@ -10,7 +10,6 @@ import net.minestom.server.inventory.click.Click.Change.Container;
import net.minestom.server.inventory.click.Click.Change.Player;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.item.StackingRule;
import net.minestom.server.utils.inventory.PlayerInventoryUtils;
import org.jetbrains.annotations.NotNull;
@ -29,7 +28,6 @@ import static net.minestom.server.utils.inventory.PlayerInventoryUtils.*;
* Provides standard implementations of most click functions.
*/
public final class ClickProcessors {
private static final @NotNull StackingRule RULE = StackingRule.get();
public static @NotNull List<Click.Change> leftClick(int slot, @NotNull Click.Getter getter) {
final ItemStack cursor = getter.cursor();
@ -38,7 +36,7 @@ public final class ClickProcessors {
final TransactionOperator.Entry pair = TransactionOperator.STACK_LEFT.apply(clickedItem, cursor);
if (pair != null) { // Stackable items, combine their counts
return List.of(new Container(slot, pair.left()), new Cursor(pair.right()));
} else if (!RULE.canBeStacked(cursor, clickedItem)) { // If they're unstackable, switch them
} else if (!cursor.isSimilar(clickedItem)) { // If they're unstackable, switch them
return List.of(new Container(slot, cursor), new Cursor(clickedItem));
} else {
return List.of();
@ -172,14 +170,14 @@ public final class ClickProcessors {
case Click.Info.Double(int slot) ->
doubleClick(doubleClickSlots.getList(getter, getter.get(slot), slot), getter);
case Click.Info.LeftDrag(List<Integer> slots) -> {
int cursorAmount = RULE.getAmount(getter.cursor());
int cursorAmount = getter.cursor().amount();
int amount = (int) Math.floor(cursorAmount / (double) slots.size());
yield dragClick(amount, slots, getter);
}
case Click.Info.RightDrag(List<Integer> slots) -> dragClick(1, slots, getter);
case Click.Info.MiddleDrag(List<Integer> slots) -> middleDragClick(slots, getter);
case Click.Info.DropSlot(int slot, boolean all) ->
dropFromSlot(slot, all ? RULE.getAmount(getter.get(slot)) : 1, getter);
dropFromSlot(slot, all ? getter.get(slot).amount() : 1, getter);
case Click.Info.LeftDropCursor() -> dropFromCursor(getter.cursor().amount(), getter);
case Click.Info.RightDropCursor() -> dropFromCursor(1, getter);
case Click.Info.MiddleDropCursor() -> List.of();

View File

@ -47,8 +47,8 @@ public sealed interface ItemComponent<T> extends StaticProtocolObject permits It
ItemComponent<Integer> MAP_ID = declare("map_id", NetworkBuffer.VAR_INT, BinaryTagSerializer.INT);
ItemComponent<MapDecorations> MAP_DECORATIONS = declare("map_decorations", null, MapDecorations.NBT_TYPE);
ItemComponent<MapPostProcessing> MAP_POST_PROCESSING = declare("map_post_processing", MapPostProcessing.NETWORK_TYPE, null);
ItemComponent<List<ItemStack>> CHARGED_PROJECTILES = declare("charged_projectiles", NetworkBuffer.ITEM.list(Short.MAX_VALUE), BinaryTagSerializer.ITEM.list());
ItemComponent<List<ItemStack>> BUNDLE_CONTENTS = declare("bundle_contents", NetworkBuffer.ITEM.list(Short.MAX_VALUE), BinaryTagSerializer.ITEM.list());
ItemComponent<List<ItemStack>> CHARGED_PROJECTILES = declare("charged_projectiles", ItemStack.NETWORK_TYPE.list(Short.MAX_VALUE), BinaryTagSerializer.ITEM.list());
ItemComponent<List<ItemStack>> BUNDLE_CONTENTS = declare("bundle_contents", ItemStack.NETWORK_TYPE.list(Short.MAX_VALUE), BinaryTagSerializer.ITEM.list());
ItemComponent<Void> POTION_CONTENTS = declare("potion_contents", null, null); //todo
ItemComponent<Void> SUSPICIOUS_STEW_EFFECTS = declare("suspicious_stew_effects", null, null); //todo
ItemComponent<WritableBookContent> WRITABLE_BOOK_CONTENT = declare("writable_book_content", WritableBookContent.NETWORK_TYPE, WritableBookContent.NBT_TYPE);
@ -69,7 +69,7 @@ public sealed interface ItemComponent<T> extends StaticProtocolObject permits It
ItemComponent<Void> BANNER_PATTERNS = declare("banner_patterns", null, null); //todo
ItemComponent<Void> BASE_COLOR = declare("base_color", null, null); //todo dyecolor is the same stringrepresentable as item rarity
ItemComponent<Void> POT_DECORATIONS = declare("pot_decorations", null, null); //todo
ItemComponent<List<ItemStack>> CONTAINER = declare("container", NetworkBuffer.ITEM.list(256), BinaryTagSerializer.ITEM.list());
ItemComponent<List<ItemStack>> CONTAINER = declare("container", ItemStack.NETWORK_TYPE.list(256), BinaryTagSerializer.ITEM.list());
ItemComponent<Void> BLOCK_STATE = declare("block_state", null, null); //todo
ItemComponent<Void> BEES = declare("bees", null, null); //todo
ItemComponent<String> LOCK = declare("lock", null, BinaryTagSerializer.STRING);

View File

@ -34,12 +34,24 @@ record ItemComponentImpl<T>(
return nbt.read(tag);
}
@Override
public @NotNull BinaryTag write(@NotNull T value) {
Check.notNull(nbt, "{0} cannot be serialized to NBT", this);
return nbt.write(value);
}
@Override
public @NotNull T read(@NotNull NetworkBuffer reader) {
Check.notNull(network, "{0} cannot be deserialized from network", this);
return network.read(reader);
}
@Override
public void write(@NotNull NetworkBuffer writer, @NotNull T value) {
Check.notNull(network, "{0} cannot be serialized to network", this);
network.write(writer, value);
}
@Override
public String toString() {
return name();

View File

@ -1,10 +1,15 @@
package net.minestom.server.item;
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface ItemComponentMap {
static @NotNull ItemComponentMap.Builder builder() {
return new ItemComponentMapImpl.BuilderImpl(new Int2ObjectArrayMap<>());
}
boolean has(@NotNull ItemComponent<?> component);
<T> @Nullable T get(@NotNull ItemComponent<T> component);
@ -14,4 +19,13 @@ public interface ItemComponentMap {
return value != null ? value : defaultValue;
}
interface Builder extends ItemComponentMap {
@NotNull Builder set(@NotNull ItemComponent<?> component, @Nullable Object value);
@NotNull Builder remove(@NotNull ItemComponent<?> component);
@NotNull ItemComponentMap build();
}
}

View File

@ -0,0 +1,47 @@
package net.minestom.server.item;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public record ItemComponentMapImpl(@NotNull Int2ObjectMap<Object> components) implements ItemComponentMap {
@Override
public boolean has(@NotNull ItemComponent<?> component) {
return components.get(component.id()) != null;
}
@Override
public <T> @Nullable T get(@NotNull ItemComponent<T> component) {
return (T) components.get(component.id());
}
public record BuilderImpl(@NotNull Int2ObjectMap<Object> components) implements ItemComponentMap.Builder {
@Override
public boolean has(@NotNull ItemComponent<?> component) {
return components.get(component.id()) != null;
}
@Override
public <T> @Nullable T get(@NotNull ItemComponent<T> component) {
return (T) components.get(component.id());
}
@Override
public @NotNull Builder set(@NotNull ItemComponent<?> component, @Nullable Object value) {
components.put(component.id(), value);
return this;
}
@Override
public @NotNull Builder remove(@NotNull ItemComponent<?> component) {
components.remove(component.id());
return this;
}
@Override
public @NotNull ItemComponentMap build() {
return new ItemComponentMapImpl(components);
}
}
}

View File

@ -7,7 +7,6 @@ import net.kyori.adventure.nbt.CompoundBinaryTag;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.nbt.BinaryTagSerializer;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -137,15 +136,34 @@ record ItemComponentPatch(@NotNull Int2ObjectMap<Object> patch) {
return new ItemComponentPatch(newPatch);
}
interface Builder extends ItemComponentMap {
public @NotNull Builder builder() {
return new Builder(new Int2ObjectArrayMap<>(patch));
}
@Contract(value = "_, _ -> this", pure = true)
<T> @NotNull Builder set(@NotNull ItemComponent<T> component, @NotNull T value);
record Builder(@NotNull Int2ObjectMap<Object> patch) implements ItemComponentMap {
@Contract(value = "_ -> this", pure = true)
@NotNull Builder remove(@NotNull ItemComponent<?> component);
@Override
public boolean has(@NotNull ItemComponent<?> component) {
return patch.get(component.id()) != null;
}
@Contract(value = "-> new", pure = true)
@NotNull ItemComponentPatch build();
@Override
public <T> @Nullable T get(@NotNull ItemComponent<T> component) {
return (T) patch.get(component.id());
}
public <T> ItemComponentPatch.@NotNull Builder set(@NotNull ItemComponent<T> component, @NotNull T value) {
patch.put(component.id(), value);
return this;
}
public ItemComponentPatch.@NotNull Builder remove(@NotNull ItemComponent<?> component) {
patch.put(component.id(), null);
return this;
}
public @NotNull ItemComponentPatch build() {
return new ItemComponentPatch(patch);
}
}
}

View File

@ -1,4 +0,0 @@
package net.minestom.server.item;
final class ItemComponentPatchImpl implements ItemComponentPatch {
}

View File

@ -3,11 +3,9 @@ package net.minestom.server.item;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.event.HoverEventSource;
import net.minestom.server.inventory.ContainerInventory;
import net.minestom.server.item.component.CustomData;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.item.component.ItemComponent;
import net.minestom.server.item.component.ItemComponentMap;
import net.minestom.server.inventory.ContainerInventory;
import net.minestom.server.tag.Tag;
import net.minestom.server.tag.TagReadable;
import net.minestom.server.tag.TagWritable;
@ -57,15 +55,7 @@ public sealed interface ItemStack extends TagReadable, ItemComponentMap, HoverEv
* @param nbtCompound The nbt representation of the item
*/
static @NotNull ItemStack fromItemNBT(@NotNull CompoundBinaryTag nbtCompound) {
// String id = nbtCompound.getString("id");
// Check.notNull(id, "Item NBT must contain an id field.");
// Material material = Material.fromNamespaceId(id);
// Check.notNull(material, "Unknown material: {0}", id);
//
// Byte amount = nbtCompound.getByte("Count");
// if (amount == null) amount = 1;
// final CompoundBinaryTag tag = nbtCompound.getCompound("tag");
// return tag != null ? fromNBT(material, tag, amount) : of(material, amount);
return ItemStackImpl.NBT_TYPE.read(nbtCompound);
}
@Contract(pure = true)
@ -91,6 +81,12 @@ public sealed interface ItemStack extends TagReadable, ItemComponentMap, HoverEv
@Contract(value = "_, _ -> new", pure = true)
<T> @NotNull ItemStack with(@NotNull ItemComponent<T> component, T value);
default <T> @NotNull ItemStack with(@NotNull ItemComponent<T> component, @NotNull UnaryOperator<T> operator) {
T value = get(component);
if (value == null) return this;
return with(component, operator.apply(value));
}
@Contract(value = "_, -> new", pure = true)
@NotNull ItemStack without(@NotNull ItemComponent<?> component);
@ -102,7 +98,12 @@ public sealed interface ItemStack extends TagReadable, ItemComponentMap, HoverEv
@Override
@Contract(pure = true)
default <T> @UnknownNullability T getTag(@NotNull Tag<T> tag) {
return getOrDefault(ItemComponent.CUSTOM_DATA, CustomData.EMPTY).getTag(tag);
return get(ItemComponent.CUSTOM_DATA, CustomData.EMPTY).getTag(tag);
}
@Contract(pure = true)
default int maxStackSize() {
return get(ItemComponent.MAX_STACK_SIZE, 64);
}
@Contract(value = "_, -> new", pure = true)
@ -133,6 +134,7 @@ public sealed interface ItemStack extends TagReadable, ItemComponentMap, HoverEv
// //todo(matt): revisit,
// throw new RuntimeException(e);
// }
throw new UnsupportedOperationException("todo");
}
sealed interface Builder extends TagWritable

View File

@ -1,5 +1,6 @@
package net.minestom.server.item;
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import net.minestom.server.item.component.CustomData;
import net.minestom.server.network.NetworkBuffer;
@ -14,7 +15,22 @@ import java.util.function.Consumer;
record ItemStackImpl(Material material, int amount, ItemComponentPatch components) implements ItemStack {
static final NetworkBuffer.Type<ItemStack> NETWORK_TYPE = null;
static final NetworkBuffer.Type<ItemStack> NETWORK_TYPE = new NetworkBuffer.Type<>() {
@Override
public void write(@NotNull NetworkBuffer buffer, ItemStack value) {
buffer.write(NetworkBuffer.VAR_INT, value.material().id());
buffer.write(NetworkBuffer.VAR_INT, value.amount());
buffer.write(ItemComponentPatch.NETWORK_TYPE, ((ItemStackImpl) value).components);
}
@Override
public ItemStack read(@NotNull NetworkBuffer buffer) {
Material material = Material.fromId(buffer.read(NetworkBuffer.VAR_INT));
int amount = buffer.read(NetworkBuffer.VAR_INT);
ItemComponentPatch components = buffer.read(ItemComponentPatch.NETWORK_TYPE);
return new ItemStackImpl(material, amount, components);
}
};
static final BinaryTagSerializer<ItemStack> NBT_TYPE = BinaryTagSerializer.COMPOUND.map(ItemStackImpl::fromCompound, ItemStackImpl::toCompound);
static ItemStack create(Material material, int amount, ItemComponentPatch components) {
@ -26,6 +42,10 @@ record ItemStackImpl(Material material, int amount, ItemComponentPatch component
return create(material, amount, ItemComponentPatch.EMPTY);
}
public ItemStackImpl {
Check.notNull(material, "Material cannot be null");
}
@Override
public <T> @Nullable T get(@NotNull ItemComponent<T> component) {
return components.get(material.prototype(), component);
@ -50,6 +70,7 @@ record ItemStackImpl(Material material, int amount, ItemComponentPatch component
@Override
public @NotNull ItemStack withAmount(int amount) {
if (amount <= 0) return ItemStack.AIR;
return create(material, amount, components);
}
@ -65,9 +86,7 @@ record ItemStackImpl(Material material, int amount, ItemComponentPatch component
@Override
public @NotNull ItemStack consume(int amount) {
int newAmount = amount() - amount;
if (newAmount <= 0) return AIR;
return withAmount(newAmount);
return withAmount(amount() - amount);
}
@Override
@ -78,14 +97,6 @@ record ItemStackImpl(Material material, int amount, ItemComponentPatch component
@Override
public @NotNull CompoundBinaryTag toItemNBT() {
return (CompoundBinaryTag) NBT_TYPE.write(this);
// CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder()
// .putString("id", material.name())
// .putByte("Count", (byte) amount);
// CompoundBinaryTag nbt = meta.toNBT();
// if (nbt.size() > 0) builder.put("tag", nbt);
// return builder.build();
//todo
}
@Contract(value = "-> new", pure = true)
@ -124,7 +135,7 @@ record ItemStackImpl(Material material, int amount, ItemComponentPatch component
Builder(Material material, int amount) {
this.material = material;
this.amount = amount;
this.components = ItemComponentPatch.builder(material);
this.components = new ItemComponentPatch.Builder(new Int2ObjectArrayMap<>());
}
@Override

View File

@ -76,27 +76,11 @@ public sealed interface Material extends StaticProtocolObject, Materials permits
}
default boolean isArmor() {
//todo how does armor work nowadays
return false;
// return registry().isArmor();
return registry().isArmor();
}
default boolean hasState() {
if (this == BOW || this == TRIDENT || this == CROSSBOW || this == SHIELD) {
return true;
} else {
return isFood();
}
}
@Deprecated(forRemoval = true)
default int maxStackSize() {
return prototype().getOrDefault(ItemComponent.MAX_STACK_SIZE, 64);
}
@Deprecated(forRemoval = true)
default boolean isFood() {
return prototype().has(ItemComponent.FOOD);
return prototype().get(ItemComponent.MAX_STACK_SIZE, 64);
}
static @NotNull Collection<@NotNull Material> values() {

View File

@ -27,8 +27,6 @@ import net.minestom.server.network.packet.server.play.BlockChangePacket;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.validate.Check;
import java.util.concurrent.atomic.AtomicBoolean;
public class BlockPlacementListener {
private static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager();
@ -89,7 +87,9 @@ public class BlockPlacementListener {
canPlaceBlock = false; // Spectators can't place blocks
} else if (player.getGameMode() == GameMode.ADVENTURE) {
//Check if the block can be placed on the block
canPlaceBlock = usedItem.meta().canPlaceOn(interactedBlock);
// canPlaceBlock = usedItem.meta().canPlaceOn(interactedBlock);
canPlaceBlock = false;
//todo
}

View File

@ -124,9 +124,10 @@ public final class PlayerDiggingListener {
} else if (player.getGameMode() == GameMode.ADVENTURE) {
// Check if the item can break the block with the current item
final ItemStack itemInMainHand = player.getItemInMainHand();
if (!itemInMainHand.meta().canDestroy(block)) {
return true;
}
//todo
// if (!itemInMainHand.meta().canDestroy(block)) {
// return true;
// }
}
return false;
}

View File

@ -7,6 +7,7 @@ import net.minestom.server.event.player.PlayerItemAnimationEvent;
import net.minestom.server.event.player.PlayerPreEatEvent;
import net.minestom.server.event.player.PlayerUseItemEvent;
import net.minestom.server.inventory.PlayerInventory;
import net.minestom.server.item.ItemComponent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.network.packet.client.play.ClientUseItemPacket;
@ -53,7 +54,7 @@ public class UseItemListener {
itemAnimationType = PlayerItemAnimationEvent.ItemAnimationType.SHIELD;
} else if (material == Material.TRIDENT) {
itemAnimationType = PlayerItemAnimationEvent.ItemAnimationType.TRIDENT;
} else if (material.isFood()) {
} else if (itemStack.has(ItemComponent.FOOD)) {
itemAnimationType = PlayerItemAnimationEvent.ItemAnimationType.EAT;
// Eating code, contains the eating time customisation

View File

@ -10,7 +10,6 @@ import net.minestom.server.entity.metadata.animal.FrogMeta;
import net.minestom.server.entity.metadata.animal.SnifferMeta;
import net.minestom.server.entity.metadata.animal.tameable.CatMeta;
import net.minestom.server.entity.metadata.other.PaintingMeta;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.packet.server.play.data.WorldPos;
import net.minestom.server.particle.Particle;
import net.minestom.server.utils.Direction;
@ -48,7 +47,6 @@ public final class NetworkBuffer {
public static final Type<Component> COMPONENT = new NetworkBufferTypeImpl.ComponentType();
public static final Type<Component> JSON_COMPONENT = new NetworkBufferTypeImpl.JsonComponentType();
public static final Type<UUID> UUID = new NetworkBufferTypeImpl.UUIDType();
public static final Type<ItemStack> ITEM = new NetworkBufferTypeImpl.ItemType();
public static final Type<byte[]> BYTE_ARRAY = new NetworkBufferTypeImpl.ByteArrayType();
public static final Type<long[]> LONG_ARRAY = new NetworkBufferTypeImpl.LongArrayType();

View File

@ -1,16 +1,12 @@
package net.minestom.server.network;
import net.kyori.adventure.nbt.BinaryTag;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.minestom.server.adventure.serializer.nbt.NbtComponentSerializer;
import net.minestom.server.color.Color;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.item.ItemComponent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.network.packet.server.play.data.WorldPos;
import net.minestom.server.particle.Particle;
import net.minestom.server.particle.data.ParticleData;
@ -407,38 +403,6 @@ interface NetworkBufferTypeImpl<T> extends NetworkBuffer.Type<T> {
}
}
record ItemType() implements NetworkBufferTypeImpl<ItemStack> {
@Override
public void write(@NotNull NetworkBuffer buffer, ItemStack value) {
if (value.isAir()) {
buffer.write(VAR_INT, 0); // 0 count always
return;
}
buffer.write(VAR_INT, value.amount());
buffer.write(VAR_INT, value.material().id());
buffer.write(VAR_INT, 1); // Added components
buffer.write(VAR_INT, 0); // Removed components
var component = ItemComponent.MAX_STACK_SIZE;
buffer.write(VAR_INT, component.id());
buffer.write(VAR_INT, 16);
}
@Override
public ItemStack read(@NotNull NetworkBuffer buffer) {
int count = buffer.read(VAR_INT);
if (count <= 0) return ItemStack.AIR;
final int id = buffer.read(VAR_INT);
final Material material = Material.fromId(id);
if (material == null) throw new RuntimeException("Unknown material id: " + id);
buffer.read(VAR_INT); // Added components
buffer.read(VAR_INT); // Removed components
return ItemStack.fromNBT(material, CompoundBinaryTag.empty(), count);
}
}
record ByteArrayType() implements NetworkBufferTypeImpl<byte[]> {
@Override
public void write(@NotNull NetworkBuffer buffer, byte[] value) {

View File

@ -22,7 +22,7 @@ public record ClientClickWindowPacket(byte windowId, int stateId,
public ClientClickWindowPacket(@NotNull NetworkBuffer reader) {
this(reader.read(BYTE), reader.read(VAR_INT),
reader.read(SHORT), reader.read(BYTE), reader.readEnum(ClickType.class),
reader.readCollection(ChangedSlot::new, MAX_CHANGED_SLOTS), reader.read(ITEM));
reader.readCollection(ChangedSlot::new, MAX_CHANGED_SLOTS), reader.read(ItemStack.NETWORK_TYPE));
}
@Override
@ -33,18 +33,18 @@ public record ClientClickWindowPacket(byte windowId, int stateId,
writer.write(BYTE, button);
writer.write(VAR_INT, clickType.ordinal());
writer.writeCollection(changedSlots);
writer.write(ITEM, clickedItem);
writer.write(ItemStack.NETWORK_TYPE, clickedItem);
}
public record ChangedSlot(short slot, @NotNull ItemStack item) implements NetworkBuffer.Writer {
public ChangedSlot(@NotNull NetworkBuffer reader) {
this(reader.read(SHORT), reader.read(ITEM));
this(reader.read(SHORT), reader.read(ItemStack.NETWORK_TYPE));
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(SHORT, slot);
writer.write(ITEM, item);
writer.write(ItemStack.NETWORK_TYPE, item);
}
}

View File

@ -5,17 +5,16 @@ import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.packet.client.ClientPacket;
import org.jetbrains.annotations.NotNull;
import static net.minestom.server.network.NetworkBuffer.ITEM;
import static net.minestom.server.network.NetworkBuffer.SHORT;
public record ClientCreativeInventoryActionPacket(short slot, @NotNull ItemStack item) implements ClientPacket {
public ClientCreativeInventoryActionPacket(@NotNull NetworkBuffer reader) {
this(reader.read(SHORT), reader.read(ITEM));
this(reader.read(SHORT), reader.read(ItemStack.NETWORK_TYPE));
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(SHORT, slot);
writer.write(ITEM, item);
writer.write(ItemStack.NETWORK_TYPE, item);
}
}

View File

@ -5,7 +5,6 @@ import net.minestom.server.advancements.FrameType;
import net.minestom.server.adventure.ComponentHolder;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.packet.server.ServerPacket.ComponentHolding;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import org.jetbrains.annotations.NotNull;
@ -164,7 +163,7 @@ public record AdvancementsPacket(boolean reset, @NotNull List<AdvancementMapping
private static DisplayData read(@NotNull NetworkBuffer reader) {
var title = reader.read(COMPONENT);
var description = reader.read(COMPONENT);
var icon = reader.read(ITEM);
var icon = reader.read(ItemStack.NETWORK_TYPE);
var frameType = FrameType.values()[reader.read(VAR_INT)];
var flags = reader.read(INT);
var backgroundTexture = (flags & 0x1) != 0 ? reader.read(STRING) : null;
@ -180,7 +179,7 @@ public record AdvancementsPacket(boolean reset, @NotNull List<AdvancementMapping
public void write(@NotNull NetworkBuffer writer) {
writer.write(COMPONENT, title);
writer.write(COMPONENT, description);
writer.write(ITEM, icon);
writer.write(ItemStack.NETWORK_TYPE, icon);
writer.writeEnum(FrameType.class, frameType);
writer.write(INT, flags);
if ((flags & 0x1) != 0) {

View File

@ -70,7 +70,7 @@ public record DeclareRecipesPacket(@NotNull List<DeclaredRecipe> recipes) implem
private DeclaredShapelessCraftingRecipe(@NotNull NetworkBuffer reader) {
this(reader.read(STRING), reader.read(STRING),
reader.readEnum(RecipeCategory.Crafting.class),
reader.readCollection(Ingredient::new, MAX_INGREDIENTS), reader.read(ITEM));
reader.readCollection(Ingredient::new, MAX_INGREDIENTS), reader.read(ItemStack.NETWORK_TYPE));
}
@Override
@ -78,7 +78,7 @@ public record DeclareRecipesPacket(@NotNull List<DeclaredRecipe> recipes) implem
writer.write(STRING, group);
writer.writeEnum(RecipeCategory.Crafting.class, crafting);
writer.writeCollection(ingredients);
writer.write(ITEM, result);
writer.write(ItemStack.NETWORK_TYPE, result);
}
@Override
@ -114,7 +114,7 @@ public record DeclareRecipesPacket(@NotNull List<DeclaredRecipe> recipes) implem
for (int slot = 0; slot < width * height; slot++) {
ingredients.add(new Ingredient(reader));
}
ItemStack result = reader.read(ITEM);
ItemStack result = reader.read(ItemStack.NETWORK_TYPE);
boolean showNotification = reader.read(BOOLEAN);
return new DeclaredShapedCraftingRecipe(recipeId, group, category, width, height, ingredients, result, showNotification);
}
@ -128,7 +128,7 @@ public record DeclareRecipesPacket(@NotNull List<DeclaredRecipe> recipes) implem
for (Ingredient ingredient : ingredients) {
ingredient.write(writer);
}
writer.write(ITEM, result);
writer.write(ItemStack.NETWORK_TYPE, result);
writer.write(BOOLEAN, showNotification);
}
@ -145,7 +145,7 @@ public record DeclareRecipesPacket(@NotNull List<DeclaredRecipe> recipes) implem
public DeclaredSmeltingRecipe(@NotNull NetworkBuffer reader) {
this(reader.read(STRING), reader.read(STRING),
reader.readEnum(RecipeCategory.Cooking.class),
new Ingredient(reader), reader.read(ITEM),
new Ingredient(reader), reader.read(ItemStack.NETWORK_TYPE),
reader.read(FLOAT), reader.read(VAR_INT));
}
@ -154,7 +154,7 @@ public record DeclareRecipesPacket(@NotNull List<DeclaredRecipe> recipes) implem
writer.write(STRING, group);
writer.writeEnum(RecipeCategory.Cooking.class, category);
writer.write(ingredient);
writer.write(ITEM, result);
writer.write(ItemStack.NETWORK_TYPE, result);
writer.write(FLOAT, experience);
writer.write(VAR_INT, cookingTime);
}
@ -172,7 +172,7 @@ public record DeclareRecipesPacket(@NotNull List<DeclaredRecipe> recipes) implem
public DeclaredBlastingRecipe(@NotNull NetworkBuffer reader) {
this(reader.read(STRING), reader.read(STRING),
reader.readEnum(RecipeCategory.Cooking.class),
new Ingredient(reader), reader.read(ITEM),
new Ingredient(reader), reader.read(ItemStack.NETWORK_TYPE),
reader.read(FLOAT), reader.read(VAR_INT));
}
@ -181,7 +181,7 @@ public record DeclareRecipesPacket(@NotNull List<DeclaredRecipe> recipes) implem
writer.write(STRING, group);
writer.writeEnum(RecipeCategory.Cooking.class, category);
writer.write(ingredient);
writer.write(ITEM, result);
writer.write(ItemStack.NETWORK_TYPE, result);
writer.write(FLOAT, experience);
writer.write(VAR_INT, cookingTime);
}
@ -199,7 +199,7 @@ public record DeclareRecipesPacket(@NotNull List<DeclaredRecipe> recipes) implem
public DeclaredSmokingRecipe(@NotNull NetworkBuffer reader) {
this(reader.read(STRING), reader.read(STRING),
reader.readEnum(RecipeCategory.Cooking.class),
new Ingredient(reader), reader.read(ITEM),
new Ingredient(reader), reader.read(ItemStack.NETWORK_TYPE),
reader.read(FLOAT), reader.read(VAR_INT));
}
@ -208,7 +208,7 @@ public record DeclareRecipesPacket(@NotNull List<DeclaredRecipe> recipes) implem
writer.write(STRING, group);
writer.writeEnum(RecipeCategory.Cooking.class, category);
writer.write(ingredient);
writer.write(ITEM, result);
writer.write(ItemStack.NETWORK_TYPE, result);
writer.write(FLOAT, experience);
writer.write(VAR_INT, cookingTime);
}
@ -226,7 +226,7 @@ public record DeclareRecipesPacket(@NotNull List<DeclaredRecipe> recipes) implem
public DeclaredCampfireCookingRecipe(@NotNull NetworkBuffer reader) {
this(reader.read(STRING), reader.read(STRING),
reader.readEnum(RecipeCategory.Cooking.class),
new Ingredient(reader), reader.read(ITEM),
new Ingredient(reader), reader.read(ItemStack.NETWORK_TYPE),
reader.read(FLOAT), reader.read(VAR_INT));
}
@ -235,7 +235,7 @@ public record DeclareRecipesPacket(@NotNull List<DeclaredRecipe> recipes) implem
writer.write(STRING, group);
writer.writeEnum(RecipeCategory.Cooking.class, category);
writer.write(ingredient);
writer.write(ITEM, result);
writer.write(ItemStack.NETWORK_TYPE, result);
writer.write(FLOAT, experience);
writer.write(VAR_INT, cookingTime);
}
@ -250,14 +250,14 @@ public record DeclareRecipesPacket(@NotNull List<DeclaredRecipe> recipes) implem
Ingredient ingredient, ItemStack result) implements DeclaredRecipe {
public DeclaredStonecutterRecipe(@NotNull NetworkBuffer reader) {
this(reader.read(STRING), reader.read(STRING),
new Ingredient(reader), reader.read(ITEM));
new Ingredient(reader), reader.read(ItemStack.NETWORK_TYPE));
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(STRING, group);
writer.write(ingredient);
writer.write(ITEM, result);
writer.write(ItemStack.NETWORK_TYPE, result);
}
@Override
@ -270,7 +270,7 @@ public record DeclareRecipesPacket(@NotNull List<DeclaredRecipe> recipes) implem
Ingredient base, Ingredient addition,
ItemStack result) implements DeclaredRecipe {
public DeclaredSmithingTransformRecipe(@NotNull NetworkBuffer reader) {
this(reader.read(STRING), new Ingredient(reader), new Ingredient(reader), new Ingredient(reader), reader.read(ITEM));
this(reader.read(STRING), new Ingredient(reader), new Ingredient(reader), new Ingredient(reader), reader.read(ItemStack.NETWORK_TYPE));
}
@Override
@ -278,7 +278,7 @@ public record DeclareRecipesPacket(@NotNull List<DeclaredRecipe> recipes) implem
writer.write(template);
writer.write(base);
writer.write(addition);
writer.write(ITEM, result);
writer.write(ItemStack.NETWORK_TYPE, result);
}
@Override
@ -312,11 +312,11 @@ public record DeclareRecipesPacket(@NotNull List<DeclaredRecipe> recipes) implem
}
public Ingredient(@NotNull NetworkBuffer reader) {
this(reader.readCollection(ITEM, MAX_INGREDIENTS));
this(reader.readCollection(ItemStack.NETWORK_TYPE, MAX_INGREDIENTS));
}
public void write(@NotNull NetworkBuffer writer) {
writer.writeCollection(ITEM, items);
writer.writeCollection(ItemStack.NETWORK_TYPE, items);
}
}
}

View File

@ -2,9 +2,9 @@ package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component;
import net.minestom.server.entity.EquipmentSlot;
import net.minestom.server.item.ItemComponent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.packet.server.ServerPacket.ComponentHolding;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import org.jetbrains.annotations.NotNull;
@ -16,7 +16,8 @@ import java.util.Objects;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import static net.minestom.server.network.NetworkBuffer.*;
import static net.minestom.server.network.NetworkBuffer.BYTE;
import static net.minestom.server.network.NetworkBuffer.VAR_INT;
public record EntityEquipmentPacket(int entityId,
@NotNull Map<EquipmentSlot, ItemStack> equipments) implements ServerPacket.Play, ServerPacket.ComponentHolding {
@ -39,7 +40,7 @@ public record EntityEquipmentPacket(int entityId,
byte slotEnum = (byte) entry.getKey().ordinal();
if (!last) slotEnum |= 0x80;
writer.write(BYTE, slotEnum);
writer.write(ITEM, entry.getValue());
writer.write(ItemStack.NETWORK_TYPE, entry.getValue());
}
}
@ -52,7 +53,7 @@ public record EntityEquipmentPacket(int entityId,
public @NotNull Collection<Component> components() {
return this.equipments.values()
.stream()
.map(ItemStack::getDisplayName)
.map(item -> item.get(ItemComponent.CUSTOM_NAME))
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
@ -60,7 +61,7 @@ public record EntityEquipmentPacket(int entityId,
@Override
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
final var map = new EnumMap<EquipmentSlot, ItemStack>(EquipmentSlot.class);
this.equipments.forEach((key, value) -> map.put(key, value.withDisplayName(operator)));
this.equipments.forEach((key, value) -> map.put(key, value.with(ItemComponent.CUSTOM_NAME, operator)));
return new EntityEquipmentPacket(this.entityId, map);
}
@ -70,7 +71,7 @@ public record EntityEquipmentPacket(int entityId,
byte slot;
do {
slot = reader.read(BYTE);
equipments.put(EquipmentSlot.values()[slot & 0x7F], reader.read(ITEM));
equipments.put(EquipmentSlot.values()[slot & 0x7F], reader.read(ItemStack.NETWORK_TYPE));
} while ((slot & 0x80) == 0x80);
return equipments;
}

View File

@ -1,5 +1,6 @@
package net.minestom.server.network.packet.server.play;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
@ -53,7 +54,7 @@ public record ExplosionPacket(double x, double y, double z, float radius,
return writer.toByteArray();
}
else if (particle.equals(Particle.ITEM)) {
writer.writeItemStack(reader.read(ITEM));
writer.writeItemStack(reader.read(ItemStack.NETWORK_TYPE));
}
else if (particle.equals(Particle.DUST_COLOR_TRANSITION)) {
for (int i = 0; i < 7; i++) writer.writeFloat(reader.read(FLOAT));

View File

@ -1,9 +1,9 @@
package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component;
import net.minestom.server.item.ItemComponent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.packet.server.ServerPacket.ComponentHolding;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import org.jetbrains.annotations.NotNull;
@ -19,7 +19,7 @@ public record SetSlotPacket(byte windowId, int stateId, short slot,
@NotNull ItemStack itemStack) implements ServerPacket.Play, ServerPacket.ComponentHolding {
public SetSlotPacket(@NotNull NetworkBuffer reader) {
this(reader.read(BYTE), reader.read(VAR_INT), reader.read(SHORT),
reader.read(ITEM));
reader.read(ItemStack.NETWORK_TYPE));
}
@Override
@ -27,7 +27,7 @@ public record SetSlotPacket(byte windowId, int stateId, short slot,
writer.write(BYTE, windowId);
writer.write(VAR_INT, stateId);
writer.write(SHORT, slot);
writer.write(ITEM, itemStack);
writer.write(ItemStack.NETWORK_TYPE, itemStack);
}
@Override
@ -37,20 +37,21 @@ public record SetSlotPacket(byte windowId, int stateId, short slot,
@Override
public @NotNull Collection<Component> components() {
final var components = new ArrayList<>(this.itemStack.getLore());
final var displayname = this.itemStack.getDisplayName();
final var components = new ArrayList<>(this.itemStack.get(ItemComponent.LORE, List.of()));
final var displayname = this.itemStack.get(ItemComponent.CUSTOM_NAME);
if (displayname != null) components.add(displayname);
return List.copyOf(components);
}
@Override
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return new SetSlotPacket(this.windowId, this.stateId, this.slot, this.itemStack.withDisplayName(operator).withLore(lines -> {
final var translatedComponents = new ArrayList<Component>();
lines.forEach(component -> translatedComponents.add(operator.apply(component)));
return translatedComponents;
}));
return new SetSlotPacket(this.windowId, this.stateId, this.slot, this.itemStack
.with(ItemComponent.CUSTOM_NAME, operator)
.with(ItemComponent.LORE, (UnaryOperator<List<Component>>) lines -> {
final var translatedComponents = new ArrayList<Component>();
lines.forEach(component -> translatedComponents.add(operator.apply(component)));
return translatedComponents;
}));
}
/**

View File

@ -45,17 +45,17 @@ public record TradeListPacket(int windowId, @NotNull List<Trade> trades,
int tradeUsesNumber, int maxTradeUsesNumber, int exp,
int specialPrice, float priceMultiplier, int demand) implements NetworkBuffer.Writer {
public Trade(@NotNull NetworkBuffer reader) {
this(reader.read(ITEM), reader.read(ITEM),
reader.readOptional(ITEM), reader.read(BOOLEAN),
this(reader.read(ItemStack.NETWORK_TYPE), reader.read(ItemStack.NETWORK_TYPE),
reader.readOptional(ItemStack.NETWORK_TYPE), reader.read(BOOLEAN),
reader.read(INT), reader.read(INT), reader.read(INT),
reader.read(INT), reader.read(FLOAT), reader.read(INT));
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(ITEM, inputItem1);
writer.write(ITEM, result);
writer.writeOptional(ITEM, inputItem2);
writer.write(ItemStack.NETWORK_TYPE, inputItem1);
writer.write(ItemStack.NETWORK_TYPE, result);
writer.writeOptional(ItemStack.NETWORK_TYPE, inputItem2);
writer.write(BOOLEAN, tradeDisabled);
writer.write(INT, tradeUsesNumber);
writer.write(INT, maxTradeUsesNumber);

View File

@ -1,9 +1,9 @@
package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component;
import net.minestom.server.item.ItemComponent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.packet.server.ServerPacket.ComponentHolding;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import org.jetbrains.annotations.NotNull;
@ -13,7 +13,8 @@ import java.util.Collection;
import java.util.List;
import java.util.function.UnaryOperator;
import static net.minestom.server.network.NetworkBuffer.*;
import static net.minestom.server.network.NetworkBuffer.BYTE;
import static net.minestom.server.network.NetworkBuffer.VAR_INT;
public record WindowItemsPacket(byte windowId, int stateId, @NotNull List<ItemStack> items,
@NotNull ItemStack carriedItem) implements ServerPacket.Play, ServerPacket.ComponentHolding {
@ -24,16 +25,16 @@ public record WindowItemsPacket(byte windowId, int stateId, @NotNull List<ItemSt
}
public WindowItemsPacket(@NotNull NetworkBuffer reader) {
this(reader.read(BYTE), reader.read(VAR_INT), reader.readCollection(ITEM, MAX_ENTRIES),
reader.read(ITEM));
this(reader.read(BYTE), reader.read(VAR_INT), reader.readCollection(ItemStack.NETWORK_TYPE, MAX_ENTRIES),
reader.read(ItemStack.NETWORK_TYPE));
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(BYTE, windowId);
writer.write(VAR_INT, stateId);
writer.writeCollection(ITEM, items);
writer.write(ITEM, carriedItem);
writer.writeCollection(ItemStack.NETWORK_TYPE, items);
writer.write(ItemStack.NETWORK_TYPE, carriedItem);
}
@Override
@ -49,9 +50,9 @@ public record WindowItemsPacket(byte windowId, int stateId, @NotNull List<ItemSt
final var components = new ArrayList<Component>();
list.forEach(itemStack -> {
components.addAll(itemStack.getLore());
components.addAll(itemStack.get(ItemComponent.LORE, List.of()));
final var displayName = itemStack.getDisplayName();
final var displayName = itemStack.get(ItemComponent.CUSTOM_NAME);
if (displayName == null) return;
components.add(displayName);
@ -62,19 +63,21 @@ public record WindowItemsPacket(byte windowId, int stateId, @NotNull List<ItemSt
@Override
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
UnaryOperator<List<Component>> loreOperator = lines -> {
final var translatedComponents = new ArrayList<Component>();
lines.forEach(component -> translatedComponents.add(operator.apply(component)));
return translatedComponents;
};
return new WindowItemsPacket(
this.windowId,
this.stateId,
this.items.stream().map(stack -> stack.withDisplayName(operator).withLore(lines -> {
final var translatedComponents = new ArrayList<Component>();
lines.forEach(component -> translatedComponents.add(operator.apply(component)));
return translatedComponents;
})).toList(),
this.carriedItem.withDisplayName(operator).withLore(lines -> {
final var translatedComponents = new ArrayList<Component>();
lines.forEach(component -> translatedComponents.add(operator.apply(component)));
return translatedComponents;
})
this.items.stream().map(stack -> stack
.with(ItemComponent.CUSTOM_NAME, operator)
.with(ItemComponent.LORE, loreOperator))
.toList(),
this.carriedItem
.with(ItemComponent.CUSTOM_NAME, operator)
.with(ItemComponent.LORE, loreOperator)
);
}
}

View File

@ -8,7 +8,7 @@ import org.jetbrains.annotations.NotNull;
public record ItemParticleData(ItemStack item) implements ParticleData {
ItemParticleData(NetworkBuffer reader) {
this(reader.read(NetworkBuffer.ITEM));
this(reader.read(ItemStack.NETWORK_TYPE));
}
ItemParticleData() {
@ -17,7 +17,7 @@ public record ItemParticleData(ItemStack item) implements ParticleData {
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(NetworkBuffer.ITEM, item);
writer.write(ItemStack.NETWORK_TYPE, item);
}
@Override

View File

@ -9,6 +9,7 @@ import net.minestom.server.collision.BoundingBox;
import net.minestom.server.collision.CollisionUtils;
import net.minestom.server.collision.Shape;
import net.minestom.server.entity.EntitySpawnType;
import net.minestom.server.entity.EquipmentSlot;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.ItemComponent;
import net.minestom.server.item.ItemComponentMap;
@ -477,8 +478,8 @@ public final class Registry {
private final Supplier<Block> blockSupplier;
private final ItemComponentMap prototype;
// private final EquipmentSlot equipmentSlot; //todo
// private final EntityType entityType; //todo
private final EquipmentSlot equipmentSlot;
// private final EntityType entityType; //todo
private final Properties custom;
private MaterialEntry(String namespace, Properties main, Properties custom) {
@ -493,32 +494,38 @@ public final class Registry {
try {
ItemComponentMap.Builder builder = ItemComponentMap.builder();
for (Map.Entry<String, Object> entry : main.section("components")) {
//noinspection unchecked
ItemComponent<Object> component = (ItemComponent<Object>) ItemComponent.fromNamespaceId(entry.getKey());
Check.notNull(component, "Unknown component: " + entry.getKey());
try {
//noinspection unchecked
ItemComponent<Object> component = (ItemComponent<Object>) ItemComponent.fromNamespaceId(entry.getKey());
Check.notNull(component, "Unknown component: " + entry.getKey());
byte[] rawValue = Base64.getDecoder().decode((String) entry.getValue());
BinaryTagReader reader = new BinaryTagReader(new DataInputStream(new ByteArrayInputStream(rawValue)));
builder.set(component, component.read(reader.readNameless()));
byte[] rawValue = Base64.getDecoder().decode((String) entry.getValue());
BinaryTagReader reader = new BinaryTagReader(new DataInputStream(new ByteArrayInputStream(rawValue)));
//todo remove this try/catch, just so i dont need to impl all comps yet
builder.set(component, component.read(reader.readNameless()));
} catch (NullPointerException e) {
System.out.println(e.getMessage());
}
}
this.prototype = builder.build();
} catch (IOException e) {
throw new RuntimeException("failed to parse material registry: " + namespace, e);
}
// {
// final Properties armorProperties = main.section("armorProperties");
// if (armorProperties != null) {
// switch (armorProperties.getString("slot")) {
// case "feet" -> this.equipmentSlot = EquipmentSlot.BOOTS;
// case "legs" -> this.equipmentSlot = EquipmentSlot.LEGGINGS;
// case "chest" -> this.equipmentSlot = EquipmentSlot.CHESTPLATE;
// case "head" -> this.equipmentSlot = EquipmentSlot.HELMET;
// default -> this.equipmentSlot = null;
// }
// } else {
// this.equipmentSlot = null;
// }
// }
{
final Properties armorProperties = main.section("armorProperties");
if (armorProperties != null) {
switch (armorProperties.getString("slot")) {
case "feet" -> this.equipmentSlot = EquipmentSlot.BOOTS;
case "legs" -> this.equipmentSlot = EquipmentSlot.LEGGINGS;
case "chest" -> this.equipmentSlot = EquipmentSlot.CHESTPLATE;
case "head" -> this.equipmentSlot = EquipmentSlot.HELMET;
default -> this.equipmentSlot = null;
}
} else {
this.equipmentSlot = null;
}
}
// {
// final Properties spawnEggProperties = main.section("spawnEggProperties");
// if (spawnEggProperties != null) {
@ -549,14 +556,14 @@ public final class Registry {
return prototype;
}
// public boolean isArmor() {
// return equipmentSlot != null;
// }
//
// public @Nullable EquipmentSlot equipmentSlot() {
// return equipmentSlot;
// }
//
public boolean isArmor() {
return equipmentSlot != null;
}
public @Nullable EquipmentSlot equipmentSlot() {
return equipmentSlot;
}
// /**
// * Gets the entity type this item can spawn. Only present for spawn eggs (e.g. wolf spawn egg, skeleton spawn egg)
// * @return The entity type it can spawn, or null if it is not a spawn egg
@ -612,11 +619,12 @@ public final class Registry {
custom);
}
}
public record TrimMaterialEntry(@NotNull NamespaceID namespace,
@NotNull String assetName,
@NotNull Material ingredient,
float itemModelIndex,
@NotNull Map<String,String> overrideArmorMaterials,
@NotNull Map<String, String> overrideArmorMaterials,
@NotNull Component description,
Properties custom) implements Entry {
public TrimMaterialEntry(@NotNull String namespace, @NotNull Properties main, Properties custom) {
@ -625,7 +633,7 @@ public final class Registry {
main.getString("asset_name"),
Objects.requireNonNull(Material.fromNamespaceId(main.getString("ingredient"))),
(float) main.getDouble("item_model_index"),
Objects.requireNonNullElse(main.section("override_armor_materials"),new PropertiesMap(Map.of()))
Objects.requireNonNullElse(main.section("override_armor_materials"), new PropertiesMap(Map.of()))
.asMap().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> (String) entry.getValue())),
JSONComponentSerializer.json().deserialize(main.section("description").toString()),
custom
@ -803,7 +811,7 @@ public final class Registry {
public String toString() {
AtomicReference<String> string = new AtomicReference<>("{ ");
this.map.forEach((s, object) -> string.set(string.get() + " , " + "\"" + s + "\"" + " : " + "\"" + object.toString() + "\""));
return string.updateAndGet(s -> s.replaceFirst(" , ","") + "}");
return string.updateAndGet(s -> s.replaceFirst(" , ", "") + "}");
}
}

View File

@ -187,7 +187,7 @@ public class BinaryReader extends InputStream {
}
public ItemStack readItemStack() {
return buffer.read(ITEM);
return buffer.read(ItemStack.NETWORK_TYPE);
}
public Component readComponent(int maxLength) {

View File

@ -164,7 +164,7 @@ public class BinaryWriter extends OutputStream {
}
public void writeItemStack(@NotNull ItemStack itemStack) {
this.buffer.write(ITEM, itemStack);
this.buffer.write(ItemStack.NETWORK_TYPE, itemStack);
}
public void writeNBT(@NotNull String name, @NotNull BinaryTag tag) {

View File

@ -58,9 +58,10 @@ public record BiomeParticle(float probability, Option option) {
@Override
public CompoundBinaryTag toNbt() {
//todo test count might be wrong type
return item.meta().toNBT()
.putString("type", type);
//todo
// return item.meta().toNBT()
// .putString("type", type);
return CompoundBinaryTag.empty();
}
}