3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-10-03 08:21:06 +02:00

Entity refactor bug fixes and other 1.18 changes

Dieser Commit ist enthalten in:
Camotoy 2021-11-18 20:44:03 -05:00
Ursprung 11997ed82b
Commit e0a7887f3f
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 7EEFB66FE798081F
60 geänderte Dateien mit 243 neuen und 301 gelöschten Zeilen

Datei anzeigen

@ -40,7 +40,7 @@ public class AbstractArrowEntity extends Entity {
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
// Set the correct texture if using the resource pack // Set the correct texture if using the resource pack
dirtyMetadata.getFlags().setFlag(EntityFlag.BRIBED, definition.entityType() == EntityType.SPECTRAL_ARROW); setFlag(EntityFlag.BRIBED, definition.entityType() == EntityType.SPECTRAL_ARROW);
setMotion(motion); setMotion(motion);
} }

Datei anzeigen

@ -45,7 +45,7 @@ public class EnderCrystalEntity extends Entity {
protected void initializeMetadata() { protected void initializeMetadata() {
super.initializeMetadata(); super.initializeMetadata();
// Bedrock 1.16.100+ - prevents the entity from appearing on fire itself when fire is underneath it // Bedrock 1.16.100+ - prevents the entity from appearing on fire itself when fire is underneath it
dirtyMetadata.getFlags().setFlag(EntityFlag.FIRE_IMMUNE, true); setFlag(EntityFlag.FIRE_IMMUNE, true);
} }
public void setBlockTarget(EntityMetadata<Position> entityMetadata) { public void setBlockTarget(EntityMetadata<Position> entityMetadata) {

Datei anzeigen

@ -32,7 +32,6 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEnti
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData; import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityDataMap;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlags; import com.nukkitx.protocol.bedrock.data.entity.EntityFlags;
import com.nukkitx.protocol.bedrock.packet.AddEntityPacket; import com.nukkitx.protocol.bedrock.packet.AddEntityPacket;
@ -83,13 +82,15 @@ public class Entity {
protected float boundingBoxHeight; protected float boundingBoxHeight;
@Setter(AccessLevel.NONE) @Setter(AccessLevel.NONE)
protected float boundingBoxWidth; protected float boundingBoxWidth;
@Setter(AccessLevel.NONE)
protected String nametag = "";
/* Metadata end */ /* Metadata end */
protected LongOpenHashSet passengers = new LongOpenHashSet(); protected LongOpenHashSet passengers = new LongOpenHashSet();
/** /**
* A container to store temporary metadata before it's sent to Bedrock. * A container to store temporary metadata before it's sent to Bedrock.
*/ */
protected final EntityDataMap dirtyMetadata = new EntityDataMap(); protected final GeyserDirtyMetadata dirtyMetadata = new GeyserDirtyMetadata();
/** /**
* The entity flags for the Bedrock entity. * The entity flags for the Bedrock entity.
* These must always be saved - if flags are updated and the other values aren't present, the Bedrock client will * These must always be saved - if flags are updated and the other values aren't present, the Bedrock client will
@ -146,15 +147,13 @@ public class Entity {
addEntityPacket.setPosition(position); addEntityPacket.setPosition(position);
addEntityPacket.setMotion(motion); addEntityPacket.setMotion(motion);
addEntityPacket.setRotation(getBedrockRotation()); addEntityPacket.setRotation(getBedrockRotation());
addEntityPacket.setEntityType(definition.bedrockId()); addEntityPacket.getMetadata().putFlags(flags);
addEntityPacket.getMetadata().putFlags(flags) dirtyMetadata.apply(addEntityPacket.getMetadata());
.putAll(dirtyMetadata);
addAdditionalSpawnData(addEntityPacket); addAdditionalSpawnData(addEntityPacket);
valid = true; valid = true;
session.sendUpstreamPacket(addEntityPacket); session.sendUpstreamPacket(addEntityPacket);
dirtyMetadata.clear();
flagsDirty = false; flagsDirty = false;
session.getConnector().getLogger().debug("Spawned entity " + getClass().getName() + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")"); session.getConnector().getLogger().debug("Spawned entity " + getClass().getName() + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")");
@ -293,16 +292,16 @@ public class Entity {
return; return;
} }
if (!dirtyMetadata.isEmpty() || flagsDirty) { if (dirtyMetadata.hasEntries() || flagsDirty) {
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
entityDataPacket.setRuntimeEntityId(geyserId); entityDataPacket.setRuntimeEntityId(geyserId);
if (flagsDirty) {
entityDataPacket.getMetadata().putFlags(flags); entityDataPacket.getMetadata().putFlags(flags);
entityDataPacket.getMetadata().putAll(dirtyMetadata);
session.sendUpstreamPacket(entityDataPacket);
dirtyMetadata.clear();
flagsDirty = false; flagsDirty = false;
} }
dirtyMetadata.apply(entityDataPacket.getMetadata());
session.sendUpstreamPacket(entityDataPacket);
}
} }
public void setFlags(EntityMetadata<Byte> entityMetadata) { public void setFlags(EntityMetadata<Byte> entityMetadata) {
@ -343,9 +342,9 @@ public class Entity {
public void setDisplayName(EntityMetadata<Component> entityMetadata) { public void setDisplayName(EntityMetadata<Component> entityMetadata) {
Component name = entityMetadata.getValue(); Component name = entityMetadata.getValue();
if (name != null) { if (name != null) {
String displayName = MessageTranslator.convertMessage(name, session.getLocale()); nametag = MessageTranslator.convertMessage(name, session.getLocale());
dirtyMetadata.put(EntityData.NAMETAG, displayName); dirtyMetadata.put(EntityData.NAMETAG, nametag);
} else if (!dirtyMetadata.getString(EntityData.NAMETAG).isEmpty()) { //TODO } else if (!nametag.isEmpty()) {
// Clear nametag // Clear nametag
dirtyMetadata.put(EntityData.NAMETAG, ""); dirtyMetadata.put(EntityData.NAMETAG, "");
} }
@ -376,14 +375,24 @@ public class Entity {
*/ */
protected void setDimensions(Pose pose) { protected void setDimensions(Pose pose) {
// No flexibility options for basic entities // No flexibility options for basic entities
if (boundingBoxHeight != definition.height() || boundingBoxWidth != definition.width()) { setBoundingBoxHeight(definition.height());
boundingBoxWidth = definition.width(); setBoundingBoxWidth(definition.width());
boundingBoxHeight = definition.height(); }
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, boundingBoxWidth);
public void setBoundingBoxHeight(float height) {
if (height != boundingBoxHeight) {
boundingBoxHeight = height;
dirtyMetadata.put(EntityData.BOUNDING_BOX_HEIGHT, boundingBoxHeight); dirtyMetadata.put(EntityData.BOUNDING_BOX_HEIGHT, boundingBoxHeight);
} }
} }
public void setBoundingBoxWidth(float width) {
if (width != boundingBoxWidth) {
boundingBoxWidth = width;
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, boundingBoxWidth);
}
}
/** /**
* Set a float from 0-1 - how strong the "frozen" overlay should be on screen. * Set a float from 0-1 - how strong the "frozen" overlay should be on screen.
*/ */
@ -396,6 +405,10 @@ public class Entity {
return freezingPercentage; return freezingPercentage;
} }
public void setRiderSeatPosition(Vector3f position) {
dirtyMetadata.put(EntityData.RIDER_SEAT_POSITION, position);
}
/** /**
* If true, the entity should be shaking on the client's end. * If true, the entity should be shaking on the client's end.
* *

Datei anzeigen

@ -46,7 +46,7 @@ import java.util.function.BiConsumer;
* *
* @param <T> the entity type this definition represents * @param <T> the entity type this definition represents
*/ */
public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, EntityType entityType, int bedrockId, String identifier, public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, EntityType entityType, String identifier,
float width, float height, float offset, List<EntityMetadataTranslator<? super T, ?>> translators) { float width, float height, float offset, List<EntityMetadataTranslator<? super T, ?>> translators) {
public static <T extends Entity> Builder<T> inherited(BaseEntityFactory<T> factory, EntityDefinition<? super T> parent) { public static <T extends Entity> Builder<T> inherited(BaseEntityFactory<T> factory, EntityDefinition<? super T> parent) {
@ -54,7 +54,7 @@ public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, Entit
} }
public static <T extends Entity> Builder<T> inherited(EntityFactory<T> factory, EntityDefinition<? super T> parent) { public static <T extends Entity> Builder<T> inherited(EntityFactory<T> factory, EntityDefinition<? super T> parent) {
return new Builder<>(factory, parent.entityType, parent.bedrockId, parent.identifier, parent.width, parent.height, parent.offset, new ObjectArrayList<>(parent.translators)); return new Builder<>(factory, parent.entityType, parent.identifier, parent.width, parent.height, parent.offset, new ObjectArrayList<>(parent.translators));
} }
public static <T extends Entity> Builder<T> builder(EntityFactory<T> factory) { public static <T extends Entity> Builder<T> builder(EntityFactory<T> factory) {
@ -66,7 +66,6 @@ public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, Entit
public static class Builder<T extends Entity> { public static class Builder<T extends Entity> {
private final EntityFactory<T> factory; private final EntityFactory<T> factory;
private EntityType type; private EntityType type;
private int bedrockId;
private String identifier; private String identifier;
private float width; private float width;
private float height; private float height;
@ -78,10 +77,9 @@ public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, Entit
translators = new ObjectArrayList<>(); translators = new ObjectArrayList<>();
} }
public Builder(EntityFactory<T> factory, EntityType type, int bedrockId, String identifier, float width, float height, float offset, List<EntityMetadataTranslator<? super T, ?>> translators) { public Builder(EntityFactory<T> factory, EntityType type, String identifier, float width, float height, float offset, List<EntityMetadataTranslator<? super T, ?>> translators) {
this.factory = factory; this.factory = factory;
this.type = type; this.type = type;
this.bedrockId = bedrockId;
this.identifier = identifier; this.identifier = identifier;
this.width = width; this.width = width;
this.height = height; this.height = height;
@ -129,10 +127,10 @@ public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, Entit
if (identifier == null && type != null) { if (identifier == null && type != null) {
identifier = "minecraft:" + type.name().toLowerCase(Locale.ROOT); identifier = "minecraft:" + type.name().toLowerCase(Locale.ROOT);
} }
EntityDefinition<T> definition = new EntityDefinition<>(factory, type, bedrockId, identifier, width, height, offset, translators); EntityDefinition<T> definition = new EntityDefinition<>(factory, type, identifier, width, height, offset, translators);
if (register && definition.entityType() != null) { if (register && definition.entityType() != null) {
Registries.ENTITY_DEFINITIONS.get().putIfAbsent(definition.entityType(), definition); Registries.ENTITY_DEFINITIONS.get().putIfAbsent(definition.entityType(), definition);
Registries.JAVA_ENTITY_IDENTIFIERS.get().putIfAbsent(definition.identifier(), definition); Registries.JAVA_ENTITY_IDENTIFIERS.get().putIfAbsent("minecraft:" + type.name().toLowerCase(Locale.ROOT), definition);
} }
return definition; return definition;
} }

Datei anzeigen

@ -33,7 +33,6 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.geysermc.connector.entity.factory.BaseEntityFactory; import org.geysermc.connector.entity.factory.BaseEntityFactory;
import org.geysermc.connector.entity.factory.EntityFactory;
import org.geysermc.connector.entity.factory.ExperienceOrbEntityFactory; import org.geysermc.connector.entity.factory.ExperienceOrbEntityFactory;
import org.geysermc.connector.entity.factory.PaintingEntityFactory; import org.geysermc.connector.entity.factory.PaintingEntityFactory;
import org.geysermc.connector.entity.living.*; import org.geysermc.connector.entity.living.*;
@ -52,6 +51,7 @@ import org.geysermc.connector.entity.living.monster.raid.SpellcasterIllagerEntit
import org.geysermc.connector.entity.living.monster.raid.VindicatorEntity; import org.geysermc.connector.entity.living.monster.raid.VindicatorEntity;
import org.geysermc.connector.entity.player.PlayerEntity; import org.geysermc.connector.entity.player.PlayerEntity;
import org.geysermc.connector.network.translators.chat.MessageTranslator; import org.geysermc.connector.network.translators.chat.MessageTranslator;
import org.geysermc.connector.registry.Registries;
public final class EntityDefinitions { public final class EntityDefinitions {
public static final EntityDefinition<AreaEffectCloudEntity> AREA_EFFECT_CLOUD; public static final EntityDefinition<AreaEffectCloudEntity> AREA_EFFECT_CLOUD;
@ -192,7 +192,6 @@ public final class EntityDefinitions {
{ {
AREA_EFFECT_CLOUD = EntityDefinition.inherited(AreaEffectCloudEntity::new, entityBase) AREA_EFFECT_CLOUD = EntityDefinition.inherited(AreaEffectCloudEntity::new, entityBase)
.type(EntityType.AREA_EFFECT_CLOUD) .type(EntityType.AREA_EFFECT_CLOUD)
.bedrockId(95)
.height(0.5f).width(1.0f) .height(0.5f).width(1.0f)
.addTranslator(MetadataType.FLOAT, AreaEffectCloudEntity::setRadius) .addTranslator(MetadataType.FLOAT, AreaEffectCloudEntity::setRadius)
.addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.EFFECT_COLOR, entityMetadata.getValue())) .addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.EFFECT_COLOR, entityMetadata.getValue()))
@ -201,7 +200,6 @@ public final class EntityDefinitions {
.build(); .build();
BOAT = EntityDefinition.inherited(BoatEntity::new, entityBase) BOAT = EntityDefinition.inherited(BoatEntity::new, entityBase)
.type(EntityType.BOAT) .type(EntityType.BOAT)
.bedrockId(90)
.height(0.6f).width(1.6f) .height(0.6f).width(1.6f)
.offset(0.35f) .offset(0.35f)
.addTranslator(MetadataType.INT, (boatEntity, entityMetadata) -> boatEntity.getDirtyMetadata().put(EntityData.HURT_TIME, entityMetadata.getValue())) // Time since last hit .addTranslator(MetadataType.INT, (boatEntity, entityMetadata) -> boatEntity.getDirtyMetadata().put(EntityData.HURT_TIME, entityMetadata.getValue())) // Time since last hit
@ -216,12 +214,10 @@ public final class EntityDefinitions {
.build(); .build();
DRAGON_FIREBALL = EntityDefinition.inherited(ItemedFireballEntity::new, entityBase) DRAGON_FIREBALL = EntityDefinition.inherited(ItemedFireballEntity::new, entityBase)
.type(EntityType.DRAGON_FIREBALL) .type(EntityType.DRAGON_FIREBALL)
.bedrockId(79)
.heightAndWidth(1.0f) .heightAndWidth(1.0f)
.build(); .build();
END_CRYSTAL = EntityDefinition.inherited(EnderCrystalEntity::new, entityBase) END_CRYSTAL = EntityDefinition.inherited(EnderCrystalEntity::new, entityBase)
.type(EntityType.END_CRYSTAL) .type(EntityType.END_CRYSTAL)
.bedrockId(71)
.heightAndWidth(2.0f) .heightAndWidth(2.0f)
.addTranslator(MetadataType.OPTIONAL_POSITION, EnderCrystalEntity::setBlockTarget) .addTranslator(MetadataType.OPTIONAL_POSITION, EnderCrystalEntity::setBlockTarget)
.<Boolean>addTranslator(MetadataType.BOOLEAN, .<Boolean>addTranslator(MetadataType.BOOLEAN,
@ -229,115 +225,94 @@ public final class EntityDefinitions {
.build(); .build();
EXPERIENCE_ORB = EntityDefinition.inherited((ExperienceOrbEntityFactory) ExpOrbEntity::new, entityBase) EXPERIENCE_ORB = EntityDefinition.inherited((ExperienceOrbEntityFactory) ExpOrbEntity::new, entityBase)
.type(EntityType.EXPERIENCE_ORB) .type(EntityType.EXPERIENCE_ORB)
.bedrockId(69)
.identifier("minecraft:xp_orb") .identifier("minecraft:xp_orb")
.build(); .build();
EVOKER_FANGS = EntityDefinition.inherited(entityBase.factory(), entityBase) EVOKER_FANGS = EntityDefinition.inherited(entityBase.factory(), entityBase)
.type(EntityType.EVOKER_FANGS) .type(EntityType.EVOKER_FANGS)
.bedrockId(103)
.height(0.8f).width(0.5f) .height(0.8f).width(0.5f)
.identifier("minecraft:evocation_fang") .identifier("minecraft:evocation_fang")
.build(); .build();
EYE_OF_ENDER = EntityDefinition.inherited(Entity::new, entityBase) EYE_OF_ENDER = EntityDefinition.inherited(Entity::new, entityBase)
.type(EntityType.EYE_OF_ENDER) .type(EntityType.EYE_OF_ENDER)
.bedrockId(70)
.heightAndWidth(0.25f) .heightAndWidth(0.25f)
.identifier("minecraft:eye_of_ender_signal") .identifier("minecraft:eye_of_ender_signal")
.build(); .build();
FALLING_BLOCK = EntityDefinition.inherited(new EntityFactory<FallingBlockEntity>() { FALLING_BLOCK = EntityDefinition.<FallingBlockEntity>inherited(null, entityBase)
}, entityBase) // TODO
.type(EntityType.FALLING_BLOCK) .type(EntityType.FALLING_BLOCK)
.bedrockId(66)
.heightAndWidth(0.98f) .heightAndWidth(0.98f)
.addTranslator(null) // "start block position"
.build(); .build();
FIREBALL = EntityDefinition.inherited(ItemedFireballEntity::new, entityBase) FIREBALL = EntityDefinition.inherited(ItemedFireballEntity::new, entityBase)
.type(EntityType.FIREBALL) .type(EntityType.FIREBALL)
.bedrockId(85)
.heightAndWidth(1.0f) .heightAndWidth(1.0f)
.build(); .build();
FIREWORK_ROCKET = EntityDefinition.inherited(FireworkEntity::new, entityBase) FIREWORK_ROCKET = EntityDefinition.inherited(FireworkEntity::new, entityBase)
.type(EntityType.FIREWORK_ROCKET) .type(EntityType.FIREWORK_ROCKET)
.bedrockId(72)
.heightAndWidth(0.25f) .heightAndWidth(0.25f)
.identifier("minecraft:fireworks_rocket") .identifier("minecraft:fireworks_rocket")
.addTranslator(MetadataType.ITEM, FireworkEntity::setFireworkItem) .addTranslator(MetadataType.ITEM, FireworkEntity::setFireworkItem)
.addTranslator(MetadataType.OPTIONAL_VARINT, FireworkEntity::setPlayerGliding) .addTranslator(MetadataType.OPTIONAL_VARINT, FireworkEntity::setPlayerGliding)
.build(); .build();
FISHING_BOBBER = EntityDefinition.inherited(new EntityFactory<FishingHookEntity>() { FISHING_BOBBER = EntityDefinition.<FishingHookEntity>inherited(null, entityBase)
}, entityBase) //TODO
.type(EntityType.FISHING_BOBBER) .type(EntityType.FISHING_BOBBER)
.bedrockId(77)
.identifier("minecraft:fishing_book") .identifier("minecraft:fishing_book")
.addTranslator(MetadataType.INT, FishingHookEntity::setHookedEntity) .addTranslator(MetadataType.INT, FishingHookEntity::setHookedEntity)
.build(); .build();
ITEM = EntityDefinition.inherited(ItemEntity::new, entityBase) ITEM = EntityDefinition.inherited(ItemEntity::new, entityBase)
.type(EntityType.ITEM) .type(EntityType.ITEM)
.bedrockId(64)
.heightAndWidth(0.25f) .heightAndWidth(0.25f)
.offset(0.125f) .offset(0.125f)
.addTranslator(MetadataType.ITEM, ItemEntity::setItem) .addTranslator(MetadataType.ITEM, ItemEntity::setItem)
.build(); .build();
LEASH_KNOT = EntityDefinition.inherited(LeashKnotEntity::new, entityBase) LEASH_KNOT = EntityDefinition.inherited(LeashKnotEntity::new, entityBase)
.type(EntityType.LEASH_KNOT) .type(EntityType.LEASH_KNOT)
.bedrockId(88)
.height(0.5f).width(0.375f) .height(0.5f).width(0.375f)
.build(); .build();
LIGHTNING_BOLT = EntityDefinition.inherited(LightningEntity::new, entityBase) LIGHTNING_BOLT = EntityDefinition.inherited(LightningEntity::new, entityBase)
.type(EntityType.LIGHTNING_BOLT) .type(EntityType.LIGHTNING_BOLT)
.bedrockId(93)
.build(); .build();
LLAMA_SPIT = EntityDefinition.inherited(ThrowableEntity::new, entityBase) LLAMA_SPIT = EntityDefinition.inherited(ThrowableEntity::new, entityBase)
.type(EntityType.LLAMA_SPIT) .type(EntityType.LLAMA_SPIT)
.bedrockId(102)
.heightAndWidth(0.25f) .heightAndWidth(0.25f)
.build(); .build();
PAINTING = EntityDefinition.inherited((PaintingEntityFactory) PaintingEntity::new, entityBase) PAINTING = EntityDefinition.inherited((PaintingEntityFactory) PaintingEntity::new, entityBase)
.type(EntityType.PAINTING) .type(EntityType.PAINTING)
.bedrockId(83)
.build(); .build();
PRIMED_TNT = EntityDefinition.inherited(TNTEntity::new, entityBase) PRIMED_TNT = EntityDefinition.inherited(TNTEntity::new, entityBase)
.type(EntityType.PRIMED_TNT) .type(EntityType.PRIMED_TNT)
.bedrockId(65)
.heightAndWidth(0.98f) .heightAndWidth(0.98f)
.identifier("minecraft:tnt") .identifier("minecraft:tnt")
.addTranslator(MetadataType.INT, TNTEntity::setFuseLength) .addTranslator(MetadataType.INT, TNTEntity::setFuseLength)
.build(); .build();
SHULKER_BULLET = EntityDefinition.inherited(ThrowableEntity::new, entityBase) SHULKER_BULLET = EntityDefinition.inherited(ThrowableEntity::new, entityBase)
.type(EntityType.SHULKER_BULLET) .type(EntityType.SHULKER_BULLET)
.bedrockId(76)
.heightAndWidth(0.3125f) .heightAndWidth(0.3125f)
.build(); .build();
SMALL_FIREBALL = EntityDefinition.inherited(ItemedFireballEntity::new, entityBase) SMALL_FIREBALL = EntityDefinition.inherited(ItemedFireballEntity::new, entityBase)
.type(EntityType.SMALL_FIREBALL) .type(EntityType.SMALL_FIREBALL)
.bedrockId(94)
.heightAndWidth(0.3125f) .heightAndWidth(0.3125f)
.build(); .build();
SNOWBALL = EntityDefinition.inherited(ThrowableItemEntity::new, entityBase) SNOWBALL = EntityDefinition.inherited(ThrowableItemEntity::new, entityBase)
.type(EntityType.SNOWBALL) .type(EntityType.SNOWBALL)
.bedrockId(81)
.heightAndWidth(0.25f) .heightAndWidth(0.25f)
.build(); .build();
THROWN_ENDERPEARL = EntityDefinition.inherited(ThrowableItemEntity::new, entityBase) THROWN_ENDERPEARL = EntityDefinition.inherited(ThrowableItemEntity::new, entityBase)
.type(EntityType.THROWN_ENDERPEARL) .type(EntityType.THROWN_ENDERPEARL)
.bedrockId(87)
.heightAndWidth(0.25f) .heightAndWidth(0.25f)
.identifier("minecraft:ender_pearl") .identifier("minecraft:ender_pearl")
.build(); .build();
THROWN_EGG = EntityDefinition.inherited(ThrowableItemEntity::new, entityBase) THROWN_EGG = EntityDefinition.inherited(ThrowableItemEntity::new, entityBase)
.type(EntityType.THROWN_EGG) .type(EntityType.THROWN_EGG)
.bedrockId(82)
.heightAndWidth(0.25f) .heightAndWidth(0.25f)
.identifier("minecraft:egg") .identifier("minecraft:egg")
.build(); .build();
THROWN_EXP_BOTTLE = EntityDefinition.inherited(ThrowableItemEntity::new, entityBase) THROWN_EXP_BOTTLE = EntityDefinition.inherited(ThrowableItemEntity::new, entityBase)
.type(EntityType.THROWN_EXP_BOTTLE) .type(EntityType.THROWN_EXP_BOTTLE)
.bedrockId(68)
.heightAndWidth(0.25f) .heightAndWidth(0.25f)
.identifier("minecraft:xp_bottle") .identifier("minecraft:xp_bottle")
.build(); .build();
THROWN_POTION = EntityDefinition.inherited(ThrownPotionEntity::new, entityBase) THROWN_POTION = EntityDefinition.inherited(ThrownPotionEntity::new, entityBase)
.type(EntityType.THROWN_POTION) .type(EntityType.THROWN_POTION)
.bedrockId(86)
.heightAndWidth(0.25f) .heightAndWidth(0.25f)
.identifier("minecraft:splash_potion") .identifier("minecraft:splash_potion")
.addTranslator(MetadataType.ITEM, ThrownPotionEntity::setPotion) .addTranslator(MetadataType.ITEM, ThrownPotionEntity::setPotion)
@ -349,30 +324,26 @@ public final class EntityDefinitions {
.build(); .build();
ARROW = EntityDefinition.inherited(TippedArrowEntity::new, abstractArrowBase) ARROW = EntityDefinition.inherited(TippedArrowEntity::new, abstractArrowBase)
.type(EntityType.ARROW) .type(EntityType.ARROW)
.bedrockId(80)
.heightAndWidth(0.25f) .heightAndWidth(0.25f)
.addTranslator(MetadataType.INT, TippedArrowEntity::setPotionEffectColor) .addTranslator(MetadataType.INT, TippedArrowEntity::setPotionEffectColor)
.build(); .build();
SPECTRAL_ARROW = EntityDefinition.inherited(abstractArrowBase.factory(), abstractArrowBase) SPECTRAL_ARROW = EntityDefinition.inherited(abstractArrowBase.factory(), abstractArrowBase)
.type(EntityType.SPECTRAL_ARROW) .type(EntityType.SPECTRAL_ARROW)
.bedrockId(80)
.heightAndWidth(0.25f) .heightAndWidth(0.25f)
.identifier("minecraft:arrow") .identifier("minecraft:arrow")
.build(); .build();
TRIDENT = EntityDefinition.inherited(TridentEntity::new, abstractArrowBase) // TODO remove class TRIDENT = EntityDefinition.inherited(TridentEntity::new, abstractArrowBase) // TODO remove class
.type(EntityType.TRIDENT) .type(EntityType.TRIDENT)
.bedrockId(73)
.identifier("minecraft:thrown_trident") .identifier("minecraft:thrown_trident")
.addTranslator(null) // Loyalty .addTranslator(null) // Loyalty
.<Boolean>addTranslator(MetadataType.BOOLEAN, (tridentEntity, entityMetadata) -> tridentEntity.setFlag(EntityFlag.ENCHANTED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue())) .<Boolean>addTranslator(MetadataType.BOOLEAN, (tridentEntity, entityMetadata) -> tridentEntity.setFlag(EntityFlag.ENCHANTED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
.build(); .build();
// Item frames are handled differently as they are blocks, not items, in Bedrock // Item frames are handled differently as they are blocks, not items, in Bedrock
ITEM_FRAME = EntityDefinition.inherited(new EntityFactory<ItemFrameEntity>() { ITEM_FRAME = EntityDefinition.<ItemFrameEntity>inherited(null, entityBase)
}, entityBase) // TODO
.type(EntityType.ITEM_FRAME) .type(EntityType.ITEM_FRAME)
.addTranslator(MetadataType.ITEM, ItemFrameEntity::setItemInFrame) .addTranslator(MetadataType.ITEM, ItemFrameEntity::setItemInFrame)
.addTranslator(MetadataType.ITEM, ItemFrameEntity::setItemRotation) .addTranslator(MetadataType.INT, ItemFrameEntity::setItemRotation)
.build(); .build();
GLOW_ITEM_FRAME = EntityDefinition.inherited(ITEM_FRAME.factory(), ITEM_FRAME) GLOW_ITEM_FRAME = EntityDefinition.inherited(ITEM_FRAME.factory(), ITEM_FRAME)
.type(EntityType.GLOW_ITEM_FRAME) .type(EntityType.GLOW_ITEM_FRAME)
@ -380,7 +351,6 @@ public final class EntityDefinitions {
MINECART = EntityDefinition.inherited(MinecartEntity::new, entityBase) MINECART = EntityDefinition.inherited(MinecartEntity::new, entityBase)
.type(EntityType.MINECART) .type(EntityType.MINECART)
.bedrockId(84)
.height(0.7f).width(0.98f) .height(0.7f).width(0.98f)
.offset(0.35f) .offset(0.35f)
.addTranslator(MetadataType.INT, (minecartEntity, entityMetadata) -> minecartEntity.getDirtyMetadata().put(EntityData.HEALTH, entityMetadata.getValue())) .addTranslator(MetadataType.INT, (minecartEntity, entityMetadata) -> minecartEntity.getDirtyMetadata().put(EntityData.HEALTH, entityMetadata.getValue()))
@ -388,7 +358,7 @@ public final class EntityDefinitions {
.<Float>addTranslator(MetadataType.FLOAT, (minecartEntity, entityMetadata) -> .<Float>addTranslator(MetadataType.FLOAT, (minecartEntity, entityMetadata) ->
// Power in Java, time in Bedrock // Power in Java, time in Bedrock
minecartEntity.getDirtyMetadata().put(EntityData.HURT_TIME, Math.min((int) ((FloatEntityMetadata) entityMetadata).getPrimitiveValue(), 15))) minecartEntity.getDirtyMetadata().put(EntityData.HURT_TIME, Math.min((int) ((FloatEntityMetadata) entityMetadata).getPrimitiveValue(), 15)))
.addTranslator(MetadataType.BLOCK_STATE, MinecartEntity::setCustomBlock) .addTranslator(MetadataType.INT, MinecartEntity::setCustomBlock)
.addTranslator(MetadataType.INT, MinecartEntity::setCustomBlockOffset) .addTranslator(MetadataType.INT, MinecartEntity::setCustomBlockOffset)
.addTranslator(MetadataType.BOOLEAN, MinecartEntity::setShowCustomBlock) .addTranslator(MetadataType.BOOLEAN, MinecartEntity::setShowCustomBlock)
.build(); .build();
@ -398,7 +368,6 @@ public final class EntityDefinitions {
.build(); .build();
MINECART_COMMAND_BLOCK = EntityDefinition.inherited(CommandBlockMinecartEntity::new, MINECART) MINECART_COMMAND_BLOCK = EntityDefinition.inherited(CommandBlockMinecartEntity::new, MINECART)
.type(EntityType.MINECART_COMMAND_BLOCK) .type(EntityType.MINECART_COMMAND_BLOCK)
.bedrockId(100)
.identifier("minecraft:command_block_minecart") .identifier("minecraft:command_block_minecart")
.addTranslator(MetadataType.STRING, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.COMMAND_BLOCK_COMMAND, entityMetadata.getValue())) .addTranslator(MetadataType.STRING, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.COMMAND_BLOCK_COMMAND, entityMetadata.getValue()))
.<Component>addTranslator(MetadataType.CHAT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.COMMAND_BLOCK_LAST_OUTPUT, MessageTranslator.convertMessage(entityMetadata.getValue()))) .<Component>addTranslator(MetadataType.CHAT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.COMMAND_BLOCK_LAST_OUTPUT, MessageTranslator.convertMessage(entityMetadata.getValue())))
@ -423,30 +392,27 @@ public final class EntityDefinitions {
WITHER_SKULL = EntityDefinition.inherited(WitherSkullEntity::new, entityBase) WITHER_SKULL = EntityDefinition.inherited(WitherSkullEntity::new, entityBase)
.type(EntityType.WITHER_SKULL) .type(EntityType.WITHER_SKULL)
.bedrockId(89)
.heightAndWidth(0.3125f) .heightAndWidth(0.3125f)
.addTranslator(MetadataType.BOOLEAN, WitherSkullEntity::setDangerous) .addTranslator(MetadataType.BOOLEAN, WitherSkullEntity::setDangerous)
.build(); .build();
WITHER_SKULL_DANGEROUS = EntityDefinition.inherited(WITHER_SKULL.factory(), WITHER_SKULL) WITHER_SKULL_DANGEROUS = EntityDefinition.inherited(WITHER_SKULL.factory(), WITHER_SKULL)
.bedrockId(91)
.build(false); .build(false);
} }
EntityDefinition<LivingEntity> livingEntityBase = EntityDefinition.inherited(LivingEntity::new, entityBase) EntityDefinition<LivingEntity> livingEntityBase = EntityDefinition.inherited(LivingEntity::new, entityBase)
.addTranslator(MetadataType.BYTE, LivingEntity::setLivingEntityFlags) .addTranslator(MetadataType.BYTE, LivingEntity::setLivingEntityFlags)
.addTranslator(MetadataType.FLOAT, LivingEntity::setHealth) .addTranslator(MetadataType.FLOAT, LivingEntity::setHealth)
.<Float>addTranslator(MetadataType.FLOAT, .<Float>addTranslator(MetadataType.INT,
(livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityData.EFFECT_COLOR, entityMetadata.getValue())) (livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityData.EFFECT_COLOR, entityMetadata.getValue()))
.<Boolean>addTranslator(MetadataType.BOOLEAN, .<Boolean>addTranslator(MetadataType.BOOLEAN,
(livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityData.EFFECT_AMBIENT, (byte) (((BooleanEntityMetadata) entityMetadata).getPrimitiveValue() ? 1 : 0))) (livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityData.EFFECT_AMBIENT, (byte) (((BooleanEntityMetadata) entityMetadata).getPrimitiveValue() ? 1 : 0)))
.addTranslator(null) // Arrow count .addTranslator(null) // Arrow count
.addTranslator(null) // Stinger count .addTranslator(null) // Stinger count
.addTranslator(MetadataType.POSITION, LivingEntity::setBedPosition) .addTranslator(MetadataType.OPTIONAL_POSITION, LivingEntity::setBedPosition)
.build(); .build();
ARMOR_STAND = EntityDefinition.inherited(ArmorStandEntity::new, livingEntityBase) ARMOR_STAND = EntityDefinition.inherited(ArmorStandEntity::new, livingEntityBase)
.type(EntityType.ARMOR_STAND) .type(EntityType.ARMOR_STAND)
.bedrockId(61)
.height(1.975f).width(0.5f) .height(1.975f).width(0.5f)
.addTranslator(MetadataType.BYTE, ArmorStandEntity::setArmorStandFlags) .addTranslator(MetadataType.BYTE, ArmorStandEntity::setArmorStandFlags)
.addTranslator(MetadataType.ROTATION, ArmorStandEntity::setHeadRotation) .addTranslator(MetadataType.ROTATION, ArmorStandEntity::setHeadRotation)
@ -458,7 +424,6 @@ public final class EntityDefinitions {
.build(); .build();
PLAYER = EntityDefinition.<PlayerEntity>inherited(null, livingEntityBase) PLAYER = EntityDefinition.<PlayerEntity>inherited(null, livingEntityBase)
.type(EntityType.PLAYER) .type(EntityType.PLAYER)
.bedrockId(63)
.height(1.8f).width(0.6f) .height(1.8f).width(0.6f)
.offset(1.62f) .offset(1.62f)
.addTranslator(MetadataType.FLOAT, PlayerEntity::setAbsorptionHearts) .addTranslator(MetadataType.FLOAT, PlayerEntity::setAbsorptionHearts)
@ -477,24 +442,20 @@ public final class EntityDefinitions {
{ {
BAT = EntityDefinition.inherited(BatEntity::new, mobEntityBase) BAT = EntityDefinition.inherited(BatEntity::new, mobEntityBase)
.type(EntityType.BAT) .type(EntityType.BAT)
.bedrockId(19)
.height(0.9f).width(0.5f) .height(0.9f).width(0.5f)
.addTranslator(MetadataType.BYTE, BatEntity::setBatFlags) .addTranslator(MetadataType.BYTE, BatEntity::setBatFlags)
.build(); .build();
BLAZE = EntityDefinition.inherited(BlazeEntity::new, mobEntityBase) BLAZE = EntityDefinition.inherited(BlazeEntity::new, mobEntityBase)
.type(EntityType.BLAZE) .type(EntityType.BLAZE)
.bedrockId(43)
.height(1.8f).width(0.6f) .height(1.8f).width(0.6f)
.addTranslator(MetadataType.BYTE, BlazeEntity::setBlazeFlags) .addTranslator(MetadataType.BYTE, BlazeEntity::setBlazeFlags)
.build(); .build();
CAVE_SPIDER = EntityDefinition.inherited(MonsterEntity::new, mobEntityBase) CAVE_SPIDER = EntityDefinition.inherited(MonsterEntity::new, mobEntityBase)
.type(EntityType.CAVE_SPIDER) .type(EntityType.CAVE_SPIDER)
.bedrockId(40)
.height(0.5f).width(0.7f) .height(0.5f).width(0.7f)
.build(); .build();
CREEPER = EntityDefinition.inherited(CreeperEntity::new, mobEntityBase) CREEPER = EntityDefinition.inherited(CreeperEntity::new, mobEntityBase)
.type(EntityType.CREEPER) .type(EntityType.CREEPER)
.bedrockId(33)
.height(1.7f).width(0.6f) .height(1.7f).width(0.6f)
.offset(1.62f) .offset(1.62f)
.addTranslator(MetadataType.INT, CreeperEntity::setSwelling) .addTranslator(MetadataType.INT, CreeperEntity::setSwelling)
@ -503,7 +464,6 @@ public final class EntityDefinitions {
.build(); .build();
DOLPHIN = EntityDefinition.inherited(WaterEntity::new, mobEntityBase) DOLPHIN = EntityDefinition.inherited(WaterEntity::new, mobEntityBase)
.type(EntityType.DOLPHIN) .type(EntityType.DOLPHIN)
.bedrockId(31)
.height(0.6f).width(0.9f) .height(0.6f).width(0.9f)
//TODO check //TODO check
.addTranslator(null) // treasure position .addTranslator(null) // treasure position
@ -512,7 +472,6 @@ public final class EntityDefinitions {
.build(); .build();
ENDERMAN = EntityDefinition.inherited(EndermanEntity::new, mobEntityBase) ENDERMAN = EntityDefinition.inherited(EndermanEntity::new, mobEntityBase)
.type(EntityType.ENDERMAN) .type(EntityType.ENDERMAN)
.bedrockId(38)
.height(2.9f).width(0.6f) .height(2.9f).width(0.6f)
.addTranslator(MetadataType.BLOCK_STATE, EndermanEntity::setCarriedBlock) .addTranslator(MetadataType.BLOCK_STATE, EndermanEntity::setCarriedBlock)
.addTranslator(MetadataType.BOOLEAN, EndermanEntity::setScreaming) .addTranslator(MetadataType.BOOLEAN, EndermanEntity::setScreaming)
@ -520,47 +479,40 @@ public final class EntityDefinitions {
.build(); .build();
ENDERMITE = EntityDefinition.inherited(MonsterEntity::new, mobEntityBase) ENDERMITE = EntityDefinition.inherited(MonsterEntity::new, mobEntityBase)
.type(EntityType.ENDERMITE) .type(EntityType.ENDERMITE)
.bedrockId(55)
.height(0.3f).width(0.4f) .height(0.3f).width(0.4f)
.build(); .build();
ENDER_DRAGON = EntityDefinition.inherited(EnderDragonEntity::new, mobEntityBase) ENDER_DRAGON = EntityDefinition.inherited(EnderDragonEntity::new, mobEntityBase)
.type(EntityType.ENDER_DRAGON) .type(EntityType.ENDER_DRAGON)
.bedrockId(53)
.addTranslator(MetadataType.INT, EnderDragonEntity::setPhase) .addTranslator(MetadataType.INT, EnderDragonEntity::setPhase)
.build(); .build();
GHAST = EntityDefinition.inherited(GhastEntity::new, mobEntityBase) GHAST = EntityDefinition.inherited(GhastEntity::new, mobEntityBase)
.type(EntityType.GHAST) .type(EntityType.GHAST)
.bedrockId(41)
.heightAndWidth(4.0f) .heightAndWidth(4.0f)
.addTranslator(MetadataType.BOOLEAN, GhastEntity::setGhastAttacking) .addTranslator(MetadataType.BOOLEAN, GhastEntity::setGhastAttacking)
.build(); .build();
GIANT = EntityDefinition.inherited(GiantEntity::new, mobEntityBase) GIANT = EntityDefinition.inherited(GiantEntity::new, mobEntityBase)
.type(EntityType.GIANT) .type(EntityType.GIANT)
.bedrockId(32)
.height(1.8f).width(1.6f) .height(1.8f).width(1.6f)
.offset(1.62f) .offset(1.62f)
.identifier("minecraft:zombie") .identifier("minecraft:zombie")
.build(); .build();
IRON_GOLEM = EntityDefinition.inherited(IronGolemEntity::new, mobEntityBase) IRON_GOLEM = EntityDefinition.inherited(IronGolemEntity::new, mobEntityBase)
.type(EntityType.IRON_GOLEM) .type(EntityType.IRON_GOLEM)
.bedrockId(20)
.height(2.7f).width(1.4f) .height(2.7f).width(1.4f)
.addTranslator(null) // "is player created", which doesn't seem to do anything clientside
.build(); .build();
PHANTOM = EntityDefinition.inherited(PhantomEntity::new, mobEntityBase) PHANTOM = EntityDefinition.inherited(PhantomEntity::new, mobEntityBase)
.type(EntityType.PHANTOM) .type(EntityType.PHANTOM)
.bedrockId(58)
.height(0.5f).width(0.9f) .height(0.5f).width(0.9f)
.offset(0.6f) .offset(0.6f)
.addTranslator(MetadataType.INT, PhantomEntity::setPhantomScale) .addTranslator(MetadataType.INT, PhantomEntity::setPhantomScale)
.build(); .build();
SILVERFISH = EntityDefinition.inherited(MonsterEntity::new, mobEntityBase) SILVERFISH = EntityDefinition.inherited(MonsterEntity::new, mobEntityBase)
.type(EntityType.SILVERFISH) .type(EntityType.SILVERFISH)
.bedrockId(39)
.height(0.3f).width(0.4f) .height(0.3f).width(0.4f)
.build(); .build();
SHULKER = EntityDefinition.inherited(ShulkerEntity::new, mobEntityBase) SHULKER = EntityDefinition.inherited(ShulkerEntity::new, mobEntityBase)
.type(EntityType.SHULKER) .type(EntityType.SHULKER)
.bedrockId(54)
.heightAndWidth(1f) .heightAndWidth(1f)
.addTranslator(MetadataType.DIRECTION, ShulkerEntity::setAttachedFace) .addTranslator(MetadataType.DIRECTION, ShulkerEntity::setAttachedFace)
.addTranslator(MetadataType.BYTE, ShulkerEntity::setShulkerHeight) .addTranslator(MetadataType.BYTE, ShulkerEntity::setShulkerHeight)
@ -568,44 +520,37 @@ public final class EntityDefinitions {
.build(); .build();
SKELETON = EntityDefinition.inherited(SkeletonEntity::new, mobEntityBase) SKELETON = EntityDefinition.inherited(SkeletonEntity::new, mobEntityBase)
.type(EntityType.SKELETON) .type(EntityType.SKELETON)
.bedrockId(34)
.height(1.8f).width(0.6f) .height(1.8f).width(0.6f)
.offset(1.62f) .offset(1.62f)
.addTranslator(MetadataType.BOOLEAN, SkeletonEntity::setConvertingToStray) .addTranslator(MetadataType.BOOLEAN, SkeletonEntity::setConvertingToStray)
.build(); .build();
SNOW_GOLEM = EntityDefinition.inherited(SnowGolemEntity::new, mobEntityBase) SNOW_GOLEM = EntityDefinition.inherited(SnowGolemEntity::new, mobEntityBase)
.type(EntityType.SNOW_GOLEM) .type(EntityType.SNOW_GOLEM)
.bedrockId(21)
.height(1.9f).width(0.7f) .height(1.9f).width(0.7f)
.addTranslator(MetadataType.BYTE, SnowGolemEntity::setSnowGolemFlags) .addTranslator(MetadataType.BYTE, SnowGolemEntity::setSnowGolemFlags)
.build(); .build();
SPIDER = EntityDefinition.inherited(SpiderEntity::new, mobEntityBase) SPIDER = EntityDefinition.inherited(SpiderEntity::new, mobEntityBase)
.type(EntityType.SPIDER) .type(EntityType.SPIDER)
.bedrockId(35)
.height(0.9f).width(1.4f) .height(0.9f).width(1.4f)
.offset(1f) .offset(1f)
.addTranslator(MetadataType.BYTE, SpiderEntity::setSpiderFlags) .addTranslator(MetadataType.BYTE, SpiderEntity::setSpiderFlags)
.build(); .build();
SQUID = EntityDefinition.inherited(SquidEntity::new, mobEntityBase) SQUID = EntityDefinition.inherited(SquidEntity::new, mobEntityBase)
.type(EntityType.SQUID) .type(EntityType.SQUID)
.bedrockId(17)
.heightAndWidth(0.8f) .heightAndWidth(0.8f)
.build(); .build();
STRAY = EntityDefinition.inherited(AbstractSkeletonEntity::new, mobEntityBase) STRAY = EntityDefinition.inherited(AbstractSkeletonEntity::new, mobEntityBase)
.type(EntityType.STRAY) .type(EntityType.STRAY)
.bedrockId(46)
.height(1.8f).width(0.6f) .height(1.8f).width(0.6f)
.offset(1.62f) .offset(1.62f)
.build(); .build();
VEX = EntityDefinition.inherited(VexEntity::new, mobEntityBase) VEX = EntityDefinition.inherited(VexEntity::new, mobEntityBase)
.type(EntityType.VEX) .type(EntityType.VEX)
.bedrockId(105)
.height(0.8f).width(0.4f) .height(0.8f).width(0.4f)
.addTranslator(MetadataType.BYTE, VexEntity::setVexFlags) .addTranslator(MetadataType.BYTE, VexEntity::setVexFlags)
.build(); .build();
WITHER = EntityDefinition.inherited(WitherEntity::new, mobEntityBase) WITHER = EntityDefinition.inherited(WitherEntity::new, mobEntityBase)
.type(EntityType.WITHER) .type(EntityType.WITHER)
.bedrockId(52)
.height(3.5f).width(0.9f) .height(3.5f).width(0.9f)
.addTranslator(MetadataType.INT, WitherEntity::setTarget1) .addTranslator(MetadataType.INT, WitherEntity::setTarget1)
.addTranslator(MetadataType.INT, WitherEntity::setTarget2) .addTranslator(MetadataType.INT, WitherEntity::setTarget2)
@ -614,18 +559,15 @@ public final class EntityDefinitions {
.build(); .build();
WITHER_SKELETON = EntityDefinition.inherited(AbstractSkeletonEntity::new, mobEntityBase) WITHER_SKELETON = EntityDefinition.inherited(AbstractSkeletonEntity::new, mobEntityBase)
.type(EntityType.WITHER_SKELETON) .type(EntityType.WITHER_SKELETON)
.bedrockId(48)
.height(2.4f).width(0.7f) .height(2.4f).width(0.7f)
.build(); .build();
ZOGLIN = EntityDefinition.inherited(ZoglinEntity::new, mobEntityBase) ZOGLIN = EntityDefinition.inherited(ZoglinEntity::new, mobEntityBase)
.type(EntityType.ZOGLIN) .type(EntityType.ZOGLIN)
.bedrockId(126)
.height(1.4f).width(1.3965f) .height(1.4f).width(1.3965f)
.addTranslator(MetadataType.BOOLEAN, ZoglinEntity::setBaby) .addTranslator(MetadataType.BOOLEAN, ZoglinEntity::setBaby)
.build(); .build();
ZOMBIE = EntityDefinition.inherited(ZombieEntity::new, mobEntityBase) ZOMBIE = EntityDefinition.inherited(ZombieEntity::new, mobEntityBase)
.type(EntityType.ZOMBIE) .type(EntityType.ZOMBIE)
.bedrockId(32)
.height(1.8f).width(0.6f) .height(1.8f).width(0.6f)
.offset(1.62f) .offset(1.62f)
.addTranslator(MetadataType.BOOLEAN, ZombieEntity::setZombieBaby) .addTranslator(MetadataType.BOOLEAN, ZombieEntity::setZombieBaby)
@ -634,7 +576,6 @@ public final class EntityDefinitions {
.build(); .build();
ZOMBIE_VILLAGER = EntityDefinition.inherited(ZombieVillagerEntity::new, ZOMBIE) ZOMBIE_VILLAGER = EntityDefinition.inherited(ZombieVillagerEntity::new, ZOMBIE)
.type(EntityType.ZOMBIE_VILLAGER) .type(EntityType.ZOMBIE_VILLAGER)
.bedrockId(44)
.height(1.8f).width(0.6f) .height(1.8f).width(0.6f)
.offset(1.62f) .offset(1.62f)
.identifier("minecraft:zombie_villager_v2") .identifier("minecraft:zombie_villager_v2")
@ -643,7 +584,6 @@ public final class EntityDefinitions {
.build(); .build();
ZOMBIFIED_PIGLIN = EntityDefinition.inherited(ZombifiedPiglinEntity::new, ZOMBIE) //TODO test how zombie entity metadata is handled? ZOMBIFIED_PIGLIN = EntityDefinition.inherited(ZombifiedPiglinEntity::new, ZOMBIE) //TODO test how zombie entity metadata is handled?
.type(EntityType.ZOMBIFIED_PIGLIN) .type(EntityType.ZOMBIFIED_PIGLIN)
.bedrockId(36)
.height(1.95f).width(0.6f) .height(1.95f).width(0.6f)
.offset(1.62f) .offset(1.62f)
.identifier("minecraft:zombie_pigman") .identifier("minecraft:zombie_pigman")
@ -651,36 +591,30 @@ public final class EntityDefinitions {
DROWNED = EntityDefinition.inherited(ZOMBIE.factory(), ZOMBIE) DROWNED = EntityDefinition.inherited(ZOMBIE.factory(), ZOMBIE)
.type(EntityType.DROWNED) .type(EntityType.DROWNED)
.bedrockId(110)
.height(1.95f).width(0.6f) .height(1.95f).width(0.6f)
.build(); .build();
HUSK = EntityDefinition.inherited(ZOMBIE.factory(), ZOMBIE) HUSK = EntityDefinition.inherited(ZOMBIE.factory(), ZOMBIE)
.type(EntityType.HUSK) .type(EntityType.HUSK)
.bedrockId(47)
.build(); .build();
GUARDIAN = EntityDefinition.inherited(GuardianEntity::new, mobEntityBase) GUARDIAN = EntityDefinition.inherited(GuardianEntity::new, mobEntityBase)
.type(EntityType.GUARDIAN) .type(EntityType.GUARDIAN)
.bedrockId(49)
.heightAndWidth(0.85f) .heightAndWidth(0.85f)
.addTranslator(null) // Moving //TODO .addTranslator(null) // Moving //TODO
.addTranslator(MetadataType.INT, GuardianEntity::setGuardianTarget) .addTranslator(MetadataType.INT, GuardianEntity::setGuardianTarget)
.build(); .build();
ELDER_GUARDIAN = EntityDefinition.inherited(ElderGuardianEntity::new, GUARDIAN) ELDER_GUARDIAN = EntityDefinition.inherited(ElderGuardianEntity::new, GUARDIAN)
.type(EntityType.ELDER_GUARDIAN) .type(EntityType.ELDER_GUARDIAN)
.bedrockId(50)
.heightAndWidth(1.9975f) .heightAndWidth(1.9975f)
.build(); .build();
SLIME = EntityDefinition.inherited(SlimeEntity::new, mobEntityBase) SLIME = EntityDefinition.inherited(SlimeEntity::new, mobEntityBase)
.type(EntityType.SLIME) .type(EntityType.SLIME)
.bedrockId(37)
.heightAndWidth(0.51f) .heightAndWidth(0.51f)
.addTranslator(MetadataType.INT, SlimeEntity::setScale) .addTranslator(MetadataType.INT, SlimeEntity::setScale)
.build(); .build();
MAGMA_CUBE = EntityDefinition.inherited(MagmaCubeEntity::new, SLIME) MAGMA_CUBE = EntityDefinition.inherited(MagmaCubeEntity::new, SLIME)
.type(EntityType.MAGMA_CUBE) .type(EntityType.MAGMA_CUBE)
.bedrockId(42)
.build(); .build();
EntityDefinition<AbstractFishEntity> abstractFishEntityBase = EntityDefinition.inherited(AbstractFishEntity::new, mobEntityBase) EntityDefinition<AbstractFishEntity> abstractFishEntityBase = EntityDefinition.inherited(AbstractFishEntity::new, mobEntityBase)
@ -688,25 +622,22 @@ public final class EntityDefinitions {
.build(); .build();
COD = EntityDefinition.inherited(abstractFishEntityBase.factory(), abstractFishEntityBase) COD = EntityDefinition.inherited(abstractFishEntityBase.factory(), abstractFishEntityBase)
.type(EntityType.COD) .type(EntityType.COD)
.bedrockId(112)
.height(0.25f).width(0.5f) .height(0.25f).width(0.5f)
.build(); .build();
PUFFERFISH = EntityDefinition.inherited(PufferFishEntity::new, abstractFishEntityBase) PUFFERFISH = EntityDefinition.inherited(PufferFishEntity::new, abstractFishEntityBase)
.type(EntityType.PUFFERFISH) .type(EntityType.PUFFERFISH)
.bedrockId(108)
.heightAndWidth(0.7f) .heightAndWidth(0.7f)
.addTranslator(MetadataType.INT, PufferFishEntity::setPufferfishSize) .addTranslator(MetadataType.INT, PufferFishEntity::setPufferfishSize)
.build(); .build();
SALMON = EntityDefinition.inherited(abstractFishEntityBase.factory(), abstractFishEntityBase) SALMON = EntityDefinition.inherited(abstractFishEntityBase.factory(), abstractFishEntityBase)
.type(EntityType.SALMON) .type(EntityType.SALMON)
.bedrockId(109)
.height(0.5f).width(0.7f) .height(0.5f).width(0.7f)
.build(); .build();
TROPICAL_FISH = EntityDefinition.inherited(TropicalFishEntity::new, abstractFishEntityBase) TROPICAL_FISH = EntityDefinition.inherited(TropicalFishEntity::new, abstractFishEntityBase)
.type(EntityType.TROPICAL_FISH) .type(EntityType.TROPICAL_FISH)
.bedrockId(111)
.heightAndWidth(0.6f) .heightAndWidth(0.6f)
.identifier("minecraft:tropicalfish") .identifier("minecraft:tropicalfish")
.addTranslator(MetadataType.INT, TropicalFishEntity::setFishVariant)
.build(); .build();
EntityDefinition<BasePiglinEntity> abstractPiglinEntityBase = EntityDefinition.inherited(BasePiglinEntity::new, mobEntityBase) EntityDefinition<BasePiglinEntity> abstractPiglinEntityBase = EntityDefinition.inherited(BasePiglinEntity::new, mobEntityBase)
@ -714,7 +645,6 @@ public final class EntityDefinitions {
.build(); .build();
PIGLIN = EntityDefinition.inherited(PiglinEntity::new, abstractPiglinEntityBase) PIGLIN = EntityDefinition.inherited(PiglinEntity::new, abstractPiglinEntityBase)
.type(EntityType.PIGLIN) .type(EntityType.PIGLIN)
.bedrockId(123)
.height(1.95f).width(0.6f) .height(1.95f).width(0.6f)
.addTranslator(MetadataType.BOOLEAN, PiglinEntity::setBaby) .addTranslator(MetadataType.BOOLEAN, PiglinEntity::setBaby)
.addTranslator(MetadataType.BOOLEAN, PiglinEntity::setChargingCrossbow) .addTranslator(MetadataType.BOOLEAN, PiglinEntity::setChargingCrossbow)
@ -722,7 +652,6 @@ public final class EntityDefinitions {
.build(); .build();
PIGLIN_BRUTE = EntityDefinition.inherited(abstractPiglinEntityBase.factory(), abstractPiglinEntityBase) PIGLIN_BRUTE = EntityDefinition.inherited(abstractPiglinEntityBase.factory(), abstractPiglinEntityBase)
.type(EntityType.PIGLIN_BRUTE) .type(EntityType.PIGLIN_BRUTE)
.bedrockId(127)
.height(1.95f).width(0.6f) .height(1.95f).width(0.6f)
.build(); .build();
@ -739,37 +668,31 @@ public final class EntityDefinitions {
.build(); .build();
EVOKER = EntityDefinition.inherited(spellcasterEntityBase.factory(), spellcasterEntityBase) EVOKER = EntityDefinition.inherited(spellcasterEntityBase.factory(), spellcasterEntityBase)
.type(EntityType.EVOKER) .type(EntityType.EVOKER)
.bedrockId(104)
.height(1.95f).width(0.6f) .height(1.95f).width(0.6f)
.identifier("minecraft:evocation_illager") .identifier("minecraft:evocation_illager")
.build(); .build();
ILLUSIONER = EntityDefinition.inherited(spellcasterEntityBase.factory(), spellcasterEntityBase) ILLUSIONER = EntityDefinition.inherited(spellcasterEntityBase.factory(), spellcasterEntityBase)
.type(EntityType.ILLUSIONER) .type(EntityType.ILLUSIONER)
.bedrockId(104)
.height(1.95f).width(0.6f) .height(1.95f).width(0.6f)
.identifier("minecraft:evocation_illager") .identifier("minecraft:evocation_illager")
.build(); .build();
PILLAGER = EntityDefinition.inherited(PillagerEntity::new, raidParticipantEntityBase) PILLAGER = EntityDefinition.inherited(PillagerEntity::new, raidParticipantEntityBase)
.type(EntityType.PILLAGER) .type(EntityType.PILLAGER)
.bedrockId(114)
.height(1.8f).width(0.6f) .height(1.8f).width(0.6f)
.offset(1.62f) .offset(1.62f)
.addTranslator(null) // Charging; doesn't have an equivalent on Bedrock //TODO check .addTranslator(null) // Charging; doesn't have an equivalent on Bedrock //TODO check
.build(); .build();
RAVAGER = EntityDefinition.inherited(raidParticipantEntityBase.factory(), raidParticipantEntityBase) RAVAGER = EntityDefinition.inherited(raidParticipantEntityBase.factory(), raidParticipantEntityBase)
.type(EntityType.RAVAGER) .type(EntityType.RAVAGER)
.bedrockId(59)
.height(1.9f).width(1.2f) .height(1.9f).width(1.2f)
.build(); .build();
VINDICATOR = EntityDefinition.inherited(VindicatorEntity::new, raidParticipantEntityBase) VINDICATOR = EntityDefinition.inherited(VindicatorEntity::new, raidParticipantEntityBase)
.type(EntityType.VINDICATOR) .type(EntityType.VINDICATOR)
.bedrockId(57)
.height(1.8f).width(0.6f) .height(1.8f).width(0.6f)
.offset(1.62f) .offset(1.62f)
.build(); .build();
WITCH = EntityDefinition.inherited(raidParticipantEntityBase.factory(), raidParticipantEntityBase) WITCH = EntityDefinition.inherited(raidParticipantEntityBase.factory(), raidParticipantEntityBase)
.type(EntityType.WITCH) .type(EntityType.WITCH)
.bedrockId(45)
.height(1.8f).width(0.6f) .height(1.8f).width(0.6f)
.offset(1.62f) .offset(1.62f)
.build(); .build();
@ -786,34 +709,30 @@ public final class EntityDefinitions {
.height(0.42f).width(0.7f) .height(0.42f).width(0.7f)
.addTranslator(MetadataType.INT, AxolotlEntity::setVariant) .addTranslator(MetadataType.INT, AxolotlEntity::setVariant)
.addTranslator(MetadataType.BOOLEAN, AxolotlEntity::setPlayingDead) .addTranslator(MetadataType.BOOLEAN, AxolotlEntity::setPlayingDead)
.addTranslator(null) // From bucket
.build(); .build();
BEE = EntityDefinition.inherited(BeeEntity::new, ageableEntityBase) BEE = EntityDefinition.inherited(BeeEntity::new, ageableEntityBase)
.type(EntityType.BEE) .type(EntityType.BEE)
.bedrockId(122)
.heightAndWidth(0.6f) .heightAndWidth(0.6f)
.addTranslator(MetadataType.BYTE, BeeEntity::setBeeFlags) .addTranslator(MetadataType.BYTE, BeeEntity::setBeeFlags)
.addTranslator(MetadataType.INT, BeeEntity::setAngerTime) .addTranslator(MetadataType.INT, BeeEntity::setAngerTime)
.build(); .build();
CHICKEN = EntityDefinition.inherited(ChickenEntity::new, ageableEntityBase) CHICKEN = EntityDefinition.inherited(ChickenEntity::new, ageableEntityBase)
.type(EntityType.CHICKEN) .type(EntityType.CHICKEN)
.bedrockId(10)
.height(0.7f).width(0.4f) .height(0.7f).width(0.4f)
.build(); .build();
COW = EntityDefinition.inherited(AnimalEntity::new, ageableEntityBase) COW = EntityDefinition.inherited(AnimalEntity::new, ageableEntityBase)
.type(EntityType.COW) .type(EntityType.COW)
.bedrockId(11)
.height(1.4f).width(0.9f) .height(1.4f).width(0.9f)
.build(); .build();
FOX = EntityDefinition.inherited(FoxEntity::new, ageableEntityBase) FOX = EntityDefinition.inherited(FoxEntity::new, ageableEntityBase)
.type(EntityType.FOX) .type(EntityType.FOX)
.bedrockId(121)
.height(0.5f).width(1.25f) .height(0.5f).width(1.25f)
.addTranslator(MetadataType.INT, FoxEntity::setFoxVariant) .addTranslator(MetadataType.INT, FoxEntity::setFoxVariant)
.addTranslator(MetadataType.BYTE, FoxEntity::setFoxFlags) .addTranslator(MetadataType.BYTE, FoxEntity::setFoxFlags)
.build(); .build();
HOGLIN = EntityDefinition.inherited(HoglinEntity::new, ageableEntityBase) HOGLIN = EntityDefinition.inherited(HoglinEntity::new, ageableEntityBase)
.type(EntityType.HOGLIN) .type(EntityType.HOGLIN)
.bedrockId(124)
.height(1.4f).width(1.3965f) .height(1.4f).width(1.3965f)
.addTranslator(MetadataType.BOOLEAN, HoglinEntity::setImmuneToZombification) .addTranslator(MetadataType.BOOLEAN, HoglinEntity::setImmuneToZombification)
.build(); .build();
@ -824,19 +743,16 @@ public final class EntityDefinitions {
.build(); .build();
MOOSHROOM = EntityDefinition.inherited(MooshroomEntity::new, ageableEntityBase) // TODO remove class MOOSHROOM = EntityDefinition.inherited(MooshroomEntity::new, ageableEntityBase) // TODO remove class
.type(EntityType.MOOSHROOM) .type(EntityType.MOOSHROOM)
.bedrockId(16)
.height(1.4f).width(0.9f) .height(1.4f).width(0.9f)
.<String>addTranslator(MetadataType.STRING, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.VARIANT, entityMetadata.getValue().equals("brown") ? 1 : 0)) .<String>addTranslator(MetadataType.STRING, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.VARIANT, entityMetadata.getValue().equals("brown") ? 1 : 0))
.build(); .build();
OCELOT = EntityDefinition.inherited(OcelotEntity::new, ageableEntityBase) OCELOT = EntityDefinition.inherited(OcelotEntity::new, ageableEntityBase)
.type(EntityType.OCELOT) .type(EntityType.OCELOT)
.bedrockId(22)
.height(0.35f).width(0.3f) .height(0.35f).width(0.3f)
.<Boolean>addTranslator(MetadataType.BOOLEAN, (ocelotEntity, entityMetadata) -> ocelotEntity.setFlag(EntityFlag.TRUSTING, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue())) .<Boolean>addTranslator(MetadataType.BOOLEAN, (ocelotEntity, entityMetadata) -> ocelotEntity.setFlag(EntityFlag.TRUSTING, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
.build(); .build();
PANDA = EntityDefinition.inherited(PandaEntity::new, ageableEntityBase) PANDA = EntityDefinition.inherited(PandaEntity::new, ageableEntityBase)
.type(EntityType.PANDA) .type(EntityType.PANDA)
.bedrockId(113)
.height(1.25f).width(1.125f) .height(1.25f).width(1.125f)
.addTranslator(null) // Unhappy counter .addTranslator(null) // Unhappy counter
.addTranslator(null) // Sneeze counter .addTranslator(null) // Sneeze counter
@ -847,32 +763,27 @@ public final class EntityDefinitions {
.build(); .build();
PIG = EntityDefinition.inherited(PigEntity::new, ageableEntityBase) PIG = EntityDefinition.inherited(PigEntity::new, ageableEntityBase)
.type(EntityType.PIG) .type(EntityType.PIG)
.bedrockId(12)
.heightAndWidth(0.9f) .heightAndWidth(0.9f)
.<Boolean>addTranslator(MetadataType.BOOLEAN, (pigEntity, entityMetadata) -> pigEntity.setFlag(EntityFlag.SADDLED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue())) .<Boolean>addTranslator(MetadataType.BOOLEAN, (pigEntity, entityMetadata) -> pigEntity.setFlag(EntityFlag.SADDLED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
.addTranslator(null) // Boost time .addTranslator(null) // Boost time
.build(); .build();
POLAR_BEAR = EntityDefinition.inherited(PolarBearEntity::new, ageableEntityBase) POLAR_BEAR = EntityDefinition.inherited(PolarBearEntity::new, ageableEntityBase)
.type(EntityType.POLAR_BEAR) .type(EntityType.POLAR_BEAR)
.bedrockId(28)
.height(1.4f).width(1.3f) .height(1.4f).width(1.3f)
.<Boolean>addTranslator(MetadataType.BOOLEAN, (entity, entityMetadata) -> entity.setFlag(EntityFlag.STANDING, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue())) .<Boolean>addTranslator(MetadataType.BOOLEAN, (entity, entityMetadata) -> entity.setFlag(EntityFlag.STANDING, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
.build(); .build();
RABBIT = EntityDefinition.inherited(RabbitEntity::new, ageableEntityBase) RABBIT = EntityDefinition.inherited(RabbitEntity::new, ageableEntityBase)
.type(EntityType.RABBIT) .type(EntityType.RABBIT)
.bedrockId(18)
.height(0.5f).width(0.4f) .height(0.5f).width(0.4f)
.addTranslator(MetadataType.INT, RabbitEntity::setRabbitVariant) .addTranslator(MetadataType.INT, RabbitEntity::setRabbitVariant)
.build(); .build();
SHEEP = EntityDefinition.inherited(SheepEntity::new, ageableEntityBase) SHEEP = EntityDefinition.inherited(SheepEntity::new, ageableEntityBase)
.type(EntityType.SHEEP) .type(EntityType.SHEEP)
.bedrockId(13)
.heightAndWidth(0.9f) .heightAndWidth(0.9f)
.addTranslator(MetadataType.BYTE, SheepEntity::setSheepFlags) .addTranslator(MetadataType.BYTE, SheepEntity::setSheepFlags)
.build(); .build();
STRIDER = EntityDefinition.inherited(StriderEntity::new, ageableEntityBase) STRIDER = EntityDefinition.inherited(StriderEntity::new, ageableEntityBase)
.type(EntityType.STRIDER) .type(EntityType.STRIDER)
.bedrockId(125)
.height(1.7f).width(0.9f) .height(1.7f).width(0.9f)
.addTranslator(null) // Boost time .addTranslator(null) // Boost time
.addTranslator(MetadataType.BOOLEAN, StriderEntity::setCold) .addTranslator(MetadataType.BOOLEAN, StriderEntity::setCold)
@ -880,7 +791,6 @@ public final class EntityDefinitions {
.build(); .build();
TURTLE = EntityDefinition.inherited(TurtleEntity::new, ageableEntityBase) TURTLE = EntityDefinition.inherited(TurtleEntity::new, ageableEntityBase)
.type(EntityType.TURTLE) .type(EntityType.TURTLE)
.bedrockId(74)
.height(0.4f).width(1.2f) .height(0.4f).width(1.2f)
.addTranslator(MetadataType.BOOLEAN, TurtleEntity::setPregnant) .addTranslator(MetadataType.BOOLEAN, TurtleEntity::setPregnant)
.addTranslator(MetadataType.BOOLEAN, TurtleEntity::setLayingEgg) .addTranslator(MetadataType.BOOLEAN, TurtleEntity::setLayingEgg)
@ -891,7 +801,6 @@ public final class EntityDefinitions {
.build(); .build();
VILLAGER = EntityDefinition.inherited(VillagerEntity::new, abstractVillagerEntityBase) VILLAGER = EntityDefinition.inherited(VillagerEntity::new, abstractVillagerEntityBase)
.type(EntityType.VILLAGER) .type(EntityType.VILLAGER)
.bedrockId(15)
.height(1.8f).width(0.6f) .height(1.8f).width(0.6f)
.offset(1.62f) .offset(1.62f)
.identifier("minecraft:villager_v2") .identifier("minecraft:villager_v2")
@ -899,7 +808,6 @@ public final class EntityDefinitions {
.build(); .build();
WANDERING_TRADER = EntityDefinition.inherited(abstractVillagerEntityBase.factory(), abstractVillagerEntityBase) WANDERING_TRADER = EntityDefinition.inherited(abstractVillagerEntityBase.factory(), abstractVillagerEntityBase)
.type(EntityType.WANDERING_TRADER) .type(EntityType.WANDERING_TRADER)
.bedrockId(118)
.height(1.8f).width(0.6f) .height(1.8f).width(0.6f)
.offset(1.62f) .offset(1.62f)
.build(); .build();
@ -913,18 +821,15 @@ public final class EntityDefinitions {
.build(); .build();
HORSE = EntityDefinition.inherited(HorseEntity::new, abstractHorseEntityBase) HORSE = EntityDefinition.inherited(HorseEntity::new, abstractHorseEntityBase)
.type(EntityType.HORSE) .type(EntityType.HORSE)
.bedrockId(23)
.height(1.6f).width(1.3965f) .height(1.6f).width(1.3965f)
.addTranslator(MetadataType.BYTE, HorseEntity::setHorseVariant) .addTranslator(MetadataType.INT, HorseEntity::setHorseVariant)
.build(); .build();
SKELETON_HORSE = EntityDefinition.inherited(abstractHorseEntityBase.factory(), abstractHorseEntityBase) SKELETON_HORSE = EntityDefinition.inherited(abstractHorseEntityBase.factory(), abstractHorseEntityBase)
.type(EntityType.SKELETON_HORSE) .type(EntityType.SKELETON_HORSE)
.bedrockId(26)
.height(1.6f).width(1.3965f) .height(1.6f).width(1.3965f)
.build(); .build();
ZOMBIE_HORSE = EntityDefinition.inherited(abstractHorseEntityBase.factory(), abstractHorseEntityBase) ZOMBIE_HORSE = EntityDefinition.inherited(abstractHorseEntityBase.factory(), abstractHorseEntityBase)
.type(EntityType.ZOMBIE_HORSE) .type(EntityType.ZOMBIE_HORSE)
.bedrockId(27)
.height(1.6f).width(1.3965f) .height(1.6f).width(1.3965f)
.build(); .build();
EntityDefinition<ChestedHorseEntity> chestedHorseEntityBase = EntityDefinition.inherited(ChestedHorseEntity::new, abstractHorseEntityBase) EntityDefinition<ChestedHorseEntity> chestedHorseEntityBase = EntityDefinition.inherited(ChestedHorseEntity::new, abstractHorseEntityBase)
@ -932,17 +837,14 @@ public final class EntityDefinitions {
.build(); .build();
DONKEY = EntityDefinition.inherited(chestedHorseEntityBase.factory(), chestedHorseEntityBase) DONKEY = EntityDefinition.inherited(chestedHorseEntityBase.factory(), chestedHorseEntityBase)
.type(EntityType.DONKEY) .type(EntityType.DONKEY)
.bedrockId(24)
.height(1.6f).width(1.3965f) .height(1.6f).width(1.3965f)
.build(); .build();
MULE = EntityDefinition.inherited(chestedHorseEntityBase.factory(), chestedHorseEntityBase) MULE = EntityDefinition.inherited(chestedHorseEntityBase.factory(), chestedHorseEntityBase)
.type(EntityType.MULE) .type(EntityType.MULE)
.bedrockId(25)
.height(1.6f).width(1.3965f) .height(1.6f).width(1.3965f)
.build(); .build();
LLAMA = EntityDefinition.inherited(LlamaEntity::new, chestedHorseEntityBase) LLAMA = EntityDefinition.inherited(LlamaEntity::new, chestedHorseEntityBase)
.type(EntityType.LLAMA) .type(EntityType.LLAMA)
.bedrockId(29)
.height(1.87f).width(0.9f) .height(1.87f).width(0.9f)
.<Integer>addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.STRENGTH, entityMetadata.getValue())) .<Integer>addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.STRENGTH, entityMetadata.getValue()))
.addTranslator(MetadataType.INT, LlamaEntity::setCarpetedColor) .addTranslator(MetadataType.INT, LlamaEntity::setCarpetedColor)
@ -960,7 +862,6 @@ public final class EntityDefinitions {
.build(); .build();
CAT = EntityDefinition.inherited(CatEntity::new, tameableEntityBase) CAT = EntityDefinition.inherited(CatEntity::new, tameableEntityBase)
.type(EntityType.CAT) .type(EntityType.CAT)
.bedrockId(75)
.height(0.35f).width(0.3f) .height(0.35f).width(0.3f)
.addTranslator(MetadataType.INT, CatEntity::setCatVariant) .addTranslator(MetadataType.INT, CatEntity::setCatVariant)
.addTranslator(MetadataType.BOOLEAN, CatEntity::setResting) .addTranslator(MetadataType.BOOLEAN, CatEntity::setResting)
@ -969,13 +870,11 @@ public final class EntityDefinitions {
.build(); .build();
PARROT = EntityDefinition.inherited(ParrotEntity::new, tameableEntityBase) PARROT = EntityDefinition.inherited(ParrotEntity::new, tameableEntityBase)
.type(EntityType.PARROT) .type(EntityType.PARROT)
.bedrockId(30)
.height(0.9f).width(0.5f) .height(0.9f).width(0.5f)
.addTranslator(MetadataType.INT, (parrotEntity, entityMetadata) -> parrotEntity.getDirtyMetadata().put(EntityData.VARIANT, entityMetadata.getValue())) // Parrot color .addTranslator(MetadataType.INT, (parrotEntity, entityMetadata) -> parrotEntity.getDirtyMetadata().put(EntityData.VARIANT, entityMetadata.getValue())) // Parrot color
.build(); .build();
WOLF = EntityDefinition.inherited(WolfEntity::new, tameableEntityBase) WOLF = EntityDefinition.inherited(WolfEntity::new, tameableEntityBase)
.type(EntityType.WOLF) .type(EntityType.WOLF)
.bedrockId(14)
.height(0.85f).width(0.6f) .height(0.85f).width(0.6f)
// "Begging" on wiki.vg, "Interested" in Nukkit - the tilt of the head // "Begging" on wiki.vg, "Interested" in Nukkit - the tilt of the head
.<Boolean>addTranslator(MetadataType.BOOLEAN, (wolfEntity, entityMetadata) -> wolfEntity.setFlag(EntityFlag.INTERESTED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue())) .<Boolean>addTranslator(MetadataType.BOOLEAN, (wolfEntity, entityMetadata) -> wolfEntity.setFlag(EntityFlag.INTERESTED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
@ -985,9 +884,10 @@ public final class EntityDefinitions {
// As of 1.18 these don't track entity data at all // As of 1.18 these don't track entity data at all
ENDER_DRAGON_PART = EntityDefinition.<EnderDragonPartEntity>builder(null) ENDER_DRAGON_PART = EntityDefinition.<EnderDragonPartEntity>builder(null)
.bedrockId(32)
.identifier("minecraft:armor_stand") // Emulated .identifier("minecraft:armor_stand") // Emulated
.build(); .build();
Registries.JAVA_ENTITY_IDENTIFIERS.get().put("minecraft:marker", null); // We don't need an entity definition for this as it is never sent over the network
} }
public static void init() { public static void init() {

Datei anzeigen

@ -31,6 +31,7 @@ import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData; import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.PlaySoundPacket; import com.nukkitx.protocol.bedrock.packet.PlaySoundPacket;
import lombok.Getter;
import org.geysermc.connector.entity.player.PlayerEntity; import org.geysermc.connector.entity.player.PlayerEntity;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.collision.BoundingBox; import org.geysermc.connector.network.translators.collision.BoundingBox;
@ -46,11 +47,15 @@ import java.util.concurrent.ThreadLocalRandom;
public class FishingHookEntity extends ThrowableEntity { public class FishingHookEntity extends ThrowableEntity {
private boolean hooked = false; private boolean hooked = false;
private boolean inWater = false;
@Getter
private final boolean isOwnerSessionPlayer;
@Getter
private long bedrockTargetId;
private final BoundingBox boundingBox; private final BoundingBox boundingBox;
private boolean inWater = false;
public FishingHookEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, Vector3f position, Vector3f motion, float yaw, float pitch, PlayerEntity owner) { public FishingHookEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, Vector3f position, Vector3f motion, float yaw, float pitch, PlayerEntity owner) {
super(session, entityId, geyserId, uuid, EntityDefinitions.FISHING_BOBBER, position, motion, yaw, pitch, 0f); super(session, entityId, geyserId, uuid, EntityDefinitions.FISHING_BOBBER, position, motion, yaw, pitch, 0f);
@ -59,8 +64,9 @@ public class FishingHookEntity extends ThrowableEntity {
// In Java, the splash sound depends on the entity's velocity, but in Bedrock the volume doesn't change. // In Java, the splash sound depends on the entity's velocity, but in Bedrock the volume doesn't change.
// This splash can be confused with the sound from catching a fish. This silences the splash from Bedrock, // This splash can be confused with the sound from catching a fish. This silences the splash from Bedrock,
// so that it can be handled by moveAbsoluteImmediate. // so that it can be handled by moveAbsoluteImmediate.
this.dirtyMetadata.putFloat(EntityData.BOUNDING_BOX_HEIGHT, 128); setBoundingBoxHeight(128);
isOwnerSessionPlayer = owner.getGeyserId() == session.getPlayerEntity().getGeyserId();
this.dirtyMetadata.put(EntityData.OWNER_EID, owner.getGeyserId()); this.dirtyMetadata.put(EntityData.OWNER_EID, owner.getGeyserId());
} }
@ -80,7 +86,8 @@ public class FishingHookEntity extends ThrowableEntity {
} }
if (entity != null) { if (entity != null) {
dirtyMetadata.put(EntityData.TARGET_EID, entity.getGeyserId()); bedrockTargetId = entity.getGeyserId();
dirtyMetadata.put(EntityData.TARGET_EID, bedrockTargetId);
hooked = true; hooked = true;
} else { } else {
hooked = false; hooked = false;

Datei anzeigen

@ -23,11 +23,33 @@
* @link https://github.com/GeyserMC/Geyser * @link https://github.com/GeyserMC/Geyser
*/ */
package org.geysermc.connector.entity.type; package org.geysermc.connector.entity;
import lombok.Getter; import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityDataMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
@Getter import java.util.Map;
public enum EntityType {
/**
* A write-only wrapper for temporarily storing entity metadata that will be sent to Bedrock.
*/
public class GeyserDirtyMetadata {
private final Map<EntityData, Object> metadata = new Object2ObjectLinkedOpenHashMap<>();
public void put(EntityData entityData, Object value) {
metadata.put(entityData, value);
}
/**
* Applies the contents of the dirty metadata into the input and clears the contents of our map.
*/
public void apply(EntityDataMap map) {
map.putAll(metadata);
metadata.clear();
}
public boolean hasEntries() {
return !metadata.isEmpty();
}
} }

Datei anzeigen

@ -41,7 +41,6 @@ import org.geysermc.connector.network.translators.world.block.BlockStateValues;
import java.util.UUID; import java.util.UUID;
public class ItemEntity extends ThrowableEntity { public class ItemEntity extends ThrowableEntity {
protected ItemData item; protected ItemData item;
private int waterLevel = -1; private int waterLevel = -1;
@ -63,7 +62,11 @@ public class ItemEntity extends ThrowableEntity {
itemPacket.setMotion(motion); itemPacket.setMotion(motion);
itemPacket.setFromFishing(false); itemPacket.setFromFishing(false);
itemPacket.setItemInHand(item); itemPacket.setItemInHand(item);
itemPacket.getMetadata().putAll(dirtyMetadata); itemPacket.getMetadata().putFlags(this.flags);
dirtyMetadata.apply(itemPacket.getMetadata());
setFlagsDirty(false);
session.sendUpstreamPacket(itemPacket); session.sendUpstreamPacket(itemPacket);
} }

Datei anzeigen

@ -104,7 +104,7 @@ public class ItemFrameEntity extends Entity {
@Override @Override
public void spawnEntity() { public void spawnEntity() {
updateBlock(); updateBlock(true);
session.getConnector().getLogger().debug("Spawned item frame at location " + bedrockPosition + " with java id " + entityId); session.getConnector().getLogger().debug("Spawned item frame at location " + bedrockPosition + " with java id " + entityId);
valid = true; valid = true;
} }
@ -174,14 +174,14 @@ public class ItemFrameEntity extends Entity {
@Override @Override
public void updateBedrockMetadata() { public void updateBedrockMetadata() {
updateBlock(); updateBlock(false);
} }
/** /**
* Updates the item frame as a block * Updates the item frame as a block
*/ */
public void updateBlock() { public void updateBlock(boolean force) {
if (!changed) { if (!changed && !force) {
// Don't send a block update packet - nothing changed // Don't send a block update packet - nothing changed
return; return;
} }

Datei anzeigen

@ -140,12 +140,8 @@ public class LivingEntity extends Entity {
@Override @Override
protected void setDimensions(Pose pose) { protected void setDimensions(Pose pose) {
if (pose == Pose.SLEEPING) { if (pose == Pose.SLEEPING) {
boundingBoxWidth = 0.2f; setBoundingBoxWidth(0.2f);
boundingBoxHeight = 0.2f; setBoundingBoxHeight(0.2f);
if (boundingBoxWidth != definition.width() || boundingBoxHeight != definition.height()) {
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, boundingBoxWidth);
dirtyMetadata.put(EntityData.BOUNDING_BOX_HEIGHT, boundingBoxHeight);
}
} else { } else {
super.setDimensions(pose); super.setDimensions(pose);
} }

Datei anzeigen

@ -294,8 +294,7 @@ public class ArmorStandEntity extends LivingEntity {
} }
return; return;
} }
//boolean isNametagEmpty = metadata.getString(EntityData.NAMETAG).isEmpty() || metadata.getByte(EntityData.NAMETAG_ALWAYS_SHOW, (byte) -1) == (byte) 0; - may not be necessary? boolean isNametagEmpty = nametag.isEmpty();
boolean isNametagEmpty = dirtyMetadata.getString(EntityData.NAMETAG).isEmpty(); // TODO
if (!isNametagEmpty && (!helmet.equals(ItemData.AIR) || !chestplate.equals(ItemData.AIR) || !leggings.equals(ItemData.AIR) if (!isNametagEmpty && (!helmet.equals(ItemData.AIR) || !chestplate.equals(ItemData.AIR) || !leggings.equals(ItemData.AIR)
|| !boots.equals(ItemData.AIR) || !hand.equals(ItemData.AIR) || !offHand.equals(ItemData.AIR))) { || !boots.equals(ItemData.AIR) || !hand.equals(ItemData.AIR) || !offHand.equals(ItemData.AIR))) {
// If the second entity exists, no need to recreate it. // If the second entity exists, no need to recreate it.
@ -313,7 +312,7 @@ public class ArmorStandEntity extends LivingEntity {
} }
// Copy metadata // Copy metadata
secondEntity.isSmall = isSmall; secondEntity.isSmall = isSmall;
secondEntity.getDirtyMetadata().putAll(dirtyMetadata); //TODO check //secondEntity.getDirtyMetadata().putAll(dirtyMetadata); //TODO check
secondEntity.flags.merge(this.flags); secondEntity.flags.merge(this.flags);
// Guarantee this copy is NOT invisible // Guarantee this copy is NOT invisible
secondEntity.setFlag(EntityFlag.INVISIBLE, false); secondEntity.setFlag(EntityFlag.INVISIBLE, false);

Datei anzeigen

@ -44,7 +44,7 @@ public class AnimalEntity extends AgeableEntity {
* <code>wheat</code>. * <code>wheat</code>.
* @return true if this is a valid item to breed with for this animal. * @return true if this is a valid item to breed with for this animal.
*/ */
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
// This is what it defaults to. OK. // This is what it defaults to. OK.
return javaIdentifierStripped.equals("wheat"); return javaIdentifierStripped.equals("wheat");
} }

Datei anzeigen

@ -56,7 +56,7 @@ public class AxolotlEntity extends AnimalEntity {
} }
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return javaIdentifierStripped.equals("tropical_fish_bucket"); return javaIdentifierStripped.equals("tropical_fish_bucket");
} }

Datei anzeigen

@ -67,7 +67,7 @@ public class BeeEntity extends AnimalEntity {
} }
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return session.getTagCache().isFlower(mapping); return session.getTagCache().isFlower(mapping);
} }
} }

Datei anzeigen

@ -39,7 +39,7 @@ public class ChickenEntity extends AnimalEntity {
} }
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return javaIdentifierStripped.contains("seeds"); return javaIdentifierStripped.contains("seeds");
} }
} }

Datei anzeigen

@ -55,7 +55,7 @@ public class FoxEntity extends AnimalEntity {
} }
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return session.getTagCache().isFoxFood(mapping); return session.getTagCache().isFoxFood(mapping);
} }
} }

Datei anzeigen

@ -29,7 +29,6 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadat
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import lombok.Getter; import lombok.Getter;
import org.geysermc.connector.entity.EntityDefinition; import org.geysermc.connector.entity.EntityDefinition;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
@ -55,8 +54,8 @@ public class GoatEntity extends AnimalEntity {
@Override @Override
protected void setDimensions(Pose pose) { protected void setDimensions(Pose pose) {
if (pose == Pose.LONG_JUMPING) { if (pose == Pose.LONG_JUMPING) {
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, LONG_JUMPING_WIDTH); setBoundingBoxWidth(LONG_JUMPING_WIDTH);
dirtyMetadata.put(EntityData.BOUNDING_BOX_HEIGHT, LONG_JUMPING_HEIGHT); setBoundingBoxHeight(LONG_JUMPING_HEIGHT);
} else { } else {
super.setDimensions(pose); super.setDimensions(pose);
} }

Datei anzeigen

@ -55,7 +55,7 @@ public class HoglinEntity extends AnimalEntity {
} }
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return javaIdentifierStripped.equals("crimson_fungus"); return javaIdentifierStripped.equals("crimson_fungus");
} }
} }

Datei anzeigen

@ -39,7 +39,7 @@ public class OcelotEntity extends AnimalEntity {
} }
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return javaIdentifierStripped.equals("cod") || javaIdentifierStripped.equals("salmon"); return javaIdentifierStripped.equals("cod") || javaIdentifierStripped.equals("salmon");
} }
} }

Datei anzeigen

@ -83,7 +83,7 @@ public class PandaEntity extends AnimalEntity {
} }
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return javaIdentifierStripped.equals("bamboo"); return javaIdentifierStripped.equals("bamboo");
} }

Datei anzeigen

@ -39,7 +39,7 @@ public class PigEntity extends AnimalEntity {
} }
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return javaIdentifierStripped.equals("carrot") || javaIdentifierStripped.equals("potato") || javaIdentifierStripped.equals("beetroot"); return javaIdentifierStripped.equals("carrot") || javaIdentifierStripped.equals("potato") || javaIdentifierStripped.equals("beetroot");
} }
} }

Datei anzeigen

@ -39,7 +39,7 @@ public class PolarBearEntity extends AnimalEntity {
} }
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return false; return false;
} }
} }

Datei anzeigen

@ -72,7 +72,7 @@ public class RabbitEntity extends AnimalEntity {
} }
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return javaIdentifierStripped.equals("dandelion") || javaIdentifierStripped.equals("carrot") || javaIdentifierStripped.equals("golden_carrot"); return javaIdentifierStripped.equals("dandelion") || javaIdentifierStripped.equals("carrot") || javaIdentifierStripped.equals("golden_carrot");
} }
} }

Datei anzeigen

@ -93,7 +93,7 @@ public class StriderEntity extends AnimalEntity {
} }
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return javaIdentifierStripped.equals("warped_fungus"); return javaIdentifierStripped.equals("warped_fungus");
} }
} }

