1
0
mirror of https://github.com/GeyserMC/Geyser.git synced 2025-12-29 11:49:16 +00:00

Implement thrown egg item variants

This commit is contained in:
onebeastchris
2025-03-28 19:06:52 +01:00
parent ea10a512b3
commit 97e15da214
5 changed files with 90 additions and 20 deletions

View File

@@ -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<ChestedHorseEntity> DONKEY;
public static final EntityDefinition<FireballEntity> DRAGON_FIREBALL;
public static final EntityDefinition<ZombieEntity> DROWNED;
public static final EntityDefinition<ThrowableItemEntity> EGG;
public static final EntityDefinition<ThrowableEggEntity> EGG;
public static final EntityDefinition<ElderGuardianEntity> ELDER_GUARDIAN;
public static final EntityDefinition<EndermanEntity> ENDERMAN;
public static final EntityDefinition<MonsterEntity> ENDERMITE;
@@ -250,7 +251,8 @@ public final class EntityDefinitions {
public static final EntityDefinition<PillagerEntity> PILLAGER;
public static final EntityDefinition<PlayerEntity> PLAYER;
public static final EntityDefinition<PolarBearEntity> POLAR_BEAR;
public static final EntityDefinition<ThrownPotionEntity> POTION;
public static final EntityDefinition<ThrownPotionEntity> SPLASH_POTION;
public static final EntityDefinition<ThrownPotionEntity> LINGERING_POTION;
public static final EntityDefinition<PufferFishEntity> PUFFERFISH;
public static final EntityDefinition<RabbitEntity> RABBIT;
public static final EntityDefinition<RavagerEntity> RAVAGER;
@@ -459,7 +461,7 @@ public final class EntityDefinitions {
EntityDefinition<ThrowableItemEntity> 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)

View File

@@ -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<ItemStack, ?> 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<Key> 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);
}
}

View File

@@ -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();

View File

@@ -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);
}
}

View File

@@ -133,7 +133,7 @@ public abstract class RecipeRegistryLoader implements RegistryLoader<String, Map
if (componentsRaw != null) {
byte[] bytes = Base64.getDecoder().decode(componentsRaw);
ByteBuf buf = Unpooled.wrappedBuffer(bytes);
DataComponents components = MinecraftTypes.readDataComponentPatch(buf);
DataComponents components = MinecraftTypes.readDataComponentPatch(buf, false);
return new ItemStack(id, count, components);
}
return new ItemStack(id, count);