diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ShulkerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ShulkerEntity.java index aecb4a915..d8266f29d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ShulkerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ShulkerEntity.java @@ -52,6 +52,12 @@ public class ShulkerEntity extends GolemEntity { // As of 1.19.4, it seems Java no longer sends the shulker color if it's the default color on initial spawn // We still need the special case for 16 color in setShulkerColor though as it will send it for an entity metadata update dirtyMetadata.put(EntityDataTypes.VARIANT, 16); + + setFlag(EntityFlag.COLLIDABLE, true); + + // This is vanilla behaviour yes (BDS does this), without this as of 1.21.93 entity became fully invisible. + // Doing this allow the invisible parity support inside GeyserOptionalPack to works again. + setFlag(EntityFlag.RENDER_WHEN_INVISIBLE, true); } public void setAttachedFace(EntityMetadata entityMetadata) { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java index 742f550d0..7dbbf0b52 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java @@ -51,6 +51,7 @@ import org.geysermc.geyser.entity.attribute.GeyserAttributeType; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.LivingEntity; import org.geysermc.geyser.entity.type.living.animal.tameable.ParrotEntity; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.ChunkUtils; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; @@ -422,6 +423,29 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { dirtyMetadata.put(EntityDataTypes.SCORE, show ? cachedScore : ""); } + @Override + public void setPose(Pose pose) { + super.setPose(pose); + setFlag(EntityFlag.SWIMMING, false); + setFlag(EntityFlag.CRAWLING, false); + + if (pose == Pose.SWIMMING) { + // This is just for, so we know if player is swimming or crawling. + if (session.getGeyser().getWorldManager().blockAt(session, this.position().toInt()).is(Blocks.WATER)) { + setFlag(EntityFlag.SWIMMING, true); + } else { + setFlag(EntityFlag.CRAWLING, true); + // Look at https://github.com/GeyserMC/Geyser/issues/5316, we're fixing this by spoofing player pitch to 0. + updateRotation(this.yaw, 0, this.onGround); + } + } + } + + @Override + public void setPitch(float pitch) { + super.setPitch(getFlag(EntityFlag.CRAWLING) ? 0 : pitch); + } + @Override public void setDimensionsFromPose(Pose pose) { float height; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java index 1fd4f5cf5..dcd3a1485 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java @@ -124,6 +124,14 @@ public class SessionPlayerEntity extends PlayerEntity { valid = true; } + @Override + protected void initializeMetadata() { + super.initializeMetadata(); + + // This allows player to be slowly push towards the closet space when stuck inside block instead of instantly moved out. + setFlag(EntityFlag.PUSH_TOWARDS_CLOSEST_SPACE, true); + } + @Override protected void setClientSideSilent() { // Do nothing, since we want the session player to hear their own footstep sounds for example.