Various entity fixes: Ensure TNT doesn't bug into the ground, reset player entity flags properly (#4670)

* Various entity fixes

* actually update the tnt entity position

* revert bad diff
This commit is contained in:
chris 2024-05-17 22:21:01 +02:00 committed by GitHub
parent 4d61766d0a
commit b010c500d8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 52 additions and 11 deletions

View file

@ -235,7 +235,7 @@ public final class EntityDefinitions {
.addTranslator(MetadataType.BOOLEAN, .addTranslator(MetadataType.BOOLEAN,
(enderCrystalEntity, entityMetadata) -> enderCrystalEntity.setFlag(EntityFlag.SHOW_BOTTOM, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue())) // There is a base located on the ender crystal (enderCrystalEntity, entityMetadata) -> enderCrystalEntity.setFlag(EntityFlag.SHOW_BOTTOM, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue())) // There is a base located on the ender crystal
.build(); .build();
EXPERIENCE_ORB = EntityDefinition.<ExpOrbEntity>inherited(null, entityBase) EXPERIENCE_ORB = EntityDefinition.inherited(ExpOrbEntity::new, entityBase)
.type(EntityType.EXPERIENCE_ORB) .type(EntityType.EXPERIENCE_ORB)
.identifier("minecraft:xp_orb") .identifier("minecraft:xp_orb")
.build(); .build();
@ -297,6 +297,7 @@ public final class EntityDefinitions {
TNT = EntityDefinition.inherited(TNTEntity::new, entityBase) TNT = EntityDefinition.inherited(TNTEntity::new, entityBase)
.type(EntityType.TNT) .type(EntityType.TNT)
.heightAndWidth(0.98f) .heightAndWidth(0.98f)
.offset(0.49f)
.addTranslator(MetadataType.INT, TNTEntity::setFuseLength) .addTranslator(MetadataType.INT, TNTEntity::setFuseLength)
.build(); .build();

View file

@ -59,6 +59,9 @@ import java.util.*;
@Getter @Getter
@Setter @Setter
public class Entity implements GeyserEntity { public class Entity implements GeyserEntity {
private static final boolean PRINT_ENTITY_SPAWN_DEBUG = Boolean.parseBoolean(System.getProperty("Geyser.PrintEntitySpawnDebug", "false"));
protected final GeyserSession session; protected final GeyserSession session;
protected int entityId; protected int entityId;
@ -181,7 +184,7 @@ public class Entity implements GeyserEntity {
flagsDirty = false; flagsDirty = false;
if (session.getGeyser().getConfig().isDebugMode()) { if (session.getGeyser().getConfig().isDebugMode() && PRINT_ENTITY_SPAWN_DEBUG) {
EntityType type = definition.entityType(); EntityType type = definition.entityType();
String name = type != null ? type.name() : getClass().getSimpleName(); String name = type != null ? type.name() : getClass().getSimpleName();
session.getGeyser().getLogger().debug("Spawned entity " + name + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")"); session.getGeyser().getLogger().debug("Spawned entity " + name + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")");

View file

@ -27,11 +27,18 @@ package org.geysermc.geyser.entity.type;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.EntityDefinitions;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import java.util.UUID;
public class ExpOrbEntity extends Entity { public class ExpOrbEntity extends Entity {
public ExpOrbEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> entityDefinition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
this(session, 1, entityId, geyserId, position);
}
public ExpOrbEntity(GeyserSession session, int amount, int entityId, long geyserId, Vector3f position) { public ExpOrbEntity(GeyserSession session, int amount, int entityId, long geyserId, Vector3f position) {
super(session, entityId, geyserId, null, EntityDefinitions.EXPERIENCE_ORB, position, Vector3f.ZERO, 0, 0, 0); super(session, entityId, geyserId, null, EntityDefinitions.EXPERIENCE_ORB, position, Vector3f.ZERO, 0, 0, 0);

View file

@ -39,7 +39,17 @@ public class TNTEntity extends Entity implements Tickable {
private int currentTick; private int currentTick;
public TNTEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { public TNTEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); super(session, entityId, geyserId, uuid, definition, position.add(0, definition.offset(), 0), motion, yaw, pitch, headYaw);
}
@Override
public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, boolean isOnGround) {
super.moveRelative(relX, relY + definition.offset(), relZ, yaw, pitch, isOnGround);
}
@Override
public void moveAbsolute(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) {
super.moveAbsolute(position.add(Vector3f.from(0, definition.offset(), 0)), yaw, pitch, headYaw, isOnGround, teleported);
} }
public void setFuseLength(IntEntityMetadata entityMetadata) { public void setFuseLength(IntEntityMetadata entityMetadata) {

View file

@ -41,6 +41,7 @@ import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData; import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.cloudburstmc.protocol.bedrock.packet.*; import org.cloudburstmc.protocol.bedrock.packet.*;
import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity; import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity;
import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.EntityDefinitions;
@ -166,6 +167,31 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
session.sendUpstreamPacket(addPlayerPacket); session.sendUpstreamPacket(addPlayerPacket);
} }
@Override
public void despawnEntity() {
super.despawnEntity();
// Since we re-use player entities: Clear flags, held item, etc
this.resetMetadata();
this.hand = ItemData.AIR;
this.offhand = ItemData.AIR;
this.boots = ItemData.AIR;
this.leggings = ItemData.AIR;
this.chestplate = ItemData.AIR;
this.helmet = ItemData.AIR;
}
public void resetMetadata() {
// Reset all metadata to their default values
// This is used when a player respawns
this.flags.clear();
this.initializeMetadata();
// Explicitly reset all metadata not handled by initializeMetadata
setParrot(null, true);
setParrot(null, false);
}
public void sendPlayer() { public void sendPlayer() {
if (session.getEntityCache().getPlayerEntity(uuid) == null) if (session.getEntityCache().getPlayerEntity(uuid) == null)
return; return;

View file

@ -264,19 +264,13 @@ public class SessionPlayerEntity extends PlayerEntity {
super.setAbsorptionHearts(entityMetadata); super.setAbsorptionHearts(entityMetadata);
} }
@Override
public void resetMetadata() { public void resetMetadata() {
// Reset all metadata to their default values super.resetMetadata();
// This is used when a player respawns
this.flags.clear();
this.initializeMetadata();
// Reset air // Reset air
this.resetAir(); this.resetAir();
// Explicitly reset all metadata not handled by initializeMetadata
setParrot(null, true);
setParrot(null, false);
// Absorption is metadata in java edition // Absorption is metadata in java edition
attributes.remove(GeyserAttributeType.ABSORPTION); attributes.remove(GeyserAttributeType.ABSORPTION);
UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();