diff --git a/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php b/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php index bbc295b72..7a720559e 100644 --- a/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php +++ b/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php @@ -305,6 +305,7 @@ final class ItemSerializerDeserializerRegistrar{ $this->map1to1Item(Ids::MUSIC_DISC_WAIT, Items::RECORD_WAIT()); $this->map1to1Item(Ids::MUSIC_DISC_WARD, Items::RECORD_WARD()); $this->map1to1Item(Ids::MUTTON, Items::RAW_MUTTON()); + $this->map1to1Item(Ids::NAME_TAG, Items::NAME_TAG()); $this->map1to1Item(Ids::NAUTILUS_SHELL, Items::NAUTILUS_SHELL()); $this->map1to1Item(Ids::NETHER_STAR, Items::NETHER_STAR()); $this->map1to1Item(Ids::NETHERBRICK, Items::NETHER_BRICK()); diff --git a/src/entity/Entity.php b/src/entity/Entity.php index d26a06d92..5fc2168d5 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -252,6 +252,14 @@ abstract class Entity{ return $this->alwaysShowNameTag; } + /** + * Returns whether players can rename this entity using a name tag. + * Note that plugins can still name entities using setNameTag(). + */ + public function canBeRenamed() : bool{ + return false; + } + public function setNameTag(string $name) : void{ $this->nameTag = $name; $this->networkPropertiesDirty = true; diff --git a/src/entity/Living.php b/src/entity/Living.php index 4d5e10cb3..e7d669fda 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -132,6 +132,10 @@ abstract class Living extends Entity{ abstract public function getName() : string; + public function canBeRenamed() : bool{ + return true; + } + protected function initEntity(CompoundTag $nbt) : void{ parent::initEntity($nbt); diff --git a/src/item/ItemTypeIds.php b/src/item/ItemTypeIds.php index bf688118b..66eebed74 100644 --- a/src/item/ItemTypeIds.php +++ b/src/item/ItemTypeIds.php @@ -323,8 +323,9 @@ final class ItemTypeIds{ public const EYE_ARMOR_TRIM_SMITHING_TEMPLATE = 20284; public const SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE = 20285; public const PITCHER_POD = 20286; + public const NAME_TAG = 20287; - public const FIRST_UNUSED_ITEM_ID = 20287; + public const FIRST_UNUSED_ITEM_ID = 20288; private static int $nextDynamicId = self::FIRST_UNUSED_ITEM_ID; diff --git a/src/item/NameTag.php b/src/item/NameTag.php new file mode 100644 index 000000000..8c7113e1d --- /dev/null +++ b/src/item/NameTag.php @@ -0,0 +1,40 @@ +canBeRenamed() && $this->hasCustomName()){ + $entity->setNameTag($this->getCustomName()); + $this->pop(); + return true; + } + return false; + } +} diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index ca73dded8..91fd2ab4a 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -1384,6 +1384,7 @@ final class StringToItemParser extends StringToTParser{ $result->register("mutton_raw", fn() => Items::RAW_MUTTON()); $result->register("muttoncooked", fn() => Items::COOKED_MUTTON()); $result->register("muttonraw", fn() => Items::RAW_MUTTON()); + $result->register("name_tag", fn() => Items::NAME_TAG()); $result->register("nautilus_shell", fn() => Items::NAUTILUS_SHELL()); $result->register("nether_brick", fn() => Items::NETHER_BRICK()); $result->register("nether_quartz", fn() => Items::NETHER_QUARTZ()); diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index f9aca9a76..bbd0dfc01 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -219,6 +219,7 @@ use function strtolower; * @method static MilkBucket MILK_BUCKET() * @method static Minecart MINECART() * @method static MushroomStew MUSHROOM_STEW() + * @method static NameTag NAME_TAG() * @method static Item NAUTILUS_SHELL() * @method static Axe NETHERITE_AXE() * @method static Armor NETHERITE_BOOTS() @@ -490,6 +491,7 @@ final class VanillaItems{ self::register("milk_bucket", new MilkBucket(new IID(Ids::MILK_BUCKET), "Milk Bucket")); self::register("minecart", new Minecart(new IID(Ids::MINECART), "Minecart")); self::register("mushroom_stew", new MushroomStew(new IID(Ids::MUSHROOM_STEW), "Mushroom Stew")); + self::register("name_tag", new NameTag(new IID(Ids::NAME_TAG), "Name Tag")); self::register("nautilus_shell", new Item(new IID(Ids::NAUTILUS_SHELL), "Nautilus Shell")); self::register("nether_brick", new Item(new IID(Ids::NETHER_BRICK), "Nether Brick")); self::register("nether_quartz", new Item(new IID(Ids::NETHER_QUARTZ), "Nether Quartz")); diff --git a/src/player/Player.php b/src/player/Player.php index 92e15ddd3..7a717dacd 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -630,6 +630,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->displayName = $ev->getNewName(); } + public function canBeRenamed() : bool{ + return false; + } + /** * Returns the player's locale, e.g. en_US. */