Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-20 06:50:09 +01:00
Entity refactor bug fixes and other 1.18 changes
Dieser Commit ist enthalten in:
Ursprung
11997ed82b
Commit
e0a7887f3f
@ -40,7 +40,7 @@ public class AbstractArrowEntity extends Entity {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ public class EnderCrystalEntity extends Entity {
|
||||
protected void initializeMetadata() {
|
||||
super.initializeMetadata();
|
||||
// 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) {
|
||||
|
@ -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.nukkitx.math.vector.Vector3f;
|
||||
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.EntityFlags;
|
||||
import com.nukkitx.protocol.bedrock.packet.AddEntityPacket;
|
||||
@ -83,13 +82,15 @@ public class Entity {
|
||||
protected float boundingBoxHeight;
|
||||
@Setter(AccessLevel.NONE)
|
||||
protected float boundingBoxWidth;
|
||||
@Setter(AccessLevel.NONE)
|
||||
protected String nametag = "";
|
||||
/* Metadata end */
|
||||
|
||||
protected LongOpenHashSet passengers = new LongOpenHashSet();
|
||||
/**
|
||||
* 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.
|
||||
* 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.setMotion(motion);
|
||||
addEntityPacket.setRotation(getBedrockRotation());
|
||||
addEntityPacket.setEntityType(definition.bedrockId());
|
||||
addEntityPacket.getMetadata().putFlags(flags)
|
||||
.putAll(dirtyMetadata);
|
||||
addEntityPacket.getMetadata().putFlags(flags);
|
||||
dirtyMetadata.apply(addEntityPacket.getMetadata());
|
||||
addAdditionalSpawnData(addEntityPacket);
|
||||
|
||||
valid = true;
|
||||
session.sendUpstreamPacket(addEntityPacket);
|
||||
|
||||
dirtyMetadata.clear();
|
||||
flagsDirty = false;
|
||||
|
||||
session.getConnector().getLogger().debug("Spawned entity " + getClass().getName() + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")");
|
||||
@ -293,15 +292,15 @@ public class Entity {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dirtyMetadata.isEmpty() || flagsDirty) {
|
||||
if (dirtyMetadata.hasEntries() || flagsDirty) {
|
||||
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
|
||||
entityDataPacket.setRuntimeEntityId(geyserId);
|
||||
entityDataPacket.getMetadata().putFlags(flags);
|
||||
entityDataPacket.getMetadata().putAll(dirtyMetadata);
|
||||
if (flagsDirty) {
|
||||
entityDataPacket.getMetadata().putFlags(flags);
|
||||
flagsDirty = false;
|
||||
}
|
||||
dirtyMetadata.apply(entityDataPacket.getMetadata());
|
||||
session.sendUpstreamPacket(entityDataPacket);
|
||||
|
||||
dirtyMetadata.clear();
|
||||
flagsDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -343,9 +342,9 @@ public class Entity {
|
||||
public void setDisplayName(EntityMetadata<Component> entityMetadata) {
|
||||
Component name = entityMetadata.getValue();
|
||||
if (name != null) {
|
||||
String displayName = MessageTranslator.convertMessage(name, session.getLocale());
|
||||
dirtyMetadata.put(EntityData.NAMETAG, displayName);
|
||||
} else if (!dirtyMetadata.getString(EntityData.NAMETAG).isEmpty()) { //TODO
|
||||
nametag = MessageTranslator.convertMessage(name, session.getLocale());
|
||||
dirtyMetadata.put(EntityData.NAMETAG, nametag);
|
||||
} else if (!nametag.isEmpty()) {
|
||||
// Clear nametag
|
||||
dirtyMetadata.put(EntityData.NAMETAG, "");
|
||||
}
|
||||
@ -376,14 +375,24 @@ public class Entity {
|
||||
*/
|
||||
protected void setDimensions(Pose pose) {
|
||||
// No flexibility options for basic entities
|
||||
if (boundingBoxHeight != definition.height() || boundingBoxWidth != definition.width()) {
|
||||
boundingBoxWidth = definition.width();
|
||||
boundingBoxHeight = definition.height();
|
||||
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, boundingBoxWidth);
|
||||
setBoundingBoxHeight(definition.height());
|
||||
setBoundingBoxWidth(definition.width());
|
||||
}
|
||||
|
||||
public void setBoundingBoxHeight(float height) {
|
||||
if (height != boundingBoxHeight) {
|
||||
boundingBoxHeight = height;
|
||||
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.
|
||||
*/
|
||||
@ -396,6 +405,10 @@ public class Entity {
|
||||
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.
|
||||
*
|
||||
|
@ -46,7 +46,7 @@ import java.util.function.BiConsumer;
|
||||
*
|
||||
* @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) {
|
||||
|
||||
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) {
|
||||
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) {
|
||||
@ -66,7 +66,6 @@ public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, Entit
|
||||
public static class Builder<T extends Entity> {
|
||||
private final EntityFactory<T> factory;
|
||||
private EntityType type;
|
||||
private int bedrockId;
|
||||
private String identifier;
|
||||
private float width;
|
||||
private float height;
|
||||
@ -78,10 +77,9 @@ public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, Entit
|
||||
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.type = type;
|
||||
this.bedrockId = bedrockId;
|
||||
this.identifier = identifier;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
@ -129,10 +127,10 @@ public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, Entit
|
||||
if (identifier == null && type != null) {
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||
import net.kyori.adventure.text.Component;
|
||||
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.PaintingEntityFactory;
|
||||
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.player.PlayerEntity;
|
||||
import org.geysermc.connector.network.translators.chat.MessageTranslator;
|
||||
import org.geysermc.connector.registry.Registries;
|
||||
|
||||
public final class EntityDefinitions {
|
||||
public static final EntityDefinition<AreaEffectCloudEntity> AREA_EFFECT_CLOUD;
|
||||
@ -192,7 +192,6 @@ public final class EntityDefinitions {
|
||||
{
|
||||
AREA_EFFECT_CLOUD = EntityDefinition.inherited(AreaEffectCloudEntity::new, entityBase)
|
||||
.type(EntityType.AREA_EFFECT_CLOUD)
|
||||
.bedrockId(95)
|
||||
.height(0.5f).width(1.0f)
|
||||
.addTranslator(MetadataType.FLOAT, AreaEffectCloudEntity::setRadius)
|
||||
.addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.EFFECT_COLOR, entityMetadata.getValue()))
|
||||
@ -201,7 +200,6 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
BOAT = EntityDefinition.inherited(BoatEntity::new, entityBase)
|
||||
.type(EntityType.BOAT)
|
||||
.bedrockId(90)
|
||||
.height(0.6f).width(1.6f)
|
||||
.offset(0.35f)
|
||||
.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();
|
||||
DRAGON_FIREBALL = EntityDefinition.inherited(ItemedFireballEntity::new, entityBase)
|
||||
.type(EntityType.DRAGON_FIREBALL)
|
||||
.bedrockId(79)
|
||||
.heightAndWidth(1.0f)
|
||||
.build();
|
||||
END_CRYSTAL = EntityDefinition.inherited(EnderCrystalEntity::new, entityBase)
|
||||
.type(EntityType.END_CRYSTAL)
|
||||
.bedrockId(71)
|
||||
.heightAndWidth(2.0f)
|
||||
.addTranslator(MetadataType.OPTIONAL_POSITION, EnderCrystalEntity::setBlockTarget)
|
||||
.<Boolean>addTranslator(MetadataType.BOOLEAN,
|
||||
@ -229,115 +225,94 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
EXPERIENCE_ORB = EntityDefinition.inherited((ExperienceOrbEntityFactory) ExpOrbEntity::new, entityBase)
|
||||
.type(EntityType.EXPERIENCE_ORB)
|
||||
.bedrockId(69)
|
||||
.identifier("minecraft:xp_orb")
|
||||
.build();
|
||||
EVOKER_FANGS = EntityDefinition.inherited(entityBase.factory(), entityBase)
|
||||
.type(EntityType.EVOKER_FANGS)
|
||||
.bedrockId(103)
|
||||
.height(0.8f).width(0.5f)
|
||||
.identifier("minecraft:evocation_fang")
|
||||
.build();
|
||||
EYE_OF_ENDER = EntityDefinition.inherited(Entity::new, entityBase)
|
||||
.type(EntityType.EYE_OF_ENDER)
|
||||
.bedrockId(70)
|
||||
.heightAndWidth(0.25f)
|
||||
.identifier("minecraft:eye_of_ender_signal")
|
||||
.build();
|
||||
FALLING_BLOCK = EntityDefinition.inherited(new EntityFactory<FallingBlockEntity>() {
|
||||
}, entityBase) // TODO
|
||||
FALLING_BLOCK = EntityDefinition.<FallingBlockEntity>inherited(null, entityBase)
|
||||
.type(EntityType.FALLING_BLOCK)
|
||||
.bedrockId(66)
|
||||
.heightAndWidth(0.98f)
|
||||
.addTranslator(null) // "start block position"
|
||||
.build();
|
||||
FIREBALL = EntityDefinition.inherited(ItemedFireballEntity::new, entityBase)
|
||||
.type(EntityType.FIREBALL)
|
||||
.bedrockId(85)
|
||||
.heightAndWidth(1.0f)
|
||||
.build();
|
||||
FIREWORK_ROCKET = EntityDefinition.inherited(FireworkEntity::new, entityBase)
|
||||
.type(EntityType.FIREWORK_ROCKET)
|
||||
.bedrockId(72)
|
||||
.heightAndWidth(0.25f)
|
||||
.identifier("minecraft:fireworks_rocket")
|
||||
.addTranslator(MetadataType.ITEM, FireworkEntity::setFireworkItem)
|
||||
.addTranslator(MetadataType.OPTIONAL_VARINT, FireworkEntity::setPlayerGliding)
|
||||
.build();
|
||||
FISHING_BOBBER = EntityDefinition.inherited(new EntityFactory<FishingHookEntity>() {
|
||||
}, entityBase) //TODO
|
||||
FISHING_BOBBER = EntityDefinition.<FishingHookEntity>inherited(null, entityBase)
|
||||
.type(EntityType.FISHING_BOBBER)
|
||||
.bedrockId(77)
|
||||
.identifier("minecraft:fishing_book")
|
||||
.addTranslator(MetadataType.INT, FishingHookEntity::setHookedEntity)
|
||||
.build();
|
||||
ITEM = EntityDefinition.inherited(ItemEntity::new, entityBase)
|
||||
.type(EntityType.ITEM)
|
||||
.bedrockId(64)
|
||||
.heightAndWidth(0.25f)
|
||||
.offset(0.125f)
|
||||
.addTranslator(MetadataType.ITEM, ItemEntity::setItem)
|
||||
.build();
|
||||
LEASH_KNOT = EntityDefinition.inherited(LeashKnotEntity::new, entityBase)
|
||||
.type(EntityType.LEASH_KNOT)
|
||||
.bedrockId(88)
|
||||
.height(0.5f).width(0.375f)
|
||||
.build();
|
||||
LIGHTNING_BOLT = EntityDefinition.inherited(LightningEntity::new, entityBase)
|
||||
.type(EntityType.LIGHTNING_BOLT)
|
||||
.bedrockId(93)
|
||||
.build();
|
||||
LLAMA_SPIT = EntityDefinition.inherited(ThrowableEntity::new, entityBase)
|
||||
.type(EntityType.LLAMA_SPIT)
|
||||
.bedrockId(102)
|
||||
.heightAndWidth(0.25f)
|
||||
.build();
|
||||
PAINTING = EntityDefinition.inherited((PaintingEntityFactory) PaintingEntity::new, entityBase)
|
||||
.type(EntityType.PAINTING)
|
||||
.bedrockId(83)
|
||||
.build();
|
||||
PRIMED_TNT = EntityDefinition.inherited(TNTEntity::new, entityBase)
|
||||
.type(EntityType.PRIMED_TNT)
|
||||
.bedrockId(65)
|
||||
.heightAndWidth(0.98f)
|
||||
.identifier("minecraft:tnt")
|
||||
.addTranslator(MetadataType.INT, TNTEntity::setFuseLength)
|
||||
.build();
|
||||
SHULKER_BULLET = EntityDefinition.inherited(ThrowableEntity::new, entityBase)
|
||||
.type(EntityType.SHULKER_BULLET)
|
||||
.bedrockId(76)
|
||||
.heightAndWidth(0.3125f)
|
||||
.build();
|
||||
SMALL_FIREBALL = EntityDefinition.inherited(ItemedFireballEntity::new, entityBase)
|
||||
.type(EntityType.SMALL_FIREBALL)
|
||||
.bedrockId(94)
|
||||
.heightAndWidth(0.3125f)
|
||||
.build();
|
||||
SNOWBALL = EntityDefinition.inherited(ThrowableItemEntity::new, entityBase)
|
||||
.type(EntityType.SNOWBALL)
|
||||
.bedrockId(81)
|
||||
.heightAndWidth(0.25f)
|
||||
.build();
|
||||
THROWN_ENDERPEARL = EntityDefinition.inherited(ThrowableItemEntity::new, entityBase)
|
||||
.type(EntityType.THROWN_ENDERPEARL)
|
||||
.bedrockId(87)
|
||||
.heightAndWidth(0.25f)
|
||||
.identifier("minecraft:ender_pearl")
|
||||
.build();
|
||||
THROWN_EGG = EntityDefinition.inherited(ThrowableItemEntity::new, entityBase)
|
||||
.type(EntityType.THROWN_EGG)
|
||||
.bedrockId(82)
|
||||
.heightAndWidth(0.25f)
|
||||
.identifier("minecraft:egg")
|
||||
.build();
|
||||
THROWN_EXP_BOTTLE = EntityDefinition.inherited(ThrowableItemEntity::new, entityBase)
|
||||
.type(EntityType.THROWN_EXP_BOTTLE)
|
||||
.bedrockId(68)
|
||||
.heightAndWidth(0.25f)
|
||||
.identifier("minecraft:xp_bottle")
|
||||
.build();
|
||||
THROWN_POTION = EntityDefinition.inherited(ThrownPotionEntity::new, entityBase)
|
||||
.type(EntityType.THROWN_POTION)
|
||||
.bedrockId(86)
|
||||
.heightAndWidth(0.25f)
|
||||
.identifier("minecraft:splash_potion")
|
||||
.addTranslator(MetadataType.ITEM, ThrownPotionEntity::setPotion)
|
||||
@ -349,30 +324,26 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
ARROW = EntityDefinition.inherited(TippedArrowEntity::new, abstractArrowBase)
|
||||
.type(EntityType.ARROW)
|
||||
.bedrockId(80)
|
||||
.heightAndWidth(0.25f)
|
||||
.addTranslator(MetadataType.INT, TippedArrowEntity::setPotionEffectColor)
|
||||
.build();
|
||||
SPECTRAL_ARROW = EntityDefinition.inherited(abstractArrowBase.factory(), abstractArrowBase)
|
||||
.type(EntityType.SPECTRAL_ARROW)
|
||||
.bedrockId(80)
|
||||
.heightAndWidth(0.25f)
|
||||
.identifier("minecraft:arrow")
|
||||
.build();
|
||||
TRIDENT = EntityDefinition.inherited(TridentEntity::new, abstractArrowBase) // TODO remove class
|
||||
.type(EntityType.TRIDENT)
|
||||
.bedrockId(73)
|
||||
.identifier("minecraft:thrown_trident")
|
||||
.addTranslator(null) // Loyalty
|
||||
.<Boolean>addTranslator(MetadataType.BOOLEAN, (tridentEntity, entityMetadata) -> tridentEntity.setFlag(EntityFlag.ENCHANTED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
|
||||
.build();
|
||||
|
||||
// Item frames are handled differently as they are blocks, not items, in Bedrock
|
||||
ITEM_FRAME = EntityDefinition.inherited(new EntityFactory<ItemFrameEntity>() {
|
||||
}, entityBase) // TODO
|
||||
ITEM_FRAME = EntityDefinition.<ItemFrameEntity>inherited(null, entityBase)
|
||||
.type(EntityType.ITEM_FRAME)
|
||||
.addTranslator(MetadataType.ITEM, ItemFrameEntity::setItemInFrame)
|
||||
.addTranslator(MetadataType.ITEM, ItemFrameEntity::setItemRotation)
|
||||
.addTranslator(MetadataType.INT, ItemFrameEntity::setItemRotation)
|
||||
.build();
|
||||
GLOW_ITEM_FRAME = EntityDefinition.inherited(ITEM_FRAME.factory(), ITEM_FRAME)
|
||||
.type(EntityType.GLOW_ITEM_FRAME)
|
||||
@ -380,7 +351,6 @@ public final class EntityDefinitions {
|
||||
|
||||
MINECART = EntityDefinition.inherited(MinecartEntity::new, entityBase)
|
||||
.type(EntityType.MINECART)
|
||||
.bedrockId(84)
|
||||
.height(0.7f).width(0.98f)
|
||||
.offset(0.35f)
|
||||
.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) ->
|
||||
// Power in Java, time in Bedrock
|
||||
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.BOOLEAN, MinecartEntity::setShowCustomBlock)
|
||||
.build();
|
||||
@ -398,7 +368,6 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
MINECART_COMMAND_BLOCK = EntityDefinition.inherited(CommandBlockMinecartEntity::new, MINECART)
|
||||
.type(EntityType.MINECART_COMMAND_BLOCK)
|
||||
.bedrockId(100)
|
||||
.identifier("minecraft:command_block_minecart")
|
||||
.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())))
|
||||
@ -423,30 +392,27 @@ public final class EntityDefinitions {
|
||||
|
||||
WITHER_SKULL = EntityDefinition.inherited(WitherSkullEntity::new, entityBase)
|
||||
.type(EntityType.WITHER_SKULL)
|
||||
.bedrockId(89)
|
||||
.heightAndWidth(0.3125f)
|
||||
.addTranslator(MetadataType.BOOLEAN, WitherSkullEntity::setDangerous)
|
||||
.build();
|
||||
WITHER_SKULL_DANGEROUS = EntityDefinition.inherited(WITHER_SKULL.factory(), WITHER_SKULL)
|
||||
.bedrockId(91)
|
||||
.build(false);
|
||||
}
|
||||
|
||||
EntityDefinition<LivingEntity> livingEntityBase = EntityDefinition.inherited(LivingEntity::new, entityBase)
|
||||
.addTranslator(MetadataType.BYTE, LivingEntity::setLivingEntityFlags)
|
||||
.addTranslator(MetadataType.FLOAT, LivingEntity::setHealth)
|
||||
.<Float>addTranslator(MetadataType.FLOAT,
|
||||
.<Float>addTranslator(MetadataType.INT,
|
||||
(livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityData.EFFECT_COLOR, entityMetadata.getValue()))
|
||||
.<Boolean>addTranslator(MetadataType.BOOLEAN,
|
||||
(livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityData.EFFECT_AMBIENT, (byte) (((BooleanEntityMetadata) entityMetadata).getPrimitiveValue() ? 1 : 0)))
|
||||
.addTranslator(null) // Arrow count
|
||||
.addTranslator(null) // Stinger count
|
||||
.addTranslator(MetadataType.POSITION, LivingEntity::setBedPosition)
|
||||
.addTranslator(MetadataType.OPTIONAL_POSITION, LivingEntity::setBedPosition)
|
||||
.build();
|
||||
|
||||
ARMOR_STAND = EntityDefinition.inherited(ArmorStandEntity::new, livingEntityBase)
|
||||
.type(EntityType.ARMOR_STAND)
|
||||
.bedrockId(61)
|
||||
.height(1.975f).width(0.5f)
|
||||
.addTranslator(MetadataType.BYTE, ArmorStandEntity::setArmorStandFlags)
|
||||
.addTranslator(MetadataType.ROTATION, ArmorStandEntity::setHeadRotation)
|
||||
@ -458,7 +424,6 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
PLAYER = EntityDefinition.<PlayerEntity>inherited(null, livingEntityBase)
|
||||
.type(EntityType.PLAYER)
|
||||
.bedrockId(63)
|
||||
.height(1.8f).width(0.6f)
|
||||
.offset(1.62f)
|
||||
.addTranslator(MetadataType.FLOAT, PlayerEntity::setAbsorptionHearts)
|
||||
@ -477,24 +442,20 @@ public final class EntityDefinitions {
|
||||
{
|
||||
BAT = EntityDefinition.inherited(BatEntity::new, mobEntityBase)
|
||||
.type(EntityType.BAT)
|
||||
.bedrockId(19)
|
||||
.height(0.9f).width(0.5f)
|
||||
.addTranslator(MetadataType.BYTE, BatEntity::setBatFlags)
|
||||
.build();
|
||||
BLAZE = EntityDefinition.inherited(BlazeEntity::new, mobEntityBase)
|
||||
.type(EntityType.BLAZE)
|
||||
.bedrockId(43)
|
||||
.height(1.8f).width(0.6f)
|
||||
.addTranslator(MetadataType.BYTE, BlazeEntity::setBlazeFlags)
|
||||
.build();
|
||||
CAVE_SPIDER = EntityDefinition.inherited(MonsterEntity::new, mobEntityBase)
|
||||
.type(EntityType.CAVE_SPIDER)
|
||||
.bedrockId(40)
|
||||
.height(0.5f).width(0.7f)
|
||||
.build();
|
||||
CREEPER = EntityDefinition.inherited(CreeperEntity::new, mobEntityBase)
|
||||
.type(EntityType.CREEPER)
|
||||
.bedrockId(33)
|
||||
.height(1.7f).width(0.6f)
|
||||
.offset(1.62f)
|
||||
.addTranslator(MetadataType.INT, CreeperEntity::setSwelling)
|
||||
@ -503,7 +464,6 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
DOLPHIN = EntityDefinition.inherited(WaterEntity::new, mobEntityBase)
|
||||
.type(EntityType.DOLPHIN)
|
||||
.bedrockId(31)
|
||||
.height(0.6f).width(0.9f)
|
||||
//TODO check
|
||||
.addTranslator(null) // treasure position
|
||||
@ -512,7 +472,6 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
ENDERMAN = EntityDefinition.inherited(EndermanEntity::new, mobEntityBase)
|
||||
.type(EntityType.ENDERMAN)
|
||||
.bedrockId(38)
|
||||
.height(2.9f).width(0.6f)
|
||||
.addTranslator(MetadataType.BLOCK_STATE, EndermanEntity::setCarriedBlock)
|
||||
.addTranslator(MetadataType.BOOLEAN, EndermanEntity::setScreaming)
|
||||
@ -520,47 +479,40 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
ENDERMITE = EntityDefinition.inherited(MonsterEntity::new, mobEntityBase)
|
||||
.type(EntityType.ENDERMITE)
|
||||
.bedrockId(55)
|
||||
.height(0.3f).width(0.4f)
|
||||
.build();
|
||||
ENDER_DRAGON = EntityDefinition.inherited(EnderDragonEntity::new, mobEntityBase)
|
||||
.type(EntityType.ENDER_DRAGON)
|
||||
.bedrockId(53)
|
||||
.addTranslator(MetadataType.INT, EnderDragonEntity::setPhase)
|
||||
.build();
|
||||
GHAST = EntityDefinition.inherited(GhastEntity::new, mobEntityBase)
|
||||
.type(EntityType.GHAST)
|
||||
.bedrockId(41)
|
||||
.heightAndWidth(4.0f)
|
||||
.addTranslator(MetadataType.BOOLEAN, GhastEntity::setGhastAttacking)
|
||||
.build();
|
||||
GIANT = EntityDefinition.inherited(GiantEntity::new, mobEntityBase)
|
||||
.type(EntityType.GIANT)
|
||||
.bedrockId(32)
|
||||
.height(1.8f).width(1.6f)
|
||||
.offset(1.62f)
|
||||
.identifier("minecraft:zombie")
|
||||
.build();
|
||||
IRON_GOLEM = EntityDefinition.inherited(IronGolemEntity::new, mobEntityBase)
|
||||
.type(EntityType.IRON_GOLEM)
|
||||
.bedrockId(20)
|
||||
.height(2.7f).width(1.4f)
|
||||
.addTranslator(null) // "is player created", which doesn't seem to do anything clientside
|
||||
.build();
|
||||
PHANTOM = EntityDefinition.inherited(PhantomEntity::new, mobEntityBase)
|
||||
.type(EntityType.PHANTOM)
|
||||
.bedrockId(58)
|
||||
.height(0.5f).width(0.9f)
|
||||
.offset(0.6f)
|
||||
.addTranslator(MetadataType.INT, PhantomEntity::setPhantomScale)
|
||||
.build();
|
||||
SILVERFISH = EntityDefinition.inherited(MonsterEntity::new, mobEntityBase)
|
||||
.type(EntityType.SILVERFISH)
|
||||
.bedrockId(39)
|
||||
.height(0.3f).width(0.4f)
|
||||
.build();
|
||||
SHULKER = EntityDefinition.inherited(ShulkerEntity::new, mobEntityBase)
|
||||
.type(EntityType.SHULKER)
|
||||
.bedrockId(54)
|
||||
.heightAndWidth(1f)
|
||||
.addTranslator(MetadataType.DIRECTION, ShulkerEntity::setAttachedFace)
|
||||
.addTranslator(MetadataType.BYTE, ShulkerEntity::setShulkerHeight)
|
||||
@ -568,44 +520,37 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
SKELETON = EntityDefinition.inherited(SkeletonEntity::new, mobEntityBase)
|
||||
.type(EntityType.SKELETON)
|
||||
.bedrockId(34)
|
||||
.height(1.8f).width(0.6f)
|
||||
.offset(1.62f)
|
||||
.addTranslator(MetadataType.BOOLEAN, SkeletonEntity::setConvertingToStray)
|
||||
.build();
|
||||
SNOW_GOLEM = EntityDefinition.inherited(SnowGolemEntity::new, mobEntityBase)
|
||||
.type(EntityType.SNOW_GOLEM)
|
||||
.bedrockId(21)
|
||||
.height(1.9f).width(0.7f)
|
||||
.addTranslator(MetadataType.BYTE, SnowGolemEntity::setSnowGolemFlags)
|
||||
.build();
|
||||
SPIDER = EntityDefinition.inherited(SpiderEntity::new, mobEntityBase)
|
||||
.type(EntityType.SPIDER)
|
||||
.bedrockId(35)
|
||||
.height(0.9f).width(1.4f)
|
||||
.offset(1f)
|
||||
.addTranslator(MetadataType.BYTE, SpiderEntity::setSpiderFlags)
|
||||
.build();
|
||||
SQUID = EntityDefinition.inherited(SquidEntity::new, mobEntityBase)
|
||||
.type(EntityType.SQUID)
|
||||
.bedrockId(17)
|
||||
.heightAndWidth(0.8f)
|
||||
.build();
|
||||
STRAY = EntityDefinition.inherited(AbstractSkeletonEntity::new, mobEntityBase)
|
||||
.type(EntityType.STRAY)
|
||||
.bedrockId(46)
|
||||
.height(1.8f).width(0.6f)
|
||||
.offset(1.62f)
|
||||
.build();
|
||||
VEX = EntityDefinition.inherited(VexEntity::new, mobEntityBase)
|
||||
.type(EntityType.VEX)
|
||||
.bedrockId(105)
|
||||
.height(0.8f).width(0.4f)
|
||||
.addTranslator(MetadataType.BYTE, VexEntity::setVexFlags)
|
||||
.build();
|
||||
WITHER = EntityDefinition.inherited(WitherEntity::new, mobEntityBase)
|
||||
.type(EntityType.WITHER)
|
||||
.bedrockId(52)
|
||||
.height(3.5f).width(0.9f)
|
||||
.addTranslator(MetadataType.INT, WitherEntity::setTarget1)
|
||||
.addTranslator(MetadataType.INT, WitherEntity::setTarget2)
|
||||
@ -614,18 +559,15 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
WITHER_SKELETON = EntityDefinition.inherited(AbstractSkeletonEntity::new, mobEntityBase)
|
||||
.type(EntityType.WITHER_SKELETON)
|
||||
.bedrockId(48)
|
||||
.height(2.4f).width(0.7f)
|
||||
.build();
|
||||
ZOGLIN = EntityDefinition.inherited(ZoglinEntity::new, mobEntityBase)
|
||||
.type(EntityType.ZOGLIN)
|
||||
.bedrockId(126)
|
||||
.height(1.4f).width(1.3965f)
|
||||
.addTranslator(MetadataType.BOOLEAN, ZoglinEntity::setBaby)
|
||||
.build();
|
||||
ZOMBIE = EntityDefinition.inherited(ZombieEntity::new, mobEntityBase)
|
||||
.type(EntityType.ZOMBIE)
|
||||
.bedrockId(32)
|
||||
.height(1.8f).width(0.6f)
|
||||
.offset(1.62f)
|
||||
.addTranslator(MetadataType.BOOLEAN, ZombieEntity::setZombieBaby)
|
||||
@ -634,7 +576,6 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
ZOMBIE_VILLAGER = EntityDefinition.inherited(ZombieVillagerEntity::new, ZOMBIE)
|
||||
.type(EntityType.ZOMBIE_VILLAGER)
|
||||
.bedrockId(44)
|
||||
.height(1.8f).width(0.6f)
|
||||
.offset(1.62f)
|
||||
.identifier("minecraft:zombie_villager_v2")
|
||||
@ -643,7 +584,6 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
ZOMBIFIED_PIGLIN = EntityDefinition.inherited(ZombifiedPiglinEntity::new, ZOMBIE) //TODO test how zombie entity metadata is handled?
|
||||
.type(EntityType.ZOMBIFIED_PIGLIN)
|
||||
.bedrockId(36)
|
||||
.height(1.95f).width(0.6f)
|
||||
.offset(1.62f)
|
||||
.identifier("minecraft:zombie_pigman")
|
||||
@ -651,36 +591,30 @@ public final class EntityDefinitions {
|
||||
|
||||
DROWNED = EntityDefinition.inherited(ZOMBIE.factory(), ZOMBIE)
|
||||
.type(EntityType.DROWNED)
|
||||
.bedrockId(110)
|
||||
.height(1.95f).width(0.6f)
|
||||
.build();
|
||||
HUSK = EntityDefinition.inherited(ZOMBIE.factory(), ZOMBIE)
|
||||
.type(EntityType.HUSK)
|
||||
.bedrockId(47)
|
||||
.build();
|
||||
|
||||
GUARDIAN = EntityDefinition.inherited(GuardianEntity::new, mobEntityBase)
|
||||
.type(EntityType.GUARDIAN)
|
||||
.bedrockId(49)
|
||||
.heightAndWidth(0.85f)
|
||||
.addTranslator(null) // Moving //TODO
|
||||
.addTranslator(MetadataType.INT, GuardianEntity::setGuardianTarget)
|
||||
.build();
|
||||
ELDER_GUARDIAN = EntityDefinition.inherited(ElderGuardianEntity::new, GUARDIAN)
|
||||
.type(EntityType.ELDER_GUARDIAN)
|
||||
.bedrockId(50)
|
||||
.heightAndWidth(1.9975f)
|
||||
.build();
|
||||
|
||||
SLIME = EntityDefinition.inherited(SlimeEntity::new, mobEntityBase)
|
||||
.type(EntityType.SLIME)
|
||||
.bedrockId(37)
|
||||
.heightAndWidth(0.51f)
|
||||
.addTranslator(MetadataType.INT, SlimeEntity::setScale)
|
||||
.build();
|
||||
MAGMA_CUBE = EntityDefinition.inherited(MagmaCubeEntity::new, SLIME)
|
||||
.type(EntityType.MAGMA_CUBE)
|
||||
.bedrockId(42)
|
||||
.build();
|
||||
|
||||
EntityDefinition<AbstractFishEntity> abstractFishEntityBase = EntityDefinition.inherited(AbstractFishEntity::new, mobEntityBase)
|
||||
@ -688,25 +622,22 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
COD = EntityDefinition.inherited(abstractFishEntityBase.factory(), abstractFishEntityBase)
|
||||
.type(EntityType.COD)
|
||||
.bedrockId(112)
|
||||
.height(0.25f).width(0.5f)
|
||||
.build();
|
||||
PUFFERFISH = EntityDefinition.inherited(PufferFishEntity::new, abstractFishEntityBase)
|
||||
.type(EntityType.PUFFERFISH)
|
||||
.bedrockId(108)
|
||||
.heightAndWidth(0.7f)
|
||||
.addTranslator(MetadataType.INT, PufferFishEntity::setPufferfishSize)
|
||||
.build();
|
||||
SALMON = EntityDefinition.inherited(abstractFishEntityBase.factory(), abstractFishEntityBase)
|
||||
.type(EntityType.SALMON)
|
||||
.bedrockId(109)
|
||||
.height(0.5f).width(0.7f)
|
||||
.build();
|
||||
TROPICAL_FISH = EntityDefinition.inherited(TropicalFishEntity::new, abstractFishEntityBase)
|
||||
.type(EntityType.TROPICAL_FISH)
|
||||
.bedrockId(111)
|
||||
.heightAndWidth(0.6f)
|
||||
.identifier("minecraft:tropicalfish")
|
||||
.addTranslator(MetadataType.INT, TropicalFishEntity::setFishVariant)
|
||||
.build();
|
||||
|
||||
EntityDefinition<BasePiglinEntity> abstractPiglinEntityBase = EntityDefinition.inherited(BasePiglinEntity::new, mobEntityBase)
|
||||
@ -714,7 +645,6 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
PIGLIN = EntityDefinition.inherited(PiglinEntity::new, abstractPiglinEntityBase)
|
||||
.type(EntityType.PIGLIN)
|
||||
.bedrockId(123)
|
||||
.height(1.95f).width(0.6f)
|
||||
.addTranslator(MetadataType.BOOLEAN, PiglinEntity::setBaby)
|
||||
.addTranslator(MetadataType.BOOLEAN, PiglinEntity::setChargingCrossbow)
|
||||
@ -722,7 +652,6 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
PIGLIN_BRUTE = EntityDefinition.inherited(abstractPiglinEntityBase.factory(), abstractPiglinEntityBase)
|
||||
.type(EntityType.PIGLIN_BRUTE)
|
||||
.bedrockId(127)
|
||||
.height(1.95f).width(0.6f)
|
||||
.build();
|
||||
|
||||
@ -739,37 +668,31 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
EVOKER = EntityDefinition.inherited(spellcasterEntityBase.factory(), spellcasterEntityBase)
|
||||
.type(EntityType.EVOKER)
|
||||
.bedrockId(104)
|
||||
.height(1.95f).width(0.6f)
|
||||
.identifier("minecraft:evocation_illager")
|
||||
.build();
|
||||
ILLUSIONER = EntityDefinition.inherited(spellcasterEntityBase.factory(), spellcasterEntityBase)
|
||||
.type(EntityType.ILLUSIONER)
|
||||
.bedrockId(104)
|
||||
.height(1.95f).width(0.6f)
|
||||
.identifier("minecraft:evocation_illager")
|
||||
.build();
|
||||
PILLAGER = EntityDefinition.inherited(PillagerEntity::new, raidParticipantEntityBase)
|
||||
.type(EntityType.PILLAGER)
|
||||
.bedrockId(114)
|
||||
.height(1.8f).width(0.6f)
|
||||
.offset(1.62f)
|
||||
.addTranslator(null) // Charging; doesn't have an equivalent on Bedrock //TODO check
|
||||
.build();
|
||||
RAVAGER = EntityDefinition.inherited(raidParticipantEntityBase.factory(), raidParticipantEntityBase)
|
||||
.type(EntityType.RAVAGER)
|
||||
.bedrockId(59)
|
||||
.height(1.9f).width(1.2f)
|
||||
.build();
|
||||
VINDICATOR = EntityDefinition.inherited(VindicatorEntity::new, raidParticipantEntityBase)
|
||||
.type(EntityType.VINDICATOR)
|
||||
.bedrockId(57)
|
||||
.height(1.8f).width(0.6f)
|
||||
.offset(1.62f)
|
||||
.build();
|
||||
WITCH = EntityDefinition.inherited(raidParticipantEntityBase.factory(), raidParticipantEntityBase)
|
||||
.type(EntityType.WITCH)
|
||||
.bedrockId(45)
|
||||
.height(1.8f).width(0.6f)
|
||||
.offset(1.62f)
|
||||
.build();
|
||||
@ -786,34 +709,30 @@ public final class EntityDefinitions {
|
||||
.height(0.42f).width(0.7f)
|
||||
.addTranslator(MetadataType.INT, AxolotlEntity::setVariant)
|
||||
.addTranslator(MetadataType.BOOLEAN, AxolotlEntity::setPlayingDead)
|
||||
.addTranslator(null) // From bucket
|
||||
.build();
|
||||
BEE = EntityDefinition.inherited(BeeEntity::new, ageableEntityBase)
|
||||
.type(EntityType.BEE)
|
||||
.bedrockId(122)
|
||||
.heightAndWidth(0.6f)
|
||||
.addTranslator(MetadataType.BYTE, BeeEntity::setBeeFlags)
|
||||
.addTranslator(MetadataType.INT, BeeEntity::setAngerTime)
|
||||
.build();
|
||||
CHICKEN = EntityDefinition.inherited(ChickenEntity::new, ageableEntityBase)
|
||||
.type(EntityType.CHICKEN)
|
||||
.bedrockId(10)
|
||||
.height(0.7f).width(0.4f)
|
||||
.build();
|
||||
COW = EntityDefinition.inherited(AnimalEntity::new, ageableEntityBase)
|
||||
.type(EntityType.COW)
|
||||
.bedrockId(11)
|
||||
.height(1.4f).width(0.9f)
|
||||
.build();
|
||||
FOX = EntityDefinition.inherited(FoxEntity::new, ageableEntityBase)
|
||||
.type(EntityType.FOX)
|
||||
.bedrockId(121)
|
||||
.height(0.5f).width(1.25f)
|
||||
.addTranslator(MetadataType.INT, FoxEntity::setFoxVariant)
|
||||
.addTranslator(MetadataType.BYTE, FoxEntity::setFoxFlags)
|
||||
.build();
|
||||
HOGLIN = EntityDefinition.inherited(HoglinEntity::new, ageableEntityBase)
|
||||
.type(EntityType.HOGLIN)
|
||||
.bedrockId(124)
|
||||
.height(1.4f).width(1.3965f)
|
||||
.addTranslator(MetadataType.BOOLEAN, HoglinEntity::setImmuneToZombification)
|
||||
.build();
|
||||
@ -824,19 +743,16 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
MOOSHROOM = EntityDefinition.inherited(MooshroomEntity::new, ageableEntityBase) // TODO remove class
|
||||
.type(EntityType.MOOSHROOM)
|
||||
.bedrockId(16)
|
||||
.height(1.4f).width(0.9f)
|
||||
.<String>addTranslator(MetadataType.STRING, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.VARIANT, entityMetadata.getValue().equals("brown") ? 1 : 0))
|
||||
.build();
|
||||
OCELOT = EntityDefinition.inherited(OcelotEntity::new, ageableEntityBase)
|
||||
.type(EntityType.OCELOT)
|
||||
.bedrockId(22)
|
||||
.height(0.35f).width(0.3f)
|
||||
.<Boolean>addTranslator(MetadataType.BOOLEAN, (ocelotEntity, entityMetadata) -> ocelotEntity.setFlag(EntityFlag.TRUSTING, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
|
||||
.build();
|
||||
PANDA = EntityDefinition.inherited(PandaEntity::new, ageableEntityBase)
|
||||
.type(EntityType.PANDA)
|
||||
.bedrockId(113)
|
||||
.height(1.25f).width(1.125f)
|
||||
.addTranslator(null) // Unhappy counter
|
||||
.addTranslator(null) // Sneeze counter
|
||||
@ -847,32 +763,27 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
PIG = EntityDefinition.inherited(PigEntity::new, ageableEntityBase)
|
||||
.type(EntityType.PIG)
|
||||
.bedrockId(12)
|
||||
.heightAndWidth(0.9f)
|
||||
.<Boolean>addTranslator(MetadataType.BOOLEAN, (pigEntity, entityMetadata) -> pigEntity.setFlag(EntityFlag.SADDLED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
|
||||
.addTranslator(null) // Boost time
|
||||
.build();
|
||||
POLAR_BEAR = EntityDefinition.inherited(PolarBearEntity::new, ageableEntityBase)
|
||||
.type(EntityType.POLAR_BEAR)
|
||||
.bedrockId(28)
|
||||
.height(1.4f).width(1.3f)
|
||||
.<Boolean>addTranslator(MetadataType.BOOLEAN, (entity, entityMetadata) -> entity.setFlag(EntityFlag.STANDING, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
|
||||
.build();
|
||||
RABBIT = EntityDefinition.inherited(RabbitEntity::new, ageableEntityBase)
|
||||
.type(EntityType.RABBIT)
|
||||
.bedrockId(18)
|
||||
.height(0.5f).width(0.4f)
|
||||
.addTranslator(MetadataType.INT, RabbitEntity::setRabbitVariant)
|
||||
.build();
|
||||
SHEEP = EntityDefinition.inherited(SheepEntity::new, ageableEntityBase)
|
||||
.type(EntityType.SHEEP)
|
||||
.bedrockId(13)
|
||||
.heightAndWidth(0.9f)
|
||||
.addTranslator(MetadataType.BYTE, SheepEntity::setSheepFlags)
|
||||
.build();
|
||||
STRIDER = EntityDefinition.inherited(StriderEntity::new, ageableEntityBase)
|
||||
.type(EntityType.STRIDER)
|
||||
.bedrockId(125)
|
||||
.height(1.7f).width(0.9f)
|
||||
.addTranslator(null) // Boost time
|
||||
.addTranslator(MetadataType.BOOLEAN, StriderEntity::setCold)
|
||||
@ -880,7 +791,6 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
TURTLE = EntityDefinition.inherited(TurtleEntity::new, ageableEntityBase)
|
||||
.type(EntityType.TURTLE)
|
||||
.bedrockId(74)
|
||||
.height(0.4f).width(1.2f)
|
||||
.addTranslator(MetadataType.BOOLEAN, TurtleEntity::setPregnant)
|
||||
.addTranslator(MetadataType.BOOLEAN, TurtleEntity::setLayingEgg)
|
||||
@ -891,7 +801,6 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
VILLAGER = EntityDefinition.inherited(VillagerEntity::new, abstractVillagerEntityBase)
|
||||
.type(EntityType.VILLAGER)
|
||||
.bedrockId(15)
|
||||
.height(1.8f).width(0.6f)
|
||||
.offset(1.62f)
|
||||
.identifier("minecraft:villager_v2")
|
||||
@ -899,7 +808,6 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
WANDERING_TRADER = EntityDefinition.inherited(abstractVillagerEntityBase.factory(), abstractVillagerEntityBase)
|
||||
.type(EntityType.WANDERING_TRADER)
|
||||
.bedrockId(118)
|
||||
.height(1.8f).width(0.6f)
|
||||
.offset(1.62f)
|
||||
.build();
|
||||
@ -913,18 +821,15 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
HORSE = EntityDefinition.inherited(HorseEntity::new, abstractHorseEntityBase)
|
||||
.type(EntityType.HORSE)
|
||||
.bedrockId(23)
|
||||
.height(1.6f).width(1.3965f)
|
||||
.addTranslator(MetadataType.BYTE, HorseEntity::setHorseVariant)
|
||||
.addTranslator(MetadataType.INT, HorseEntity::setHorseVariant)
|
||||
.build();
|
||||
SKELETON_HORSE = EntityDefinition.inherited(abstractHorseEntityBase.factory(), abstractHorseEntityBase)
|
||||
.type(EntityType.SKELETON_HORSE)
|
||||
.bedrockId(26)
|
||||
.height(1.6f).width(1.3965f)
|
||||
.build();
|
||||
ZOMBIE_HORSE = EntityDefinition.inherited(abstractHorseEntityBase.factory(), abstractHorseEntityBase)
|
||||
.type(EntityType.ZOMBIE_HORSE)
|
||||
.bedrockId(27)
|
||||
.height(1.6f).width(1.3965f)
|
||||
.build();
|
||||
EntityDefinition<ChestedHorseEntity> chestedHorseEntityBase = EntityDefinition.inherited(ChestedHorseEntity::new, abstractHorseEntityBase)
|
||||
@ -932,17 +837,14 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
DONKEY = EntityDefinition.inherited(chestedHorseEntityBase.factory(), chestedHorseEntityBase)
|
||||
.type(EntityType.DONKEY)
|
||||
.bedrockId(24)
|
||||
.height(1.6f).width(1.3965f)
|
||||
.build();
|
||||
MULE = EntityDefinition.inherited(chestedHorseEntityBase.factory(), chestedHorseEntityBase)
|
||||
.type(EntityType.MULE)
|
||||
.bedrockId(25)
|
||||
.height(1.6f).width(1.3965f)
|
||||
.build();
|
||||
LLAMA = EntityDefinition.inherited(LlamaEntity::new, chestedHorseEntityBase)
|
||||
.type(EntityType.LLAMA)
|
||||
.bedrockId(29)
|
||||
.height(1.87f).width(0.9f)
|
||||
.<Integer>addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityData.STRENGTH, entityMetadata.getValue()))
|
||||
.addTranslator(MetadataType.INT, LlamaEntity::setCarpetedColor)
|
||||
@ -960,7 +862,6 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
CAT = EntityDefinition.inherited(CatEntity::new, tameableEntityBase)
|
||||
.type(EntityType.CAT)
|
||||
.bedrockId(75)
|
||||
.height(0.35f).width(0.3f)
|
||||
.addTranslator(MetadataType.INT, CatEntity::setCatVariant)
|
||||
.addTranslator(MetadataType.BOOLEAN, CatEntity::setResting)
|
||||
@ -969,13 +870,11 @@ public final class EntityDefinitions {
|
||||
.build();
|
||||
PARROT = EntityDefinition.inherited(ParrotEntity::new, tameableEntityBase)
|
||||
.type(EntityType.PARROT)
|
||||
.bedrockId(30)
|
||||
.height(0.9f).width(0.5f)
|
||||
.addTranslator(MetadataType.INT, (parrotEntity, entityMetadata) -> parrotEntity.getDirtyMetadata().put(EntityData.VARIANT, entityMetadata.getValue())) // Parrot color
|
||||
.build();
|
||||
WOLF = EntityDefinition.inherited(WolfEntity::new, tameableEntityBase)
|
||||
.type(EntityType.WOLF)
|
||||
.bedrockId(14)
|
||||
.height(0.85f).width(0.6f)
|
||||
// "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()))
|
||||
@ -985,9 +884,10 @@ public final class EntityDefinitions {
|
||||
|
||||
// As of 1.18 these don't track entity data at all
|
||||
ENDER_DRAGON_PART = EntityDefinition.<EnderDragonPartEntity>builder(null)
|
||||
.bedrockId(32)
|
||||
.identifier("minecraft:armor_stand") // Emulated
|
||||
.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() {
|
||||
|
@ -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.EntityFlag;
|
||||
import com.nukkitx.protocol.bedrock.packet.PlaySoundPacket;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.connector.entity.player.PlayerEntity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.collision.BoundingBox;
|
||||
@ -46,11 +47,15 @@ import java.util.concurrent.ThreadLocalRandom;
|
||||
public class FishingHookEntity extends ThrowableEntity {
|
||||
|
||||
private boolean hooked = false;
|
||||
private boolean inWater = false;
|
||||
|
||||
@Getter
|
||||
private final boolean isOwnerSessionPlayer;
|
||||
@Getter
|
||||
private long bedrockTargetId;
|
||||
|
||||
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) {
|
||||
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.
|
||||
// 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.
|
||||
this.dirtyMetadata.putFloat(EntityData.BOUNDING_BOX_HEIGHT, 128);
|
||||
setBoundingBoxHeight(128);
|
||||
|
||||
isOwnerSessionPlayer = owner.getGeyserId() == session.getPlayerEntity().getGeyserId();
|
||||
this.dirtyMetadata.put(EntityData.OWNER_EID, owner.getGeyserId());
|
||||
}
|
||||
|
||||
@ -80,7 +86,8 @@ public class FishingHookEntity extends ThrowableEntity {
|
||||
}
|
||||
|
||||
if (entity != null) {
|
||||
dirtyMetadata.put(EntityData.TARGET_EID, entity.getGeyserId());
|
||||
bedrockTargetId = entity.getGeyserId();
|
||||
dirtyMetadata.put(EntityData.TARGET_EID, bedrockTargetId);
|
||||
hooked = true;
|
||||
} else {
|
||||
hooked = false;
|
||||
|
@ -23,11 +23,33 @@
|
||||
* @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
|
||||
public enum EntityType {
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
}
|
@ -41,7 +41,6 @@ import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ItemEntity extends ThrowableEntity {
|
||||
|
||||
protected ItemData item;
|
||||
|
||||
private int waterLevel = -1;
|
||||
@ -63,7 +62,11 @@ public class ItemEntity extends ThrowableEntity {
|
||||
itemPacket.setMotion(motion);
|
||||
itemPacket.setFromFishing(false);
|
||||
itemPacket.setItemInHand(item);
|
||||
itemPacket.getMetadata().putAll(dirtyMetadata);
|
||||
itemPacket.getMetadata().putFlags(this.flags);
|
||||
dirtyMetadata.apply(itemPacket.getMetadata());
|
||||
|
||||
setFlagsDirty(false);
|
||||
|
||||
session.sendUpstreamPacket(itemPacket);
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ public class ItemFrameEntity extends Entity {
|
||||
|
||||
@Override
|
||||
public void spawnEntity() {
|
||||
updateBlock();
|
||||
updateBlock(true);
|
||||
session.getConnector().getLogger().debug("Spawned item frame at location " + bedrockPosition + " with java id " + entityId);
|
||||
valid = true;
|
||||
}
|
||||
@ -174,14 +174,14 @@ public class ItemFrameEntity extends Entity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata() {
|
||||
updateBlock();
|
||||
updateBlock(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the item frame as a block
|
||||
*/
|
||||
public void updateBlock() {
|
||||
if (!changed) {
|
||||
public void updateBlock(boolean force) {
|
||||
if (!changed && !force) {
|
||||
// Don't send a block update packet - nothing changed
|
||||
return;
|
||||
}
|
||||
|
@ -140,12 +140,8 @@ public class LivingEntity extends Entity {
|
||||
@Override
|
||||
protected void setDimensions(Pose pose) {
|
||||
if (pose == Pose.SLEEPING) {
|
||||
boundingBoxWidth = 0.2f;
|
||||
boundingBoxHeight = 0.2f;
|
||||
if (boundingBoxWidth != definition.width() || boundingBoxHeight != definition.height()) {
|
||||
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, boundingBoxWidth);
|
||||
dirtyMetadata.put(EntityData.BOUNDING_BOX_HEIGHT, boundingBoxHeight);
|
||||
}
|
||||
setBoundingBoxWidth(0.2f);
|
||||
setBoundingBoxHeight(0.2f);
|
||||
} else {
|
||||
super.setDimensions(pose);
|
||||
}
|
||||
|
@ -294,8 +294,7 @@ public class ArmorStandEntity extends LivingEntity {
|
||||
}
|
||||
return;
|
||||
}
|
||||
//boolean isNametagEmpty = metadata.getString(EntityData.NAMETAG).isEmpty() || metadata.getByte(EntityData.NAMETAG_ALWAYS_SHOW, (byte) -1) == (byte) 0; - may not be necessary?
|
||||
boolean isNametagEmpty = dirtyMetadata.getString(EntityData.NAMETAG).isEmpty(); // TODO
|
||||
boolean isNametagEmpty = nametag.isEmpty();
|
||||
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))) {
|
||||
// If the second entity exists, no need to recreate it.
|
||||
@ -313,7 +312,7 @@ public class ArmorStandEntity extends LivingEntity {
|
||||
}
|
||||
// Copy metadata
|
||||
secondEntity.isSmall = isSmall;
|
||||
secondEntity.getDirtyMetadata().putAll(dirtyMetadata); //TODO check
|
||||
//secondEntity.getDirtyMetadata().putAll(dirtyMetadata); //TODO check
|
||||
secondEntity.flags.merge(this.flags);
|
||||
// Guarantee this copy is NOT invisible
|
||||
secondEntity.setFlag(EntityFlag.INVISIBLE, false);
|
||||
|
@ -44,7 +44,7 @@ public class AnimalEntity extends AgeableEntity {
|
||||
* <code>wheat</code>.
|
||||
* @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.
|
||||
return javaIdentifierStripped.equals("wheat");
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ public class AxolotlEntity extends AnimalEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
||||
public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
|
||||
return javaIdentifierStripped.equals("tropical_fish_bucket");
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ public class BeeEntity extends AnimalEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
||||
public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
|
||||
return session.getTagCache().isFlower(mapping);
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public class ChickenEntity extends AnimalEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
||||
public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
|
||||
return javaIdentifierStripped.contains("seeds");
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ public class FoxEntity extends AnimalEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
||||
public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
|
||||
return session.getTagCache().isFoxFood(mapping);
|
||||
}
|
||||
}
|
||||
|
@ -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.type.BooleanEntityMetadata;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.connector.entity.EntityDefinition;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
@ -55,8 +54,8 @@ public class GoatEntity extends AnimalEntity {
|
||||
@Override
|
||||
protected void setDimensions(Pose pose) {
|
||||
if (pose == Pose.LONG_JUMPING) {
|
||||
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, LONG_JUMPING_WIDTH);
|
||||
dirtyMetadata.put(EntityData.BOUNDING_BOX_HEIGHT, LONG_JUMPING_HEIGHT);
|
||||
setBoundingBoxWidth(LONG_JUMPING_WIDTH);
|
||||
setBoundingBoxHeight(LONG_JUMPING_HEIGHT);
|
||||
} else {
|
||||
super.setDimensions(pose);
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ public class HoglinEntity extends AnimalEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
||||
public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
|
||||
return javaIdentifierStripped.equals("crimson_fungus");
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public class OcelotEntity extends AnimalEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
||||
public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
|
||||
return javaIdentifierStripped.equals("cod") || javaIdentifierStripped.equals("salmon");
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ public class PandaEntity extends AnimalEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
||||
public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
|
||||
return javaIdentifierStripped.equals("bamboo");
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ public class PigEntity extends AnimalEntity {
|
||||
}
|
||||
|
||||
@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");
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public class PolarBearEntity extends AnimalEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
||||
public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ public class RabbitEntity extends AnimalEntity {
|
||||
}
|
||||
|
||||
@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");
|
||||
}
|
||||
}
|
@ -93,7 +93,7 @@ public class StriderEntity extends AnimalEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
||||
public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
|
||||
return javaIdentifierStripped.equals("warped_fungus");
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ public class TurtleEntity extends AnimalEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
||||
public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
|
||||
return javaIdentifierStripped.equals("seagrass");
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ public class AbstractHorseEntity extends AnimalEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
||||
public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
|
||||
return DONKEY_AND_HORSE_FOODS.contains(javaIdentifierStripped);
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ public class LlamaEntity extends ChestedHorseEntity {
|
||||
}
|
||||
|
||||
@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");
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ public class CatEntity extends TameableEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
||||
public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
|
||||
return javaIdentifierStripped.equals("cod") || javaIdentifierStripped.equals("salmon");
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public class ParrotEntity extends TameableEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
||||
public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
|
||||
return javaIdentifierStripped.contains("seeds") || javaIdentifierStripped.equals("cookie");
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ public class WolfEntity extends TameableEntity {
|
||||
|
||||
@Override
|
||||
public void setTameableFlags(EntityMetadata<Byte> entityMetadata) {
|
||||
super.setFlags(entityMetadata);
|
||||
super.setTameableFlags(entityMetadata);
|
||||
// Reset wolf color
|
||||
byte xd = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
||||
boolean angry = (xd & 0x02) == 0x02;
|
||||
@ -87,8 +87,8 @@ public class WolfEntity extends TameableEntity {
|
||||
}
|
||||
|
||||
@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
|
||||
return WOLF_FOODS.contains(javaIdentifierStripped) && !getFlag(EntityFlag.BABY);
|
||||
return WOLF_FOODS.contains(javaIdentifierStripped) && !isBaby();
|
||||
}
|
||||
}
|
||||
|
@ -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.nukkitx.math.vector.Vector3f;
|
||||
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.EntityFlag;
|
||||
import com.nukkitx.protocol.bedrock.packet.*;
|
||||
@ -237,7 +236,7 @@ public class EnderDragonEntity extends MobEntity implements Tickable {
|
||||
|
||||
phaseTicks++;
|
||||
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);
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
|
@ -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) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
// OptionalPack usage
|
||||
dirtyMetadata.getFlags().setFlag(EntityFlag.BRIBED, this.definition == EntityDefinitions.ILLUSIONER);
|
||||
setFlag(EntityFlag.BRIBED, this.definition == EntityDefinitions.ILLUSIONER);
|
||||
}
|
||||
|
||||
public void setSpellType(EntityMetadata<Byte> entityMetadata) {
|
||||
|
@ -28,6 +28,7 @@ package org.geysermc.connector.entity.player;
|
||||
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.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.FloatEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition;
|
||||
@ -67,6 +68,8 @@ public class PlayerEntity extends LivingEntity {
|
||||
private String username;
|
||||
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
|
||||
*/
|
||||
@ -114,10 +117,9 @@ public class PlayerEntity extends LivingEntity {
|
||||
addPlayerPacket.getAdventureSettings().setPlayerPermission(PlayerPermission.MEMBER);
|
||||
addPlayerPacket.setDeviceId("");
|
||||
addPlayerPacket.setPlatformChatId("");
|
||||
addPlayerPacket.getMetadata().putAll(dirtyMetadata);
|
||||
addPlayerPacket.getMetadata().putFlags(flags);
|
||||
dirtyMetadata.apply(addPlayerPacket.getMetadata());
|
||||
|
||||
dirtyMetadata.clear();
|
||||
setFlagsDirty(false);
|
||||
|
||||
long linkedEntityId = session.getEntityCache().getCachedPlayerEntityLink(entityId);
|
||||
@ -189,8 +191,7 @@ public class PlayerEntity extends LivingEntity {
|
||||
movePlayerPacket.setMode(MovePlayerPacket.Mode.NORMAL);
|
||||
// If the player is moved while sleeping, we have to adjust their y, so it appears
|
||||
// correctly on Bedrock. This fixes GSit's lay.
|
||||
if (dirtyMetadata.getFlags().getFlag(EntityFlag.SLEEPING)) {
|
||||
Vector3i bedPosition = dirtyMetadata.getPos(EntityData.BED_POSITION);
|
||||
if (getFlag(EntityFlag.SLEEPING)) {
|
||||
if (bedPosition != null && (bedPosition.getY() == 0 || bedPosition.distanceSquared(position.toInt()) > 4)) {
|
||||
// Force the player movement by using a teleport
|
||||
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));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3i setBedPosition(EntityMetadata<Position> entityMetadata) {
|
||||
return bedPosition = super.setBedPosition(entityMetadata);
|
||||
}
|
||||
|
||||
public void setAbsorptionHearts(EntityMetadata<Float> entityMetadata) {
|
||||
// Extra hearts - is not metadata but an attribute on Bedrock
|
||||
UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();
|
||||
@ -358,11 +364,12 @@ public class PlayerEntity extends LivingEntity {
|
||||
// The name is not visible to the session player; clear name
|
||||
newDisplayName = "";
|
||||
}
|
||||
needsUpdate = useGivenTeam && !newDisplayName.equals(dirtyMetadata.getString(EntityData.NAMETAG, null));
|
||||
needsUpdate = useGivenTeam && !newDisplayName.equals(nametag);
|
||||
nametag = newDisplayName;
|
||||
dirtyMetadata.put(EntityData.NAMETAG, newDisplayName);
|
||||
} else if (useGivenTeam) {
|
||||
// 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);
|
||||
} else {
|
||||
needsUpdate = false;
|
||||
@ -393,10 +400,8 @@ public class PlayerEntity extends LivingEntity {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (height != boundingBoxHeight || definition.width() != boundingBoxWidth) {
|
||||
dirtyMetadata.put(EntityData.BOUNDING_BOX_WIDTH, definition.width());
|
||||
dirtyMetadata.put(EntityData.BOUNDING_BOX_HEIGHT, height);
|
||||
}
|
||||
setBoundingBoxWidth(definition.width());
|
||||
setBoundingBoxHeight(height);
|
||||
}
|
||||
|
||||
public void setBelowNameText(Objective objective) {
|
||||
@ -410,7 +415,6 @@ public class PlayerEntity extends LivingEntity {
|
||||
}
|
||||
String displayString = amount + " " + objective.getDisplayName();
|
||||
|
||||
dirtyMetadata.put(EntityData.SCORE_TAG, displayString);
|
||||
if (valid) {
|
||||
// Already spawned - we still need to run the rest of this code because the spawn packet will be
|
||||
// providing the information
|
||||
@ -419,15 +423,11 @@ public class PlayerEntity extends LivingEntity {
|
||||
packet.getMetadata().put(EntityData.SCORE_TAG, displayString);
|
||||
session.sendUpstreamPacket(packet);
|
||||
}
|
||||
} else {
|
||||
// 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();
|
||||
packet.setRuntimeEntityId(geyserId);
|
||||
packet.getMetadata().put(EntityData.SCORE_TAG, "");
|
||||
session.sendUpstreamPacket(packet);
|
||||
}
|
||||
} else if (valid) {
|
||||
SetEntityDataPacket packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(geyserId);
|
||||
packet.getMetadata().put(EntityData.SCORE_TAG, "");
|
||||
session.sendUpstreamPacket(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.nukkitx.math.vector.Vector3f;
|
||||
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.packet.UpdateAttributesPacket;
|
||||
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
|
||||
*/
|
||||
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;
|
||||
|
||||
@ -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
|
||||
public AttributeData createHealthAttribute() {
|
||||
// Max health must be divisible by two in bedrock
|
||||
|
@ -83,10 +83,9 @@ public class SkullPlayerEntity extends PlayerEntity {
|
||||
addPlayerPacket.getAdventureSettings().setPlayerPermission(PlayerPermission.MEMBER);
|
||||
addPlayerPacket.setDeviceId("");
|
||||
addPlayerPacket.setPlatformChatId("");
|
||||
addPlayerPacket.getMetadata().putAll(dirtyMetadata);
|
||||
addPlayerPacket.getMetadata().putFlags(flags);
|
||||
dirtyMetadata.apply(addPlayerPacket.getMetadata());
|
||||
|
||||
dirtyMetadata.clear();
|
||||
setFlagsDirty(false);
|
||||
|
||||
valid = true;
|
||||
|
@ -1072,7 +1072,7 @@ public class GeyserSession implements CommandSender {
|
||||
AttributeData currentPlayerSpeed = playerEntity.getAttributes().get(GeyserAttributeType.MOVEMENT_SPEED);
|
||||
if (currentPlayerSpeed != null) {
|
||||
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
|
||||
AttributeData speedAttribute = GeyserAttributeType.MOVEMENT_SPEED.getAttribute(originalSpeedAttribute / 3.32f);
|
||||
playerEntity.getAttributes().put(GeyserAttributeType.MOVEMENT_SPEED, speedAttribute);
|
||||
|
@ -50,7 +50,7 @@ public class BedrockAdventureSettingsTranslator extends PacketTranslator<Adventu
|
||||
ServerboundPlayerAbilitiesPacket abilitiesPacket = new ServerboundPlayerAbilitiesPacket(isFlying);
|
||||
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
|
||||
session.setSwimming(false);
|
||||
}
|
||||
|
@ -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.ServerboundPlayerInputPacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||
import com.nukkitx.protocol.bedrock.packet.PlayerInputPacket;
|
||||
import org.geysermc.connector.entity.BoatEntity;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
@ -65,8 +64,7 @@ public class BedrockPlayerInputTranslator extends PacketTranslator<PlayerInputPa
|
||||
sendMovement = true;
|
||||
} else {
|
||||
// Check if the player is the front rider
|
||||
Vector3f seatPos = session.getPlayerEntity().getDirtyMetadata().getVector3f(EntityData.RIDER_SEAT_POSITION, null);
|
||||
if (seatPos != null && seatPos.getX() > 0) {
|
||||
if (session.getPlayerEntity().isRidingInFront()) {
|
||||
sendMovement = true;
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundCl
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket;
|
||||
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.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
@ -54,11 +53,7 @@ public class BedrockRespawnTranslator extends PacketTranslator<RespawnPacket> {
|
||||
if (session.isSpawned()) {
|
||||
// Client might be stuck; resend spawn information
|
||||
PlayerEntity entity = session.getPlayerEntity();
|
||||
if (entity == null) return;
|
||||
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
|
||||
entityDataPacket.setRuntimeEntityId(entity.getGeyserId());
|
||||
entityDataPacket.getMetadata().putAll(entity.getDirtyMetadata());
|
||||
session.sendUpstreamPacket(entityDataPacket);
|
||||
entity.updateBedrockMetadata(); // TODO test?
|
||||
|
||||
MovePlayerPacket movePlayerPacket = new MovePlayerPacket();
|
||||
movePlayerPacket.setRuntimeEntityId(entity.getGeyserId());
|
||||
|
@ -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.packet.ingame.serverbound.inventory.ServerboundSelectTradePacket;
|
||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||
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.Inventory;
|
||||
import org.geysermc.connector.inventory.MerchantContainer;
|
||||
@ -55,14 +54,15 @@ public class BedrockEntityEventTranslator extends PacketTranslator<EntityEventPa
|
||||
session.sendDownstreamPacket(selectTradePacket);
|
||||
|
||||
session.scheduleInEventLoop(() -> {
|
||||
Entity villager = session.getPlayerEntity();
|
||||
SessionPlayerEntity villager = session.getPlayerEntity();
|
||||
Inventory openInventory = session.getOpenInventory();
|
||||
if (openInventory instanceof MerchantContainer merchantInventory) {
|
||||
VillagerTrade[] trades = merchantInventory.getVillagerTrades();
|
||||
if (trades != null && packet.getData() >= 0 && packet.getData() < trades.length) {
|
||||
VillagerTrade trade = merchantInventory.getVillagerTrades()[packet.getData()];
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
|
||||
useItemPacket = new ServerboundUseItemPacket(Hand.OFF_HAND);
|
||||
}
|
||||
session.sendDownstreamPacket(useItemPacket);
|
||||
session.getPlayerEntity().getDirtyMetadata().getFlags().setFlag(EntityFlag.BLOCKING, true);
|
||||
session.getPlayerEntity().setFlag(EntityFlag.BLOCKING, true);
|
||||
// metadata will be updated when sneaking
|
||||
}
|
||||
|
||||
@ -127,10 +127,10 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
|
||||
session.sendDownstreamPacket(stopSneakPacket);
|
||||
|
||||
// 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);
|
||||
session.sendDownstreamPacket(releaseItemPacket);
|
||||
session.getPlayerEntity().getDirtyMetadata().getFlags().setFlag(EntityFlag.BLOCKING, false);
|
||||
session.getPlayerEntity().setFlag(EntityFlag.BLOCKING, false);
|
||||
// metadata will be updated when sneaking
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ public class BedrockInteractTranslator extends PacketTranslator<InteractPacket>
|
||||
if (session.getOpenInventory() == null) {
|
||||
Entity ridingEntity = session.getRidingVehicleEntity();
|
||||
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
|
||||
ServerboundPlayerCommandPacket openHorseWindowPacket = new ServerboundPlayerCommandPacket((int) session.getPlayerEntity().getEntityId(), PlayerState.OPEN_HORSE_INVENTORY);
|
||||
session.sendDownstreamPacket(openHorseWindowPacket);
|
||||
|
@ -28,10 +28,8 @@ package org.geysermc.connector.network.translators.collision;
|
||||
import com.nukkitx.math.vector.Vector3d;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
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.packet.MovePlayerPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
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 - 1⁄4) blocks high.
|
||||
// - 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.
|
||||
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.setSizeY(playerHeight);
|
||||
}
|
||||
@ -188,10 +186,7 @@ public class CollisionManager {
|
||||
public void recalculatePosition() {
|
||||
PlayerEntity entity = session.getPlayerEntity();
|
||||
// Gravity might need to be reset...
|
||||
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
|
||||
entityDataPacket.setRuntimeEntityId(entity.getGeyserId());
|
||||
entityDataPacket.getMetadata().putAll(entity.getDirtyMetadata());
|
||||
session.sendUpstreamPacket(entityDataPacket);
|
||||
entity.updateBedrockMetadata(); // TODO may not be necessary
|
||||
|
||||
MovePlayerPacket movePlayerPacket = new MovePlayerPacket();
|
||||
movePlayerPacket.setRuntimeEntityId(entity.getGeyserId());
|
||||
|
@ -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 ITEM_STACK -> session.getItemMappings().getItemNames();
|
||||
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 SCOREBOARD_SLOT -> VALID_SCOREBOARD_SLOTS;
|
||||
case MOB_EFFECT -> ALL_EFFECT_IDENTIFIERS;
|
||||
|
@ -90,10 +90,7 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
|
||||
session.sendUpstreamPacket(playerGameTypePacket);
|
||||
}
|
||||
|
||||
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
|
||||
entityDataPacket.setRuntimeEntityId(entity.getGeyserId());
|
||||
entityDataPacket.getMetadata().putAll(entity.getDirtyMetadata());
|
||||
session.sendUpstreamPacket(entityDataPacket);
|
||||
entity.updateBedrockMetadata();
|
||||
|
||||
// Send if client should show respawn screen
|
||||
GameRulesChangedPacket gamerulePacket = new GameRulesChangedPacket();
|
||||
|
@ -34,6 +34,7 @@ import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
||||
import com.nukkitx.protocol.bedrock.packet.*;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.entity.EntityDefinitions;
|
||||
import org.geysermc.connector.entity.FishingHookEntity;
|
||||
import org.geysermc.connector.entity.LivingEntity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
@ -122,9 +123,9 @@ public class JavaEntityEventTranslator extends PacketTranslator<ClientboundEntit
|
||||
case FISHING_HOOK_PULL_PLAYER:
|
||||
// Player is pulled from a fishing rod
|
||||
// The physics of this are clientside on Java
|
||||
long pulledById = entity.getDirtyMetadata().getLong(EntityData.TARGET_EID);
|
||||
if (session.getPlayerEntity().getGeyserId() == pulledById) {
|
||||
Entity hookOwner = session.getEntityCache().getEntityByGeyserId(entity.getDirtyMetadata().getLong(EntityData.OWNER_EID));
|
||||
FishingHookEntity fishingHook = (FishingHookEntity) entity;
|
||||
if (fishingHook.isOwnerSessionPlayer()) {
|
||||
Entity hookOwner = session.getEntityCache().getEntityByGeyserId(fishingHook.getBedrockTargetId());
|
||||
if (hookOwner != null) {
|
||||
// https://minecraft.gamepedia.com/Fishing_Rod#Hooking_mobs_and_other_entities
|
||||
SetEntityMotionPacket motionPacket = new SetEntityMotionPacket();
|
||||
|
@ -33,7 +33,6 @@ import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.Translator;
|
||||
import org.geysermc.connector.utils.InteractiveTagManager;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -61,16 +60,19 @@ public class JavaSetEntityDataTranslator extends PacketTranslator<ClientboundSet
|
||||
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) {
|
||||
// This can safely happen; it means we don't translate this entity metadata
|
||||
continue;
|
||||
}
|
||||
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());
|
||||
if (session.getConnector().getConfig().isDebugMode()) {
|
||||
session.getConnector().getLogger().debug(metadata.toString());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
translator.translateFunction().accept(entity, metadata);
|
||||
translator.translateFunction().accept(entity, (EntityMetadata<Object>) metadata);
|
||||
}
|
||||
|
||||
entity.updateBedrockMetadata();
|
||||
|
@ -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.packet.MovePlayerPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.RespawnPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.SetEntityLinkPacket;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.entity.EntityDefinitions;
|
||||
@ -69,10 +68,7 @@ public class JavaPlayerPositionTranslator extends PacketTranslator<ClientboundPl
|
||||
respawnPacket.setState(RespawnPacket.State.SERVER_READY);
|
||||
session.sendUpstreamPacket(respawnPacket);
|
||||
|
||||
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
|
||||
entityDataPacket.setRuntimeEntityId(entity.getGeyserId());
|
||||
entityDataPacket.getMetadata().putAll(entity.getDirtyMetadata());
|
||||
session.sendUpstreamPacket(entityDataPacket);
|
||||
entity.updateBedrockMetadata();
|
||||
|
||||
MovePlayerPacket movePlayerPacket = new MovePlayerPacket();
|
||||
movePlayerPacket.setRuntimeEntityId(entity.getGeyserId());
|
||||
|
@ -29,7 +29,6 @@ import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.Cli
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
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.packet.UpdateEquipPacket;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
@ -132,6 +131,6 @@ public class JavaHorseScreenOpenTranslator extends PacketTranslator<ClientboundH
|
||||
session.sendUpstreamPacket(updateEquipPacket);
|
||||
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ import io.netty.buffer.ByteBufOutputStream;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
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.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.Translator;
|
||||
@ -68,9 +69,7 @@ import org.geysermc.connector.utils.ChunkUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
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
|
||||
int yOffset = session.getChunkCache().getChunkMinY();
|
||||
int chunkSize = session.getChunkCache().getChunkHeightY();
|
||||
|
||||
// Temporarily stores compound tags of Bedrock-only block entities
|
||||
List<NbtMap> bedrockOnlyBlockEntities = new ArrayList<>();
|
||||
DataPalette[] javaChunks = new DataPalette[session.getChunkCache().getChunkHeightY()];
|
||||
DataPalette[] javaBiomes = new DataPalette[session.getChunkCache().getChunkHeightY()];
|
||||
DataPalette[] javaChunks = new DataPalette[chunkSize];
|
||||
DataPalette[] javaBiomes = new DataPalette[chunkSize];
|
||||
|
||||
BitSet waterloggedPaletteIds = new BitSet();
|
||||
BitSet pistonOrFlowerPaletteIds = new BitSet();
|
||||
@ -100,21 +100,21 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||
int sectionCount;
|
||||
byte[] payload;
|
||||
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 {
|
||||
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));
|
||||
if (bedrockSectionY < 0 || maxBedrockSectionY < bedrockSectionY) {
|
||||
// Ignore this chunk section since it goes outside the bounds accepted by the Bedrock client
|
||||
continue;
|
||||
}
|
||||
|
||||
ChunkSection javaSection = ChunkSection.read(in);
|
||||
javaChunks[sectionY] = javaSection.getChunkData();
|
||||
javaBiomes[sectionY] = javaSection.getBiomeData();
|
||||
|
||||
// No need to encode an empty section...
|
||||
if (javaSection.isBlockCountEmpty()) {
|
||||
continue;
|
||||
@ -316,11 +316,11 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||
for (int i = 0; i < sectionCount; i++) {
|
||||
int biomeYOffset = dimensionOffset + i;
|
||||
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);
|
||||
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
|
||||
@ -356,5 +356,14 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||
levelChunkPacket.setChunkZ(packet.getZ());
|
||||
levelChunkPacket.setData(payload);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -136,18 +136,18 @@ public class JavaLevelParticlesTranslator extends PacketTranslator<ClientboundLe
|
||||
return null;
|
||||
}
|
||||
|
||||
if (particleMapping.getLevelEventType() != null) {
|
||||
if (particleMapping.levelEventType() != null) {
|
||||
return (position) -> {
|
||||
LevelEventPacket packet = new LevelEventPacket();
|
||||
packet.setType(particleMapping.getLevelEventType());
|
||||
packet.setType(particleMapping.levelEventType());
|
||||
packet.setPosition(position);
|
||||
return packet;
|
||||
};
|
||||
} else if (particleMapping.getIdentifier() != null) {
|
||||
} else if (particleMapping.identifier() != null) {
|
||||
int dimensionId = DimensionUtils.javaToBedrock(session.getDimension());
|
||||
return (position) -> {
|
||||
SpawnParticleEffectPacket stringPacket = new SpawnParticleEffectPacket();
|
||||
stringPacket.setIdentifier(particleMapping.getIdentifier());
|
||||
stringPacket.setIdentifier(particleMapping.identifier());
|
||||
stringPacket.setDimensionId(dimensionId);
|
||||
stringPacket.setPosition(position);
|
||||
return stringPacket;
|
||||
|
@ -27,7 +27,6 @@ package org.geysermc.connector.network.translators.sound.entity;
|
||||
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.data.entity.EntityEventType;
|
||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.entity.living.animal.AnimalEntity;
|
||||
@ -42,10 +41,10 @@ public class FeedBabySoundInteractionHandler implements EntitySoundInteractionHa
|
||||
|
||||
@Override
|
||||
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();
|
||||
boolean isBaby = entity.getDirtyMetadata().getFlags().getFlag(EntityFlag.BABY);
|
||||
if (isBaby && ((AnimalEntity) entity).canEat(session, handIdentifier.replace("minecraft:", ""),
|
||||
boolean isBaby = animalEntity.isBaby();
|
||||
if (isBaby && animalEntity.canEat(handIdentifier.replace("minecraft:", ""),
|
||||
session.getPlayerInventory().getItemInHand().getMapping(session))) {
|
||||
// Play the "feed child" effect
|
||||
EntityEventPacket feedEvent = new EntityEventPacket();
|
||||
|
@ -43,7 +43,7 @@ public class MilkEntitySoundInteractionHandler implements EntitySoundInteraction
|
||||
if (!session.getPlayerInventory().getItemInHand().getMapping(session).getJavaIdentifier().equals("minecraft:bucket")) {
|
||||
return;
|
||||
}
|
||||
if (value.getDirtyMetadata().getFlags().getFlag(EntityFlag.BABY)) {
|
||||
if (value.getFlag(EntityFlag.BABY)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import org.geysermc.connector.registry.type.ParticleMapping;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -49,12 +50,10 @@ public class ParticleTypesRegistryLoader extends EffectRegistryLoader<Map<Partic
|
||||
while (particlesIterator.hasNext()) {
|
||||
Map.Entry<String, JsonNode> entry = particlesIterator.next();
|
||||
JsonNode bedrockId = entry.getValue().get("bedrockId");
|
||||
JsonNode bedrockIdNumeric = entry.getValue().get("bedrockNumericId");
|
||||
JsonNode eventType = entry.getValue().get("eventType");
|
||||
particles.put(ParticleType.valueOf(entry.getKey().toUpperCase()), new ParticleMapping(
|
||||
eventType == null ? null : LevelEventType.valueOf(eventType.asText().toUpperCase()),
|
||||
bedrockId == null ? null : bedrockId.asText(),
|
||||
bedrockIdNumeric == null ? -1 : bedrockIdNumeric.asInt())
|
||||
particles.put(ParticleType.valueOf(entry.getKey().toUpperCase(Locale.ROOT)), new ParticleMapping(
|
||||
eventType == null ? null : LevelEventType.valueOf(eventType.asText().toUpperCase(Locale.ROOT)),
|
||||
bedrockId == null ? null : bedrockId.asText())
|
||||
);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -226,6 +226,8 @@ public class ItemRegistryPopulator {
|
||||
if (javaIdentifier.equals("minecraft:sculk_sensor")) {
|
||||
// TODO fix in mappings
|
||||
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")) {
|
||||
@ -398,7 +400,7 @@ public class ItemRegistryPopulator {
|
||||
.count(1)
|
||||
.blockRuntimeId(mapping.getBedrockBlockId())
|
||||
.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
|
||||
Registries.RECORDS.register(itemIndex, SoundEvent.valueOf("RECORD_" +
|
||||
javaIdentifier.replace("minecraft:music_disc_", "").toUpperCase(Locale.ENGLISH)));
|
||||
|
@ -26,14 +26,9 @@
|
||||
package org.geysermc.connector.registry.type;
|
||||
|
||||
import com.nukkitx.protocol.bedrock.data.LevelEventType;
|
||||
import lombok.Value;
|
||||
|
||||
import javax.annotation.ParametersAreNullableByDefault;
|
||||
|
||||
@Value
|
||||
@ParametersAreNullableByDefault
|
||||
public class ParticleMapping {
|
||||
LevelEventType levelEventType;
|
||||
String identifier;
|
||||
int id;
|
||||
public record ParticleMapping(LevelEventType levelEventType, String identifier) {
|
||||
}
|
@ -152,7 +152,7 @@ public class ChunkUtils {
|
||||
ItemFrameEntity itemFrameEntity = ItemFrameEntity.getItemFrameEntity(session, position);
|
||||
if (itemFrameEntity != null) {
|
||||
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
|
||||
session.getChunkCache().updateBlock(position.getX(), position.getY(), position.getZ(), blockState);
|
||||
return;
|
||||
|
@ -50,7 +50,7 @@ public class EffectUtils {
|
||||
return -1;
|
||||
}
|
||||
|
||||
LevelEventType levelEventType = mapping.getLevelEventType();
|
||||
LevelEventType levelEventType = mapping.levelEventType();
|
||||
if (levelEventType == null) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -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.type.EntityType;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.entity.EntityDefinitions;
|
||||
@ -70,7 +69,7 @@ public final class EntityUtils {
|
||||
}
|
||||
|
||||
private static float getMountedHeightOffset(Entity mount) {
|
||||
float height = mount.getDirtyMetadata().getFloat(EntityData.BOUNDING_BOX_HEIGHT);
|
||||
float height = mount.getBoundingBoxHeight();
|
||||
float mountedHeightOffset = height * 0.75f;
|
||||
switch (mount.getDefinition().entityType()) {
|
||||
case CHICKEN, SPIDER -> mountedHeightOffset = height * 0.5f;
|
||||
@ -80,7 +79,7 @@ public final class EntityUtils {
|
||||
MINECART_COMMAND_BLOCK -> mountedHeightOffset = 0;
|
||||
case BOAT -> mountedHeightOffset = -0.1f;
|
||||
case HOGLIN, ZOGLIN -> {
|
||||
boolean isBaby = mount.getDirtyMetadata().getFlags().getFlag(EntityFlag.BABY);
|
||||
boolean isBaby = mount.getFlag(EntityFlag.BABY);
|
||||
mountedHeightOffset = height - (isBaby ? 0.2f : 0.15f);
|
||||
}
|
||||
case PIGLIN -> mountedHeightOffset = height * 0.92f;
|
||||
@ -110,10 +109,10 @@ public final class EntityUtils {
|
||||
case PIGLIN:
|
||||
case PIGLIN_BRUTE:
|
||||
case ZOMBIFIED_PIGLIN:
|
||||
isBaby = passenger.getDirtyMetadata().getFlags().getFlag(EntityFlag.BABY);
|
||||
isBaby = passenger.getFlag(EntityFlag.BABY);
|
||||
return isBaby ? -0.05f : -0.45f;
|
||||
case ZOMBIE:
|
||||
isBaby = passenger.getDirtyMetadata().getFlags().getFlag(EntityFlag.BABY);
|
||||
isBaby = passenger.getFlag(EntityFlag.BABY);
|
||||
return isBaby ? 0.0f : -0.45f;
|
||||
case EVOKER:
|
||||
case ILLUSIONER:
|
||||
@ -174,7 +173,7 @@ public final class EntityUtils {
|
||||
MINECART_COMMAND_BLOCK, BOAT -> yOffset -= mount.getDefinition().height() * 0.5f;
|
||||
}
|
||||
Vector3f offset = Vector3f.from(xOffset, yOffset, zOffset);
|
||||
passenger.getDirtyMetadata().put(EntityData.RIDER_SEAT_POSITION, offset);
|
||||
passenger.setRiderSeatPosition(offset);
|
||||
}
|
||||
passenger.updateBedrockMetadata();
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ public class InteractiveTagManager {
|
||||
// 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)
|
||||
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
|
||||
interactiveTag = InteractiveTag.FEED;
|
||||
} else {
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren