From 5fca5d5ef50c04dcfc0932e997f10bac6f7269dd Mon Sep 17 00:00:00 2001 From: rtm516 Date: Wed, 3 Jun 2020 21:12:16 +0100 Subject: [PATCH] Fix position of non-marker invisible armour stands (#697) This adds the height of the armour stand to the position if its invisible and not a marker to counteract the scale being 0 therefore having a wrong nametag position --- .../org/geysermc/connector/entity/Entity.java | 5 ++-- .../entity/living/ArmorStandEntity.java | 30 +++++++++++++++++-- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/entity/Entity.java b/connector/src/main/java/org/geysermc/connector/entity/Entity.java index 06679934a..16e9c0a1b 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -214,9 +214,8 @@ public class Entity { metadata.getFlags().setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80); if ((xd & 0x20) == 0x20) { - if (this.is(ArmorStandEntity.class)) { - metadata.put(EntityData.SCALE, 0.0f); - } else { + // Armour stands are handled in their own class + if (!this.is(ArmorStandEntity.class)) { metadata.getFlags().setFlag(EntityFlag.INVISIBLE, true); } } else { diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java index 8d3c8f8fd..47faad367 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java @@ -35,17 +35,42 @@ import org.geysermc.connector.network.session.GeyserSession; public class ArmorStandEntity extends LivingEntity { + // These are used to store the state of the armour stand for use when handling invisibility + private boolean isMarker = false; + private boolean isInvisible = false; + private boolean isSmall = false; + public ArmorStandEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); } + @Override + public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) { + // Fake the height to be above where it is so the nametag appears in the right location for invisible non-marker armour stands + if (!isMarker && isInvisible) { + position = position.add(0d, entityType.getHeight() * (isSmall ? 0.55d : 1d), 0d); + } + + super.moveAbsolute(session, position, rotation, isOnGround, teleported); + } + @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { - if (entityMetadata.getType() == MetadataType.BYTE) { + if (entityMetadata.getId() == 0 && entityMetadata.getType() == MetadataType.BYTE) { + byte xd = (byte) entityMetadata.getValue(); + + // Check if the armour stand is invisible and store accordingly + if ((xd & 0x20) == 0x20) { + metadata.put(EntityData.SCALE, 0.0f); + isInvisible = true; + } + } else if (entityMetadata.getId() == 14 && entityMetadata.getType() == MetadataType.BYTE) { byte xd = (byte) entityMetadata.getValue(); // isSmall if ((xd & 0x01) == 0x01) { + isSmall = true; + if (metadata.getFloat(EntityData.SCALE) != 0.55f && metadata.getFloat(EntityData.SCALE) != 0.0f) { metadata.put(EntityData.SCALE, 0.55f); } @@ -60,9 +85,10 @@ public class ArmorStandEntity extends LivingEntity { } // setMarker - if ((xd & 0x10) == 0x10 && (metadata.get(EntityData.BOUNDING_BOX_WIDTH) != null && !metadata.get(EntityData.BOUNDING_BOX_WIDTH).equals(0.0f))) { + if ((xd & 0x10) == 0x10 && (metadata.get(EntityData.BOUNDING_BOX_WIDTH) == null || !metadata.get(EntityData.BOUNDING_BOX_WIDTH).equals(0.0f))) { metadata.put(EntityData.BOUNDING_BOX_WIDTH, 0.0f); metadata.put(EntityData.BOUNDING_BOX_HEIGHT, 0.0f); + isMarker = true; } } super.updateBedrockMetadata(entityMetadata, session);