Datei anzeigen

@ -50,7 +50,7 @@ public class TurtleEntity extends AnimalEntity {
} }
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return javaIdentifierStripped.equals("seagrass"); return javaIdentifierStripped.equals("seagrass");
} }
} }

Datei anzeigen

@ -120,7 +120,7 @@ public class AbstractHorseEntity extends AnimalEntity {
} }
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return DONKEY_AND_HORSE_FOODS.contains(javaIdentifierStripped); return DONKEY_AND_HORSE_FOODS.contains(javaIdentifierStripped);
} }
} }

Datei anzeigen

@ -70,7 +70,7 @@ public class LlamaEntity extends ChestedHorseEntity {
} }
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return javaIdentifierStripped.equals("wheat") || javaIdentifierStripped.equals("hay_block"); return javaIdentifierStripped.equals("wheat") || javaIdentifierStripped.equals("hay_block");
} }
} }

Datei anzeigen

@ -95,7 +95,7 @@ public class CatEntity extends TameableEntity {
} }
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return javaIdentifierStripped.equals("cod") || javaIdentifierStripped.equals("salmon"); return javaIdentifierStripped.equals("cod") || javaIdentifierStripped.equals("salmon");
} }
} }

Datei anzeigen

@ -39,7 +39,7 @@ public class ParrotEntity extends TameableEntity {
} }
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return javaIdentifierStripped.contains("seeds") || javaIdentifierStripped.equals("cookie"); return javaIdentifierStripped.contains("seeds") || javaIdentifierStripped.equals("cookie");
} }
} }

