diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 41d69f002..242bf2ffb 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -37,6 +37,7 @@ import org.geysermc.geyser.entity.type.BoatEntity; import org.geysermc.geyser.entity.type.ChestBoatEntity; import org.geysermc.geyser.entity.type.CommandBlockMinecartEntity; import org.geysermc.geyser.entity.type.DisplayBaseEntity; +import org.geysermc.geyser.entity.type.ThrowableEggEntity; import org.geysermc.geyser.entity.type.EnderCrystalEntity; import org.geysermc.geyser.entity.type.EnderEyeEntity; import org.geysermc.geyser.entity.type.Entity; @@ -189,7 +190,7 @@ public final class EntityDefinitions { public static final EntityDefinition DONKEY; public static final EntityDefinition DRAGON_FIREBALL; public static final EntityDefinition DROWNED; - public static final EntityDefinition EGG; + public static final EntityDefinition EGG; public static final EntityDefinition ELDER_GUARDIAN; public static final EntityDefinition ENDERMAN; public static final EntityDefinition ENDERMITE; @@ -250,7 +251,8 @@ public final class EntityDefinitions { public static final EntityDefinition PILLAGER; public static final EntityDefinition PLAYER; public static final EntityDefinition POLAR_BEAR; - public static final EntityDefinition POTION; + public static final EntityDefinition SPLASH_POTION; + public static final EntityDefinition LINGERING_POTION; public static final EntityDefinition PUFFERFISH; public static final EntityDefinition RABBIT; public static final EntityDefinition RAVAGER; @@ -459,7 +461,7 @@ public final class EntityDefinitions { EntityDefinition throwableItemBase = EntityDefinition.inherited(ThrowableItemEntity::new, entityBase) .addTranslator(MetadataTypes.ITEM_STACK, ThrowableItemEntity::setItem) .build(); - EGG = EntityDefinition.inherited(ThrowableItemEntity::new, throwableItemBase) + EGG = EntityDefinition.inherited(ThrowableEggEntity::new, throwableItemBase) .type(EntityType.EGG) .heightAndWidth(0.25f) .properties(VanillaEntityProperties.CLIMATE_VARIANT) @@ -473,12 +475,16 @@ public final class EntityDefinitions { .heightAndWidth(0.25f) .identifier("minecraft:xp_bottle") .build(); - // TODO 1.21.5 lingering potion - POTION = EntityDefinition.inherited(ThrownPotionEntity::new, throwableItemBase) + SPLASH_POTION = EntityDefinition.inherited(ThrownPotionEntity::new, throwableItemBase) .type(EntityType.SPLASH_POTION) .heightAndWidth(0.25f) .identifier("minecraft:splash_potion") .build(); + LINGERING_POTION = EntityDefinition.inherited(ThrownPotionEntity::new, throwableItemBase) + .type(EntityType.SPLASH_POTION) + .heightAndWidth(0.25f) + .identifier("minecraft:splash_potion") + .build(); SNOWBALL = EntityDefinition.inherited(ThrowableItemEntity::new, throwableItemBase) .type(EntityType.SNOWBALL) .heightAndWidth(0.25f) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEggEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEggEntity.java new file mode 100644 index 000000000..e86265ded --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEggEntity.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.entity.type; + +import net.kyori.adventure.key.Key; +import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.packet.AddEntityPacket; +import org.geysermc.geyser.entity.EntityDefinition; +import org.geysermc.geyser.entity.properties.VanillaEntityProperties; +import org.geysermc.geyser.entity.type.living.animal.farm.TemperatureVariantAnimal; +import org.geysermc.geyser.inventory.GeyserItemStack; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.registry.JavaRegistries; +import org.geysermc.mcprotocollib.protocol.data.game.Holder; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes; + +import java.util.Locale; +import java.util.UUID; + +public class ThrowableEggEntity extends ThrowableItemEntity { + public ThrowableEggEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { + super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + } + + @Override + public void addAdditionalSpawnData(AddEntityPacket addEntityPacket) { + propertyManager.add(VanillaEntityProperties.CLIMATE_VARIANT_ID, "temperate"); + propertyManager.applyIntProperties(addEntityPacket.getProperties().getIntProperties()); + } + + @Override + public void setItem(EntityMetadata entityMetadata) { + GeyserItemStack stack = GeyserItemStack.from(entityMetadata.getValue()); + propertyManager.add(VanillaEntityProperties.CLIMATE_VARIANT_ID, getVariantOrFallback(session, stack)); + updateBedrockEntityProperties(); + } + + private static String getVariantOrFallback(GeyserSession session, GeyserItemStack stack) { + Holder holder = stack.getComponent(DataComponentTypes.CHICKEN_VARIANT); + if (holder != null) { + Key chickenVariant = holder.getOrCompute(id -> JavaRegistries.CHICKEN_VARIANT.keyFromNetworkId(session, id)); + for (var variant : TemperatureVariantAnimal.BuiltInVariant.values()) { + if (chickenVariant.asMinimalString().equalsIgnoreCase(variant.name())) { + return chickenVariant.asMinimalString().toLowerCase(Locale.ROOT); + } + } + } + + return TemperatureVariantAnimal.BuiltInVariant.TEMPERATE.name().toLowerCase(Locale.ROOT); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java index e49ce864a..fbbe2de50 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java @@ -28,13 +28,10 @@ package org.geysermc.geyser.entity.type; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; -import org.cloudburstmc.protocol.bedrock.packet.AddEntityPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinitions; -import org.geysermc.geyser.entity.properties.VanillaEntityProperties; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; -import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import java.util.UUID; @@ -56,14 +53,6 @@ public class ThrowableItemEntity extends ThrowableEntity { age = 0; } - @Override - public void addAdditionalSpawnData(AddEntityPacket addEntityPacket) { - if (definition.entityType() == EntityType.EGG) { - propertyManager.add(VanillaEntityProperties.CLIMATE_VARIANT_ID, "temperate"); - propertyManager.applyIntProperties(addEntityPacket.getProperties().getIntProperties()); - } - } - @Override protected void initializeMetadata() { super.initializeMetadata(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java index e940b074e..84c2cb731 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java @@ -31,10 +31,9 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.item.Potion; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; @@ -73,7 +72,7 @@ public class ThrownPotionEntity extends ThrowableItemEntity { } } - boolean isLingering = Registries.JAVA_ITEMS.get().get(itemStack.getId()) == Items.LINGERING_POTION; + boolean isLingering = definition.entityType() == EntityType.LINGERING_POTION; setFlag(EntityFlag.LINGERING, isLingering); } } diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/RecipeRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/RecipeRegistryLoader.java index 74c36c00a..d0673a1c5 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/RecipeRegistryLoader.java +++ b/core/src/main/java/org/geysermc/geyser/registry/loader/RecipeRegistryLoader.java @@ -133,7 +133,7 @@ public abstract class RecipeRegistryLoader implements RegistryLoader