Datei anzeigen

@ -56,7 +56,7 @@ public class WolfEntity extends TameableEntity {
@Override @Override
public void setTameableFlags(EntityMetadata<Byte> entityMetadata) { public void setTameableFlags(EntityMetadata<Byte> entityMetadata) {
super.setFlags(entityMetadata); super.setTameableFlags(entityMetadata);
// Reset wolf color // Reset wolf color
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue(); byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
boolean angry = (xd & 0x02) == 0x02; boolean angry = (xd & 0x02) == 0x02;
@ -87,8 +87,8 @@ public class WolfEntity extends TameableEntity {
} }
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
// Cannot be a baby to eat these foods // Cannot be a baby to eat these foods
return WOLF_FOODS.contains(javaIdentifierStripped) && !getFlag(EntityFlag.BABY); return WOLF_FOODS.contains(javaIdentifierStripped) && !isBaby();
} }
} }

Datei anzeigen

@ -29,7 +29,6 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadat
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.LevelEventType; import com.nukkitx.protocol.bedrock.data.LevelEventType;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityEventType; import com.nukkitx.protocol.bedrock.data.entity.EntityEventType;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.*; import com.nukkitx.protocol.bedrock.packet.*;
@ -237,7 +236,7 @@ public class EnderDragonEntity extends MobEntity implements Tickable {
phaseTicks++; phaseTicks++;
if (phase == 3) { // Landing Phase if (phase == 3) { // Landing Phase
float headHeight = head.getDirtyMetadata().getFloat(EntityData.BOUNDING_BOX_HEIGHT); //TODO float headHeight = head.getBoundingBoxHeight();
Vector3f headCenter = head.getPosition().up(headHeight * 0.5f); Vector3f headCenter = head.getPosition().up(headHeight * 0.5f);
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {

Datei anzeigen

@ -44,7 +44,7 @@ public class SpellcasterIllagerEntity extends AbstractIllagerEntity {
public SpellcasterIllagerEntity(GeyserSession session, long entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { public SpellcasterIllagerEntity(GeyserSession session, long 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); super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
// OptionalPack usage // OptionalPack usage
dirtyMetadata.getFlags().setFlag(EntityFlag.BRIBED, this.definition == EntityDefinitions.ILLUSIONER); setFlag(EntityFlag.BRIBED, this.definition == EntityDefinitions.ILLUSIONER);
} }
public void setSpellType(EntityMetadata<Byte> entityMetadata) { public void setSpellType(EntityMetadata<Byte> entityMetadata) {

Datei anzeigen

@ -28,6 +28,7 @@ package org.geysermc.connector.entity.player;
import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.auth.data.GameProfile;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition;
@ -67,6 +68,8 @@ public class PlayerEntity extends LivingEntity {
private String username; private String username;
private boolean playerList = true; // Player is in the player list private boolean playerList = true; // Player is in the player list
private Vector3i bedPosition;
/** /**
* Saves the parrot currently on the player's left shoulder; otherwise null * Saves the parrot currently on the player's left shoulder; otherwise null
*/ */
@ -114,10 +117,9 @@ public class PlayerEntity extends LivingEntity {
addPlayerPacket.getAdventureSettings().setPlayerPermission(PlayerPermission.MEMBER); addPlayerPacket.getAdventureSettings().setPlayerPermission(PlayerPermission.MEMBER);
addPlayerPacket.setDeviceId(""); addPlayerPacket.setDeviceId("");
addPlayerPacket.setPlatformChatId(""); addPlayerPacket.setPlatformChatId("");
addPlayerPacket.getMetadata().putAll(dirtyMetadata);
addPlayerPacket.getMetadata().putFlags(flags); addPlayerPacket.getMetadata().putFlags(flags);
dirtyMetadata.apply(addPlayerPacket.getMetadata());
dirtyMetadata.clear();
setFlagsDirty(false); setFlagsDirty(false);
long linkedEntityId = session.getEntityCache().getCachedPlayerEntityLink(entityId); long linkedEntityId = session.getEntityCache().getCachedPlayerEntityLink(entityId);
@ -189,8 +191,7 @@ public class PlayerEntity extends LivingEntity {
movePlayerPacket.setMode(MovePlayerPacket.Mode.NORMAL); movePlayerPacket.setMode(MovePlayerPacket.Mode.NORMAL);
// If the player is moved while sleeping, we have to adjust their y, so it appears // If the player is moved while sleeping, we have to adjust their y, so it appears
// correctly on Bedrock. This fixes GSit's lay. // correctly on Bedrock. This fixes GSit's lay.
if (dirtyMetadata.getFlags().getFlag(EntityFlag.SLEEPING)) { if (getFlag(EntityFlag.SLEEPING)) {
Vector3i bedPosition = dirtyMetadata.getPos(EntityData.BED_POSITION);
if (bedPosition != null && (bedPosition.getY() == 0 || bedPosition.distanceSquared(position.toInt()) > 4)) { if (bedPosition != null && (bedPosition.getY() == 0 || bedPosition.distanceSquared(position.toInt()) > 4)) {
// Force the player movement by using a teleport // Force the player movement by using a teleport
movePlayerPacket.setPosition(Vector3f.from(position.getX(), position.getY() - definition.offset() + 0.2f, position.getZ())); movePlayerPacket.setPosition(Vector3f.from(position.getX(), position.getY() - definition.offset() + 0.2f, position.getZ()));
@ -253,6 +254,11 @@ public class PlayerEntity extends LivingEntity {
super.setPosition(position.add(0, definition.offset(), 0)); super.setPosition(position.add(0, definition.offset(), 0));
} }
@Override
public Vector3i setBedPosition(EntityMetadata<Position> entityMetadata) {
return bedPosition = super.setBedPosition(entityMetadata);
}
public void setAbsorptionHearts(EntityMetadata<Float> entityMetadata) { public void setAbsorptionHearts(EntityMetadata<Float> entityMetadata) {
// Extra hearts - is not metadata but an attribute on Bedrock // Extra hearts - is not metadata but an attribute on Bedrock
UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();
@ -358,11 +364,12 @@ public class PlayerEntity extends LivingEntity {
// The name is not visible to the session player; clear name // The name is not visible to the session player; clear name
newDisplayName = ""; newDisplayName = "";
} }
needsUpdate = useGivenTeam && !newDisplayName.equals(dirtyMetadata.getString(EntityData.NAMETAG, null)); needsUpdate = useGivenTeam && !newDisplayName.equals(nametag);
nametag = newDisplayName;
dirtyMetadata.put(EntityData.NAMETAG, newDisplayName); dirtyMetadata.put(EntityData.NAMETAG, newDisplayName);
} else if (useGivenTeam) { } else if (useGivenTeam) {
// The name has reset, if it was previously something else // The name has reset, if it was previously something else
needsUpdate = !newDisplayName.equals(dirtyMetadata.getString(EntityData.NAMETAG)); needsUpdate = !newDisplayName.equals(nametag);
dirtyMetadata.put(EntityData.NAMETAG, this.username); dirtyMetadata.put(EntityData.NAMETAG, this.username);
} else { } else {
needsUpdate = false; needsUpdate = false;
@ -393,10 +400,8 @@ public class PlayerEntity extends LivingEntity {
return; return;
} }
} }
if (height != boundingBoxHeight || definition.width() != boundingBoxWidth) { setBoundingBoxWidth(definition.width());
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, definition.width()); setBoundingBoxHeight(height);
dirtyMetadata.put(EntityData.BOUNDING_BOX_HEIGHT, height);
}
} }
public void setBelowNameText(Objective objective) { public void setBelowNameText(Objective objective) {
@ -410,7 +415,6 @@ public class PlayerEntity extends LivingEntity {
} }
String displayString = amount + " " + objective.getDisplayName(); String displayString = amount + " " + objective.getDisplayName();
dirtyMetadata.put(EntityData.SCORE_TAG, displayString);
if (valid) { if (valid) {
// Already spawned - we still need to run the rest of this code because the spawn packet will be // Already spawned - we still need to run the rest of this code because the spawn packet will be
// providing the information // providing the information
@ -419,10 +423,7 @@ public class PlayerEntity extends LivingEntity {
packet.getMetadata().put(EntityData.SCORE_TAG, displayString); packet.getMetadata().put(EntityData.SCORE_TAG, displayString);
session.sendUpstreamPacket(packet); session.sendUpstreamPacket(packet);
} }
} else { } else if (valid) {
// Always remove the score tag first, then check for valid.
// That way the score tag is removed if the player was spawned, then despawned, and is being respawned
if (dirtyMetadata.remove(EntityData.SCORE_TAG) != null && valid) {
SetEntityDataPacket packet = new SetEntityDataPacket(); SetEntityDataPacket packet = new SetEntityDataPacket();
packet.setRuntimeEntityId(geyserId); packet.setRuntimeEntityId(geyserId);
packet.getMetadata().put(EntityData.SCORE_TAG, ""); packet.getMetadata().put(EntityData.SCORE_TAG, "");
@ -430,4 +431,3 @@ public class PlayerEntity extends LivingEntity {
} }
} }
} }
}

Datei anzeigen

@ -33,6 +33,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.AttributeData; import com.nukkitx.protocol.bedrock.data.AttributeData;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket; import com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
@ -59,6 +60,15 @@ public class SessionPlayerEntity extends PlayerEntity {
* Whether to check for updated speed after all entity metadata has been processed * Whether to check for updated speed after all entity metadata has been processed
*/ */
private boolean refreshSpeed = false; private boolean refreshSpeed = false;
/**
* Used in PlayerInputTranslator for movement checks.
*/
@Getter
private boolean isRidingInFront;
/**
* Used for villager inventory emulation.
*/
private int fakeTradeXp;
private final GeyserSession session; private final GeyserSession session;
@ -130,6 +140,17 @@ public class SessionPlayerEntity extends PlayerEntity {
} }
} }
@Override
public void setRiderSeatPosition(Vector3f position) {
super.setRiderSeatPosition(position);
this.isRidingInFront = position != null && position.getX() > 0;
}
public void addFakeTradeExperience(int tradeXp) {
fakeTradeXp += tradeXp;
dirtyMetadata.put(EntityData.TRADE_XP, fakeTradeXp);
}
@Override @Override
public AttributeData createHealthAttribute() { public AttributeData createHealthAttribute() {
// Max health must be divisible by two in bedrock // Max health must be divisible by two in bedrock

Datei anzeigen

@ -83,10 +83,9 @@ public class SkullPlayerEntity extends PlayerEntity {
addPlayerPacket.getAdventureSettings().setPlayerPermission(PlayerPermission.MEMBER); addPlayerPacket.getAdventureSettings().setPlayerPermission(PlayerPermission.MEMBER);
addPlayerPacket.setDeviceId(""); addPlayerPacket.setDeviceId("");
addPlayerPacket.setPlatformChatId(""); addPlayerPacket.setPlatformChatId("");
addPlayerPacket.getMetadata().putAll(dirtyMetadata);
addPlayerPacket.getMetadata().putFlags(flags); addPlayerPacket.getMetadata().putFlags(flags);
dirtyMetadata.apply(addPlayerPacket.getMetadata());
dirtyMetadata.clear();
setFlagsDirty(false); setFlagsDirty(false);
valid = true; valid = true;

Datei anzeigen

@ -1072,7 +1072,7 @@ public class GeyserSession implements CommandSender {
AttributeData currentPlayerSpeed = playerEntity.getAttributes().get(GeyserAttributeType.MOVEMENT_SPEED); AttributeData currentPlayerSpeed = playerEntity.getAttributes().get(GeyserAttributeType.MOVEMENT_SPEED);
if (currentPlayerSpeed != null) { if (currentPlayerSpeed != null) {
if ((pose.equals(Pose.SNEAKING) && !sneaking && collisionManager.isUnderSlab()) || if ((pose.equals(Pose.SNEAKING) && !sneaking && collisionManager.isUnderSlab()) ||
(!swimmingInWater && playerEntity.getDirtyMetadata().getFlags().getFlag(EntityFlag.SWIMMING) && !collisionManager.isPlayerInWater())) { (!swimmingInWater && playerEntity.getFlag(EntityFlag.SWIMMING) && !collisionManager.isPlayerInWater())) {
// Either of those conditions means that Bedrock goes zoom when they shouldn't be // Either of those conditions means that Bedrock goes zoom when they shouldn't be
AttributeData speedAttribute = GeyserAttributeType.MOVEMENT_SPEED.getAttribute(originalSpeedAttribute / 3.32f); AttributeData speedAttribute = GeyserAttributeType.MOVEMENT_SPEED.getAttribute(originalSpeedAttribute / 3.32f);
playerEntity.getAttributes().put(GeyserAttributeType.MOVEMENT_SPEED, speedAttribute); playerEntity.getAttributes().put(GeyserAttributeType.MOVEMENT_SPEED, speedAttribute);

Datei anzeigen

@ -50,7 +50,7 @@ public class BedrockAdventureSettingsTranslator extends PacketTranslator<Adventu
ServerboundPlayerAbilitiesPacket abilitiesPacket = new ServerboundPlayerAbilitiesPacket(isFlying); ServerboundPlayerAbilitiesPacket abilitiesPacket = new ServerboundPlayerAbilitiesPacket(isFlying);
session.sendDownstreamPacket(abilitiesPacket); session.sendDownstreamPacket(abilitiesPacket);
if (isFlying && session.getPlayerEntity().getDirtyMetadata().getFlags().getFlag(EntityFlag.SWIMMING)) { if (isFlying && session.getPlayerEntity().getFlag(EntityFlag.SWIMMING)) {
// Bedrock can fly and swim at the same time? Make sure that can't happen // Bedrock can fly and swim at the same time? Make sure that can't happen
session.setSwimming(false); session.setSwimming(false);
} }

Datei anzeigen

@ -28,7 +28,6 @@ package org.geysermc.connector.network.translators.bedrock;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundMoveVehiclePacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundMoveVehiclePacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundPlayerInputPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundPlayerInputPacket;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.packet.PlayerInputPacket; import com.nukkitx.protocol.bedrock.packet.PlayerInputPacket;
import org.geysermc.connector.entity.BoatEntity; import org.geysermc.connector.entity.BoatEntity;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Entity;
@ -65,8 +64,7 @@ public class BedrockPlayerInputTranslator extends PacketTranslator<PlayerInputPa
sendMovement = true; sendMovement = true;
} else { } else {
// Check if the player is the front rider // Check if the player is the front rider
Vector3f seatPos = session.getPlayerEntity().getDirtyMetadata().getVector3f(EntityData.RIDER_SEAT_POSITION, null); if (session.getPlayerEntity().isRidingInFront()) {
if (seatPos != null && seatPos.getX() > 0) {
sendMovement = true; sendMovement = true;
} }
} }

Datei anzeigen

@ -30,7 +30,6 @@ import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundCl
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket; import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket;
import com.nukkitx.protocol.bedrock.packet.RespawnPacket; import com.nukkitx.protocol.bedrock.packet.RespawnPacket;
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
import org.geysermc.connector.entity.player.PlayerEntity; import org.geysermc.connector.entity.player.PlayerEntity;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
@ -54,11 +53,7 @@ public class BedrockRespawnTranslator extends PacketTranslator<RespawnPacket> {
if (session.isSpawned()) { if (session.isSpawned()) {
// Client might be stuck; resend spawn information // Client might be stuck; resend spawn information
PlayerEntity entity = session.getPlayerEntity(); PlayerEntity entity = session.getPlayerEntity();
if (entity == null) return; entity.updateBedrockMetadata(); // TODO test?
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
entityDataPacket.setRuntimeEntityId(entity.getGeyserId());
entityDataPacket.getMetadata().putAll(entity.getDirtyMetadata());
session.sendUpstreamPacket(entityDataPacket);
MovePlayerPacket movePlayerPacket = new MovePlayerPacket(); MovePlayerPacket movePlayerPacket = new MovePlayerPacket();
movePlayerPacket.setRuntimeEntityId(entity.getGeyserId()); movePlayerPacket.setRuntimeEntityId(entity.getGeyserId());

Datei anzeigen

@ -27,9 +27,8 @@ package org.geysermc.connector.network.translators.bedrock.entity;
import com.github.steveice10.mc.protocol.data.game.inventory.VillagerTrade; import com.github.steveice10.mc.protocol.data.game.inventory.VillagerTrade;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSelectTradePacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSelectTradePacket;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket; import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.player.SessionPlayerEntity;
import org.geysermc.connector.inventory.GeyserItemStack; import org.geysermc.connector.inventory.GeyserItemStack;
import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.inventory.MerchantContainer; import org.geysermc.connector.inventory.MerchantContainer;
@ -55,14 +54,15 @@ public class BedrockEntityEventTranslator extends PacketTranslator<EntityEventPa
session.sendDownstreamPacket(selectTradePacket); session.sendDownstreamPacket(selectTradePacket);
session.scheduleInEventLoop(() -> { session.scheduleInEventLoop(() -> {
Entity villager = session.getPlayerEntity(); SessionPlayerEntity villager = session.getPlayerEntity();
Inventory openInventory = session.getOpenInventory(); Inventory openInventory = session.getOpenInventory();
if (openInventory instanceof MerchantContainer merchantInventory) { if (openInventory instanceof MerchantContainer merchantInventory) {
VillagerTrade[] trades = merchantInventory.getVillagerTrades(); VillagerTrade[] trades = merchantInventory.getVillagerTrades();
if (trades != null && packet.getData() >= 0 && packet.getData() < trades.length) { if (trades != null && packet.getData() >= 0 && packet.getData() < trades.length) {
VillagerTrade trade = merchantInventory.getVillagerTrades()[packet.getData()]; VillagerTrade trade = merchantInventory.getVillagerTrades()[packet.getData()];
openInventory.setItem(2, GeyserItemStack.from(trade.getOutput()), session); openInventory.setItem(2, GeyserItemStack.from(trade.getOutput()), session);
villager.getDirtyMetadata().put(EntityData.TRADE_XP, trade.getXp() + villager.getDirtyMetadata().getInt(EntityData.TRADE_XP)); // TODO this logic doesn't add up
villager.addFakeTradeExperience(trade.getXp());
villager.updateBedrockMetadata(); villager.updateBedrockMetadata();
} }
} }

Datei anzeigen

@ -116,7 +116,7 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
useItemPacket = new ServerboundUseItemPacket(Hand.OFF_HAND); useItemPacket = new ServerboundUseItemPacket(Hand.OFF_HAND);
} }
session.sendDownstreamPacket(useItemPacket); session.sendDownstreamPacket(useItemPacket);
session.getPlayerEntity().getDirtyMetadata().getFlags().setFlag(EntityFlag.BLOCKING, true); session.getPlayerEntity().setFlag(EntityFlag.BLOCKING, true);
// metadata will be updated when sneaking // metadata will be updated when sneaking
} }
@ -127,10 +127,10 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
session.sendDownstreamPacket(stopSneakPacket); session.sendDownstreamPacket(stopSneakPacket);
// Stop shield, if necessary // Stop shield, if necessary
if (session.getPlayerEntity().getDirtyMetadata().getFlags().getFlag(EntityFlag.BLOCKING)) { if (session.getPlayerEntity().getFlag(EntityFlag.BLOCKING)) {
ServerboundPlayerActionPacket releaseItemPacket = new ServerboundPlayerActionPacket(PlayerAction.RELEASE_USE_ITEM, BlockUtils.POSITION_ZERO, Direction.DOWN); ServerboundPlayerActionPacket releaseItemPacket = new ServerboundPlayerActionPacket(PlayerAction.RELEASE_USE_ITEM, BlockUtils.POSITION_ZERO, Direction.DOWN);
session.sendDownstreamPacket(releaseItemPacket); session.sendDownstreamPacket(releaseItemPacket);
session.getPlayerEntity().getDirtyMetadata().getFlags().setFlag(EntityFlag.BLOCKING, false); session.getPlayerEntity().setFlag(EntityFlag.BLOCKING, false);
// metadata will be updated when sneaking // metadata will be updated when sneaking
} }

Datei anzeigen

@ -99,7 +99,7 @@ public class BedrockInteractTranslator extends PacketTranslator<InteractPacket>
if (session.getOpenInventory() == null) { if (session.getOpenInventory() == null) {
Entity ridingEntity = session.getRidingVehicleEntity(); Entity ridingEntity = session.getRidingVehicleEntity();
if (ridingEntity instanceof AbstractHorseEntity) { if (ridingEntity instanceof AbstractHorseEntity) {
if (ridingEntity.getDirtyMetadata().getFlags().getFlag(EntityFlag.TAMED)) { if (ridingEntity.getFlag(EntityFlag.TAMED)) {
// We should request to open the horse inventory instead // We should request to open the horse inventory instead
ServerboundPlayerCommandPacket openHorseWindowPacket = new ServerboundPlayerCommandPacket((int) session.getPlayerEntity().getEntityId(), PlayerState.OPEN_HORSE_INVENTORY); ServerboundPlayerCommandPacket openHorseWindowPacket = new ServerboundPlayerCommandPacket((int) session.getPlayerEntity().getEntityId(), PlayerState.OPEN_HORSE_INVENTORY);
session.sendDownstreamPacket(openHorseWindowPacket); session.sendDownstreamPacket(openHorseWindowPacket);

Datei anzeigen

@ -28,10 +28,8 @@ package org.geysermc.connector.network.translators.collision;
import com.nukkitx.math.vector.Vector3d; import com.nukkitx.math.vector.Vector3d;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.math.vector.Vector3i; import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket; import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket;
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Entity;
@ -121,7 +119,7 @@ public class CollisionManager {
// - In Bedrock Edition, the height becomes 1.65 blocks, allowing movement through spaces as small as 1.75 (2 - 14) blocks high. // - In Bedrock Edition, the height becomes 1.65 blocks, allowing movement through spaces as small as 1.75 (2 - 14) blocks high.
// - In Java Edition, the height becomes 1.5 blocks. // - In Java Edition, the height becomes 1.5 blocks.
// Other instances have the player's bounding box become as small as 0.6 or 0.2. // Other instances have the player's bounding box become as small as 0.6 or 0.2.
double playerHeight = session.getPlayerEntity().getDirtyMetadata().getFloat(EntityData.BOUNDING_BOX_HEIGHT); double playerHeight = session.getPlayerEntity().getBoundingBoxHeight();
playerBoundingBox.setMiddleY(playerBoundingBox.getMiddleY() - (playerBoundingBox.getSizeY() / 2.0) + (playerHeight / 2.0)); playerBoundingBox.setMiddleY(playerBoundingBox.getMiddleY() - (playerBoundingBox.getSizeY() / 2.0) + (playerHeight / 2.0));
playerBoundingBox.setSizeY(playerHeight); playerBoundingBox.setSizeY(playerHeight);
} }
@ -188,10 +186,7 @@ public class CollisionManager {
public void recalculatePosition() { public void recalculatePosition() {
PlayerEntity entity = session.getPlayerEntity(); PlayerEntity entity = session.getPlayerEntity();
// Gravity might need to be reset... // Gravity might need to be reset...
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); entity.updateBedrockMetadata(); // TODO may not be necessary
entityDataPacket.setRuntimeEntityId(entity.getGeyserId());
entityDataPacket.getMetadata().putAll(entity.getDirtyMetadata());
session.sendUpstreamPacket(entityDataPacket);
MovePlayerPacket movePlayerPacket = new MovePlayerPacket(); MovePlayerPacket movePlayerPacket = new MovePlayerPacket();
movePlayerPacket.setRuntimeEntityId(entity.getGeyserId()); movePlayerPacket.setRuntimeEntityId(entity.getGeyserId());

Datei anzeigen

@ -220,7 +220,7 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
case BLOCK_STATE -> BlockRegistries.JAVA_TO_BEDROCK_IDENTIFIERS.get().keySet().toArray(new String[0]); case BLOCK_STATE -> BlockRegistries.JAVA_TO_BEDROCK_IDENTIFIERS.get().keySet().toArray(new String[0]);
case ITEM_STACK -> session.getItemMappings().getItemNames(); case ITEM_STACK -> session.getItemMappings().getItemNames();
case ITEM_ENCHANTMENT -> Enchantment.JavaEnchantment.ALL_JAVA_IDENTIFIERS; case ITEM_ENCHANTMENT -> Enchantment.JavaEnchantment.ALL_JAVA_IDENTIFIERS;
case ENTITY_SUMMON -> Registries.JAVA_ENTITY_IDENTIFIERS.get().keySet().toArray(new String[0]); //TODO add Marker case ENTITY_SUMMON -> Registries.JAVA_ENTITY_IDENTIFIERS.get().keySet().toArray(new String[0]);
case COLOR -> VALID_COLORS; case COLOR -> VALID_COLORS;
case SCOREBOARD_SLOT -> VALID_SCOREBOARD_SLOTS; case SCOREBOARD_SLOT -> VALID_SCOREBOARD_SLOTS;
case MOB_EFFECT -> ALL_EFFECT_IDENTIFIERS; case MOB_EFFECT -> ALL_EFFECT_IDENTIFIERS;

Datei anzeigen

@ -90,10 +90,7 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
session.sendUpstreamPacket(playerGameTypePacket); session.sendUpstreamPacket(playerGameTypePacket);
} }
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); entity.updateBedrockMetadata();
entityDataPacket.setRuntimeEntityId(entity.getGeyserId());
entityDataPacket.getMetadata().putAll(entity.getDirtyMetadata());
session.sendUpstreamPacket(entityDataPacket);
// Send if client should show respawn screen // Send if client should show respawn screen
GameRulesChangedPacket gamerulePacket = new GameRulesChangedPacket(); GameRulesChangedPacket gamerulePacket = new GameRulesChangedPacket();

Datei anzeigen

@ -34,6 +34,7 @@ import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
import com.nukkitx.protocol.bedrock.packet.*; import com.nukkitx.protocol.bedrock.packet.*;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.entity.EntityDefinitions; import org.geysermc.connector.entity.EntityDefinitions;
import org.geysermc.connector.entity.FishingHookEntity;
import org.geysermc.connector.entity.LivingEntity; import org.geysermc.connector.entity.LivingEntity;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
@ -122,9 +123,9 @@ public class JavaEntityEventTranslator extends PacketTranslator<ClientboundEntit
case FISHING_HOOK_PULL_PLAYER: case FISHING_HOOK_PULL_PLAYER:
// Player is pulled from a fishing rod // Player is pulled from a fishing rod
// The physics of this are clientside on Java // The physics of this are clientside on Java
long pulledById = entity.getDirtyMetadata().getLong(EntityData.TARGET_EID); FishingHookEntity fishingHook = (FishingHookEntity) entity;
if (session.getPlayerEntity().getGeyserId() == pulledById) { if (fishingHook.isOwnerSessionPlayer()) {
Entity hookOwner = session.getEntityCache().getEntityByGeyserId(entity.getDirtyMetadata().getLong(EntityData.OWNER_EID)); Entity hookOwner = session.getEntityCache().getEntityByGeyserId(fishingHook.getBedrockTargetId());
if (hookOwner != null) { if (hookOwner != null) {
// https://minecraft.gamepedia.com/Fishing_Rod#Hooking_mobs_and_other_entities // https://minecraft.gamepedia.com/Fishing_Rod#Hooking_mobs_and_other_entities
SetEntityMotionPacket motionPacket = new SetEntityMotionPacket(); SetEntityMotionPacket motionPacket = new SetEntityMotionPacket();

Datei anzeigen

@ -33,7 +33,6 @@ import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.utils.InteractiveTagManager; import org.geysermc.connector.utils.InteractiveTagManager;
import org.geysermc.connector.utils.LanguageUtils;
import java.util.List; import java.util.List;
@ -61,16 +60,19 @@ public class JavaSetEntityDataTranslator extends PacketTranslator<ClientboundSet
continue; continue;
} }
EntityMetadataTranslator<? super Entity, ?> translator = (EntityMetadataTranslator<? super Entity, ?>) translators.get(metadata.getId()); EntityMetadataTranslator<? super Entity, Object> translator = (EntityMetadataTranslator<? super Entity, Object>) translators.get(metadata.getId());
if (translator == null) { if (translator == null) {
// This can safely happen; it means we don't translate this entity metadata // This can safely happen; it means we don't translate this entity metadata
continue; continue;
} }
if (translator.acceptedType() != metadata.getType()) { if (translator.acceptedType() != metadata.getType()) {
session.getConnector().getLogger().warning("Metadata ID " + metadata.getId() + " was received with type " + metadata.getType() + " but we expected " + translator.acceptedType() + " for " + entity.getDefinition().entityType()); session.getConnector().getLogger().warning("Metadata ID " + metadata.getId() + " was received with type " + metadata.getType() + " but we expected " + translator.acceptedType() + " for " + entity.getDefinition().entityType());
if (session.getConnector().getConfig().isDebugMode()) {
session.getConnector().getLogger().debug(metadata.toString());
}
continue; continue;
} }
translator.translateFunction().accept(entity, metadata); translator.translateFunction().accept(entity, (EntityMetadata<Object>) metadata);
} }
entity.updateBedrockMetadata(); entity.updateBedrockMetadata();

Datei anzeigen

@ -33,7 +33,6 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityLinkData; import com.nukkitx.protocol.bedrock.data.entity.EntityLinkData;
import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket; import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket;
import com.nukkitx.protocol.bedrock.packet.RespawnPacket; import com.nukkitx.protocol.bedrock.packet.RespawnPacket;
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
import com.nukkitx.protocol.bedrock.packet.SetEntityLinkPacket; import com.nukkitx.protocol.bedrock.packet.SetEntityLinkPacket;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.entity.EntityDefinitions; import org.geysermc.connector.entity.EntityDefinitions;
@ -69,10 +68,7 @@ public class JavaPlayerPositionTranslator extends PacketTranslator<ClientboundPl
respawnPacket.setState(RespawnPacket.State.SERVER_READY); respawnPacket.setState(RespawnPacket.State.SERVER_READY);
session.sendUpstreamPacket(respawnPacket); session.sendUpstreamPacket(respawnPacket);
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); entity.updateBedrockMetadata();
entityDataPacket.setRuntimeEntityId(entity.getGeyserId());
entityDataPacket.getMetadata().putAll(entity.getDirtyMetadata());
session.sendUpstreamPacket(entityDataPacket);
MovePlayerPacket movePlayerPacket = new MovePlayerPacket(); MovePlayerPacket movePlayerPacket = new MovePlayerPacket();
movePlayerPacket.setRuntimeEntityId(entity.getGeyserId()); movePlayerPacket.setRuntimeEntityId(entity.getGeyserId());

Datei anzeigen

@ -29,7 +29,6 @@ import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.Cli
import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtMap;
import com.nukkitx.nbt.NbtMapBuilder; import com.nukkitx.nbt.NbtMapBuilder;
import com.nukkitx.nbt.NbtType; import com.nukkitx.nbt.NbtType;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; import com.nukkitx.protocol.bedrock.data.inventory.ContainerType;
import com.nukkitx.protocol.bedrock.packet.UpdateEquipPacket; import com.nukkitx.protocol.bedrock.packet.UpdateEquipPacket;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Entity;
@ -132,6 +131,6 @@ public class JavaHorseScreenOpenTranslator extends PacketTranslator<ClientboundH
session.sendUpstreamPacket(updateEquipPacket); session.sendUpstreamPacket(updateEquipPacket);
session.setInventoryTranslator(inventoryTranslator); session.setInventoryTranslator(inventoryTranslator);
InventoryUtils.openInventory(session, new Container(entity.getDirtyMetadata().getString(EntityData.NAMETAG), packet.getContainerId(), packet.getNumberOfSlots(), null, session.getPlayerInventory())); InventoryUtils.openInventory(session, new Container(entity.getNametag(), packet.getContainerId(), packet.getNumberOfSlots(), null, session.getPlayerInventory()));
} }
} }

Datei anzeigen

@ -49,6 +49,7 @@ import io.netty.buffer.ByteBufOutputStream;
import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.ints.IntLists; import it.unimi.dsi.fastutil.ints.IntLists;
import org.geysermc.connector.entity.ItemFrameEntity;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
@ -68,9 +69,7 @@ import org.geysermc.connector.utils.ChunkUtils;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.*;
import java.util.BitSet;
import java.util.List;
import static org.geysermc.connector.utils.ChunkUtils.*; import static org.geysermc.connector.utils.ChunkUtils.*;
@ -85,11 +84,12 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
// Ensure that, if the player is using lower world heights, the position is not offset // Ensure that, if the player is using lower world heights, the position is not offset
int yOffset = session.getChunkCache().getChunkMinY(); int yOffset = session.getChunkCache().getChunkMinY();
int chunkSize = session.getChunkCache().getChunkHeightY();
// Temporarily stores compound tags of Bedrock-only block entities // Temporarily stores compound tags of Bedrock-only block entities
List<NbtMap> bedrockOnlyBlockEntities = new ArrayList<>(); List<NbtMap> bedrockOnlyBlockEntities = new ArrayList<>();
DataPalette[] javaChunks = new DataPalette[session.getChunkCache().getChunkHeightY()]; DataPalette[] javaChunks = new DataPalette[chunkSize];
DataPalette[] javaBiomes = new DataPalette[session.getChunkCache().getChunkHeightY()]; DataPalette[] javaBiomes = new DataPalette[chunkSize];
BitSet waterloggedPaletteIds = new BitSet(); BitSet waterloggedPaletteIds = new BitSet();
BitSet pistonOrFlowerPaletteIds = new BitSet(); BitSet pistonOrFlowerPaletteIds = new BitSet();
@ -100,21 +100,21 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
int sectionCount; int sectionCount;
byte[] payload; byte[] payload;
ByteBuf byteBuf = null; ByteBuf byteBuf = null;
GeyserChunkSection[] sections = new GeyserChunkSection[javaChunks.length - yOffset]; GeyserChunkSection[] sections = new GeyserChunkSection[javaChunks.length - (yOffset + ((overworld ? MINIMUM_ACCEPTED_HEIGHT_OVERWORLD : MINIMUM_ACCEPTED_HEIGHT) >> 4))];
try { try {
NetInput in = new StreamNetInput(new ByteArrayInputStream(packet.getChunkData())); NetInput in = new StreamNetInput(new ByteArrayInputStream(packet.getChunkData()));
for (int sectionY = 0; sectionY < session.getChunkCache().getChunkHeightY(); sectionY++) { for (int sectionY = 0; sectionY < chunkSize; sectionY++) {
ChunkSection javaSection = ChunkSection.read(in);
javaChunks[sectionY] = javaSection.getChunkData();
javaBiomes[sectionY] = javaSection.getBiomeData();
int bedrockSectionY = sectionY + (yOffset - ((overworld ? MINIMUM_ACCEPTED_HEIGHT_OVERWORLD : MINIMUM_ACCEPTED_HEIGHT) >> 4)); int bedrockSectionY = sectionY + (yOffset - ((overworld ? MINIMUM_ACCEPTED_HEIGHT_OVERWORLD : MINIMUM_ACCEPTED_HEIGHT) >> 4));
if (bedrockSectionY < 0 || maxBedrockSectionY < bedrockSectionY) { if (bedrockSectionY < 0 || maxBedrockSectionY < bedrockSectionY) {
// Ignore this chunk section since it goes outside the bounds accepted by the Bedrock client // Ignore this chunk section since it goes outside the bounds accepted by the Bedrock client
continue; continue;
} }
ChunkSection javaSection = ChunkSection.read(in);
javaChunks[sectionY] = javaSection.getChunkData();
javaBiomes[sectionY] = javaSection.getBiomeData();
// No need to encode an empty section... // No need to encode an empty section...
if (javaSection.isBlockCountEmpty()) { if (javaSection.isBlockCountEmpty()) {
continue; continue;
@ -316,11 +316,11 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
for (int i = 0; i < sectionCount; i++) { for (int i = 0; i < sectionCount; i++) {
int biomeYOffset = dimensionOffset + i; int biomeYOffset = dimensionOffset + i;
if (biomeYOffset < yOffset) { if (biomeYOffset < yOffset) {
// Ignore this biome section since it goes below the height of the Java world // Ignore this biome section since it goes above or below the height of the Java world
byteBuf.writeBytes(ChunkUtils.EMPTY_BIOME_DATA); byteBuf.writeBytes(ChunkUtils.EMPTY_BIOME_DATA);
continue; continue;
} }
BiomeTranslator.toNewBedrockBiome(session, javaBiomes[i]).writeToNetwork(byteBuf); BiomeTranslator.toNewBedrockBiome(session, javaBiomes[i + (dimensionOffset - yOffset)]).writeToNetwork(byteBuf);
} }
// As of 1.17.10, Bedrock hardcodes to always read 32 biome sections // As of 1.17.10, Bedrock hardcodes to always read 32 biome sections
@ -356,5 +356,14 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
levelChunkPacket.setChunkZ(packet.getZ()); levelChunkPacket.setChunkZ(packet.getZ());
levelChunkPacket.setData(payload); levelChunkPacket.setData(payload);
session.sendUpstreamPacket(levelChunkPacket); session.sendUpstreamPacket(levelChunkPacket);
for (Map.Entry<Vector3i, ItemFrameEntity> entry : session.getItemFrameCache().entrySet()) {
Vector3i position = entry.getKey();
if ((position.getX() >> 4) == packet.getX() && (position.getZ() >> 4) == packet.getZ()) {
// Update this item frame so it doesn't get lost in the abyss
//TODO optimize
entry.getValue().updateBlock(true);
}
}
} }
} }

Datei anzeigen

@ -136,18 +136,18 @@ public class JavaLevelParticlesTranslator extends PacketTranslator<ClientboundLe
return null; return null;
} }
if (particleMapping.getLevelEventType() != null) { if (particleMapping.levelEventType() != null) {
return (position) -> { return (position) -> {
LevelEventPacket packet = new LevelEventPacket(); LevelEventPacket packet = new LevelEventPacket();
packet.setType(particleMapping.getLevelEventType()); packet.setType(particleMapping.levelEventType());
packet.setPosition(position); packet.setPosition(position);
return packet; return packet;
}; };
} else if (particleMapping.getIdentifier() != null) { } else if (particleMapping.identifier() != null) {
int dimensionId = DimensionUtils.javaToBedrock(session.getDimension()); int dimensionId = DimensionUtils.javaToBedrock(session.getDimension());
return (position) -> { return (position) -> {
SpawnParticleEffectPacket stringPacket = new SpawnParticleEffectPacket(); SpawnParticleEffectPacket stringPacket = new SpawnParticleEffectPacket();
stringPacket.setIdentifier(particleMapping.getIdentifier()); stringPacket.setIdentifier(particleMapping.identifier());
stringPacket.setDimensionId(dimensionId); stringPacket.setDimensionId(dimensionId);
stringPacket.setPosition(position); stringPacket.setPosition(position);
return stringPacket; return stringPacket;

Datei anzeigen

@ -27,7 +27,6 @@ package org.geysermc.connector.network.translators.sound.entity;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityEventType; import com.nukkitx.protocol.bedrock.data.entity.EntityEventType;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket; import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.entity.living.animal.AnimalEntity; import org.geysermc.connector.entity.living.animal.AnimalEntity;
@ -42,10 +41,10 @@ public class FeedBabySoundInteractionHandler implements EntitySoundInteractionHa
@Override @Override
public void handleInteraction(GeyserSession session, Vector3f position, Entity entity) { public void handleInteraction(GeyserSession session, Vector3f position, Entity entity) {
if (entity instanceof AnimalEntity && !(entity instanceof CatEntity || entity instanceof OcelotEntity)) { if (entity instanceof AnimalEntity animalEntity && !(entity instanceof CatEntity || entity instanceof OcelotEntity)) {
String handIdentifier = session.getPlayerInventory().getItemInHand().getMapping(session).getJavaIdentifier(); String handIdentifier = session.getPlayerInventory().getItemInHand().getMapping(session).getJavaIdentifier();
boolean isBaby = entity.getDirtyMetadata().getFlags().getFlag(EntityFlag.BABY); boolean isBaby = animalEntity.isBaby();
if (isBaby && ((AnimalEntity) entity).canEat(session, handIdentifier.replace("minecraft:", ""), if (isBaby && animalEntity.canEat(handIdentifier.replace("minecraft:", ""),
session.getPlayerInventory().getItemInHand().getMapping(session))) { session.getPlayerInventory().getItemInHand().getMapping(session))) {
// Play the "feed child" effect // Play the "feed child" effect
EntityEventPacket feedEvent = new EntityEventPacket(); EntityEventPacket feedEvent = new EntityEventPacket();

Datei anzeigen

@ -43,7 +43,7 @@ public class MilkEntitySoundInteractionHandler implements EntitySoundInteraction
if (!session.getPlayerInventory().getItemInHand().getMapping(session).getJavaIdentifier().equals("minecraft:bucket")) { if (!session.getPlayerInventory().getItemInHand().getMapping(session).getJavaIdentifier().equals("minecraft:bucket")) {
return; return;
} }
if (value.getDirtyMetadata().getFlags().getFlag(EntityFlag.BABY)) { if (value.getFlag(EntityFlag.BABY)) {
return; return;
} }

Datei anzeigen

@ -32,6 +32,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import org.geysermc.connector.registry.type.ParticleMapping; import org.geysermc.connector.registry.type.ParticleMapping;
import java.util.Iterator; import java.util.Iterator;
import java.util.Locale;
import java.util.Map; import java.util.Map;
/** /**
@ -49,12 +50,10 @@ public class ParticleTypesRegistryLoader extends EffectRegistryLoader<Map<Partic
while (particlesIterator.hasNext()) { while (particlesIterator.hasNext()) {
Map.Entry<String, JsonNode> entry = particlesIterator.next(); Map.Entry<String, JsonNode> entry = particlesIterator.next();
JsonNode bedrockId = entry.getValue().get("bedrockId"); JsonNode bedrockId = entry.getValue().get("bedrockId");
JsonNode bedrockIdNumeric = entry.getValue().get("bedrockNumericId");
JsonNode eventType = entry.getValue().get("eventType"); JsonNode eventType = entry.getValue().get("eventType");
particles.put(ParticleType.valueOf(entry.getKey().toUpperCase()), new ParticleMapping( particles.put(ParticleType.valueOf(entry.getKey().toUpperCase(Locale.ROOT)), new ParticleMapping(
eventType == null ? null : LevelEventType.valueOf(eventType.asText().toUpperCase()), eventType == null ? null : LevelEventType.valueOf(eventType.asText().toUpperCase(Locale.ROOT)),
bedrockId == null ? null : bedrockId.asText(), bedrockId == null ? null : bedrockId.asText())
bedrockIdNumeric == null ? -1 : bedrockIdNumeric.asInt())
); );
} }
} catch (Exception e) { } catch (Exception e) {

Datei anzeigen

@ -226,6 +226,8 @@ public class ItemRegistryPopulator {
if (javaIdentifier.equals("minecraft:sculk_sensor")) { if (javaIdentifier.equals("minecraft:sculk_sensor")) {
// TODO fix in mappings // TODO fix in mappings
mappingItem.setBedrockIdentifier("minecraft:sculk_sensor"); mappingItem.setBedrockIdentifier("minecraft:sculk_sensor");
} else if (javaIdentifier.equals("minecraft:music_disc_otherside") && palette.getValue().protocolVersion() <= Bedrock_v471.V471_CODEC.getProtocolVersion()) {
mappingItem.setBedrockIdentifier("minecraft:music_disc_pigstep");
} }
if (usingFurnaceMinecart && javaIdentifier.equals("minecraft:furnace_minecart")) { if (usingFurnaceMinecart && javaIdentifier.equals("minecraft:furnace_minecart")) {
@ -398,7 +400,7 @@ public class ItemRegistryPopulator {
.count(1) .count(1)
.blockRuntimeId(mapping.getBedrockBlockId()) .blockRuntimeId(mapping.getBedrockBlockId())
.build()); .build());
} else if (javaIdentifier.startsWith("minecraft:music_disc_")) { } else if (javaIdentifier.startsWith("minecraft:music_disc_") && !javaIdentifier.equals("minecraft:music_disc_otherside")) { // TODO TEMPORARY
// The Java record level event uses the item ID as the "key" to play the record // The Java record level event uses the item ID as the "key" to play the record
Registries.RECORDS.register(itemIndex, SoundEvent.valueOf("RECORD_" + Registries.RECORDS.register(itemIndex, SoundEvent.valueOf("RECORD_" +
javaIdentifier.replace("minecraft:music_disc_", "").toUpperCase(Locale.ENGLISH))); javaIdentifier.replace("minecraft:music_disc_", "").toUpperCase(Locale.ENGLISH)));

Datei anzeigen

@ -26,14 +26,9 @@
package org.geysermc.connector.registry.type; package org.geysermc.connector.registry.type;
import com.nukkitx.protocol.bedrock.data.LevelEventType; import com.nukkitx.protocol.bedrock.data.LevelEventType;
import lombok.Value;
import javax.annotation.ParametersAreNullableByDefault; import javax.annotation.ParametersAreNullableByDefault;
@Value
@ParametersAreNullableByDefault @ParametersAreNullableByDefault
public class ParticleMapping { public record ParticleMapping(LevelEventType levelEventType, String identifier) {
LevelEventType levelEventType;
String identifier;
int id;
} }

Datei anzeigen

@ -152,7 +152,7 @@ public class ChunkUtils {
ItemFrameEntity itemFrameEntity = ItemFrameEntity.getItemFrameEntity(session, position); ItemFrameEntity itemFrameEntity = ItemFrameEntity.getItemFrameEntity(session, position);
if (itemFrameEntity != null) { if (itemFrameEntity != null) {
if (blockState == JAVA_AIR_ID) { // Item frame is still present and no block overrides that; refresh it if (blockState == JAVA_AIR_ID) { // Item frame is still present and no block overrides that; refresh it
itemFrameEntity.updateBlock(); itemFrameEntity.updateBlock(true);
// Still update the chunk cache with the new block // Still update the chunk cache with the new block
session.getChunkCache().updateBlock(position.getX(), position.getY(), position.getZ(), blockState); session.getChunkCache().updateBlock(position.getX(), position.getY(), position.getZ(), blockState);
return; return;

Datei anzeigen

@ -50,7 +50,7 @@ public class EffectUtils {
return -1; return -1;
} }
LevelEventType levelEventType = mapping.getLevelEventType(); LevelEventType levelEventType = mapping.levelEventType();
if (levelEventType == null) { if (levelEventType == null) {
return -1; return -1;
} }

Datei anzeigen

@ -28,7 +28,6 @@ package org.geysermc.connector.utils;
import com.github.steveice10.mc.protocol.data.game.entity.Effect; import com.github.steveice10.mc.protocol.data.game.entity.Effect;
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.entity.EntityDefinitions; import org.geysermc.connector.entity.EntityDefinitions;
@ -70,7 +69,7 @@ public final class EntityUtils {
} }
private static float getMountedHeightOffset(Entity mount) { private static float getMountedHeightOffset(Entity mount) {
float height = mount.getDirtyMetadata().getFloat(EntityData.BOUNDING_BOX_HEIGHT); float height = mount.getBoundingBoxHeight();
float mountedHeightOffset = height * 0.75f; float mountedHeightOffset = height * 0.75f;
switch (mount.getDefinition().entityType()) { switch (mount.getDefinition().entityType()) {
case CHICKEN, SPIDER -> mountedHeightOffset = height * 0.5f; case CHICKEN, SPIDER -> mountedHeightOffset = height * 0.5f;
@ -80,7 +79,7 @@ public final class EntityUtils {
MINECART_COMMAND_BLOCK -> mountedHeightOffset = 0; MINECART_COMMAND_BLOCK -> mountedHeightOffset = 0;
case BOAT -> mountedHeightOffset = -0.1f; case BOAT -> mountedHeightOffset = -0.1f;
case HOGLIN, ZOGLIN -> { case HOGLIN, ZOGLIN -> {
boolean isBaby = mount.getDirtyMetadata().getFlags().getFlag(EntityFlag.BABY); boolean isBaby = mount.getFlag(EntityFlag.BABY);
mountedHeightOffset = height - (isBaby ? 0.2f : 0.15f); mountedHeightOffset = height - (isBaby ? 0.2f : 0.15f);
} }
case PIGLIN -> mountedHeightOffset = height * 0.92f; case PIGLIN -> mountedHeightOffset = height * 0.92f;
@ -110,10 +109,10 @@ public final class EntityUtils {
case PIGLIN: case PIGLIN:
case PIGLIN_BRUTE: case PIGLIN_BRUTE:
case ZOMBIFIED_PIGLIN: case ZOMBIFIED_PIGLIN:
isBaby = passenger.getDirtyMetadata().getFlags().getFlag(EntityFlag.BABY); isBaby = passenger.getFlag(EntityFlag.BABY);
return isBaby ? -0.05f : -0.45f; return isBaby ? -0.05f : -0.45f;
case ZOMBIE: case ZOMBIE:
isBaby = passenger.getDirtyMetadata().getFlags().getFlag(EntityFlag.BABY); isBaby = passenger.getFlag(EntityFlag.BABY);
return isBaby ? 0.0f : -0.45f; return isBaby ? 0.0f : -0.45f;
case EVOKER: case EVOKER:
case ILLUSIONER: case ILLUSIONER:
@ -174,7 +173,7 @@ public final class EntityUtils {
MINECART_COMMAND_BLOCK, BOAT -> yOffset -= mount.getDefinition().height() * 0.5f; MINECART_COMMAND_BLOCK, BOAT -> yOffset -= mount.getDefinition().height() * 0.5f;
} }
Vector3f offset = Vector3f.from(xOffset, yOffset, zOffset); Vector3f offset = Vector3f.from(xOffset, yOffset, zOffset);
passenger.getDirtyMetadata().put(EntityData.RIDER_SEAT_POSITION, offset); passenger.setRiderSeatPosition(offset);
} }
passenger.updateBedrockMetadata(); passenger.updateBedrockMetadata();
} }

Datei anzeigen

@ -86,7 +86,7 @@ public class InteractiveTagManager {
// Holding a leash and the mob is leashable for sure // Holding a leash and the mob is leashable for sure
// (Plugins can change this behavior so that's something to look into in the far far future) // (Plugins can change this behavior so that's something to look into in the far far future)
interactiveTag = InteractiveTag.LEASH; interactiveTag = InteractiveTag.LEASH;
} else if (interactEntity instanceof AnimalEntity && ((AnimalEntity) interactEntity).canEat(session, javaIdentifierStripped, mapping)) { } else if (interactEntity instanceof AnimalEntity && ((AnimalEntity) interactEntity).canEat(javaIdentifierStripped, mapping)) {
// This animal can be fed // This animal can be fed
interactiveTag = InteractiveTag.FEED; interactiveTag = InteractiveTag.FEED;
} else { } else {