diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index eda8e0c84..73814628f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -184,7 +184,7 @@ public final class EntityDefinitions { .addTranslator(MetadataType.INT, Entity::setAir) // Air/bubbles .addTranslator(MetadataType.OPTIONAL_CHAT, Entity::setDisplayName) .addTranslator(MetadataType.BOOLEAN, Entity::setDisplayNameVisible) - .addTranslator(MetadataType.BOOLEAN, (entity, entityMetadata) -> entity.setFlag(EntityFlag.SILENT, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue())) + .addTranslator(MetadataType.BOOLEAN, Entity::setSilent) .addTranslator(MetadataType.BOOLEAN, Entity::setGravity) .addTranslator(MetadataType.POSE, (entity, entityMetadata) -> entity.setPose(entityMetadata.getValue())) .addTranslator(MetadataType.INT, Entity::setFreezing) diff --git a/core/src/main/java/org/geysermc/geyser/entity/ChestBoatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ChestBoatEntity.java similarity index 96% rename from core/src/main/java/org/geysermc/geyser/entity/ChestBoatEntity.java rename to core/src/main/java/org/geysermc/geyser/entity/type/ChestBoatEntity.java index 76e98d953..724bf921e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/ChestBoatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ChestBoatEntity.java @@ -23,11 +23,11 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.entity; +package org.geysermc.geyser.entity.type; import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import com.nukkitx.math.vector.Vector3f; -import org.geysermc.geyser.entity.type.BoatEntity; +import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java index 52efcf67e..144d1cbf9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java @@ -94,6 +94,8 @@ public class Entity { private float boundingBoxWidth; @Setter(AccessLevel.NONE) protected String nametag = ""; + @Setter(AccessLevel.NONE) + protected boolean silent = false; /* Metadata end */ protected List passengers = Collections.emptyList(); @@ -148,6 +150,12 @@ public class Entity { setFlag(EntityFlag.HAS_COLLISION, true); setFlag(EntityFlag.CAN_SHOW_NAME, true); setFlag(EntityFlag.CAN_CLIMB, true); + // Let the Java server (or us) supply all sounds for an entity + setClientSideSilent(); + } + + protected void setClientSideSilent() { + setFlag(EntityFlag.SILENT, true); } public void spawnEntity() { @@ -370,6 +378,10 @@ public class Entity { dirtyMetadata.put(EntityData.NAMETAG_ALWAYS_SHOW, (byte) (entityMetadata.getPrimitiveValue() ? 1 : 0)); } + public final void setSilent(BooleanEntityMetadata entityMetadata) { + silent = entityMetadata.getPrimitiveValue(); + } + public void setGravity(BooleanEntityMetadata entityMetadata) { setFlag(EntityFlag.HAS_GRAVITY, !entityMetadata.getPrimitiveValue()); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/EvokerFangsEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/EvokerFangsEntity.java index 03c71cec6..af7dca68c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/EvokerFangsEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/EvokerFangsEntity.java @@ -27,7 +27,6 @@ package org.geysermc.geyser.entity.type; 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 org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; @@ -58,7 +57,7 @@ public class EvokerFangsEntity extends Entity implements Tickable { public void setAttackStarted() { this.attackStarted = true; - if (!getFlag(EntityFlag.SILENT)) { + if (!silent) { // Play the chomp sound PlaySoundPacket packet = new PlaySoundPacket(); packet.setPosition(this.position); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java index 57b597781..75bdd9021 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java @@ -28,17 +28,16 @@ package org.geysermc.geyser.entity.type; 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.EntityFlag; import com.nukkitx.protocol.bedrock.packet.PlaySoundPacket; import lombok.Getter; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.player.PlayerEntity; -import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.level.physics.BoundingBox; -import org.geysermc.geyser.translator.collision.BlockCollision; -import org.geysermc.geyser.level.block.BlockStateValues; -import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.level.block.BlockPositionIterator; +import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.physics.BoundingBox; +import org.geysermc.geyser.registry.BlockRegistries; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.collision.BlockCollision; import org.geysermc.geyser.util.BlockUtils; import java.util.UUID; @@ -129,7 +128,7 @@ public class FishingHookEntity extends ThrowableEntity { } private void sendSplashSound(GeyserSession session) { - if (!getFlag(EntityFlag.SILENT)) { + if (!silent) { float volume = (float) (0.2f * Math.sqrt(0.2 * (motion.getX() * motion.getX() + motion.getZ() * motion.getZ()) + motion.getY() * motion.getY())); if (volume > 1) { volume = 1; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java index 1d689e806..6adcb4694 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java @@ -213,7 +213,7 @@ public class EnderDragonEntity extends MobEntity implements Tickable { */ private void effectTick() { Random random = ThreadLocalRandom.current(); - if (!getFlag(EntityFlag.SILENT)) { + if (!silent) { if (Math.cos(wingPosition * 2f * Math.PI) <= -0.3f && Math.cos(lastWingPosition * 2f * Math.PI) >= -0.3f) { PlaySoundPacket playSoundPacket = new PlaySoundPacket(); playSoundPacket.setSound("mob.enderdragon.flap"); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WardenEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WardenEntity.java index 3a8e9d351..0ec12da83 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WardenEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WardenEntity.java @@ -31,13 +31,19 @@ import com.nukkitx.math.GenericMath; 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 org.geysermc.geyser.entity.EntityDefinition; +import org.geysermc.geyser.entity.type.Tickable; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.MathUtils; import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +public class WardenEntity extends MonsterEntity implements Tickable { + private int heartBeatDelay; + private int tickCount; -public class WardenEntity extends MonsterEntity { public WardenEntity(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); } @@ -53,6 +59,23 @@ public class WardenEntity extends MonsterEntity { public void setAngerLevel(IntEntityMetadata entityMetadata) { float anger = (float) entityMetadata.getPrimitiveValue() / 80f; - dirtyMetadata.put(EntityData.HEARTBEAT_INTERVAL_TICKS, 40 - GenericMath.floor(MathUtils.clamp(anger, 0.0F, 1.0F) * 30F)); + heartBeatDelay = 40 - GenericMath.floor(MathUtils.clamp(anger, 0.0F, 1.0F) * 30F); + dirtyMetadata.put(EntityData.HEARTBEAT_INTERVAL_TICKS, heartBeatDelay); + } + + @Override + public void tick() { + if (++tickCount % heartBeatDelay == 0 && !silent) { + // We have to do these calculations because they're clientside on Java Edition but we mute entities + // to prevent hearing their step sounds + ThreadLocalRandom random = ThreadLocalRandom.current(); + + PlaySoundPacket packet = new PlaySoundPacket(); + packet.setSound("mob.warden.heartbeat"); + packet.setPosition(position); + packet.setPitch(1.0f); + packet.setVolume((random.nextFloat() - random.nextFloat()) * 0.2f + 1.0f); + session.sendUpstreamPacket(packet); + } } } 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 db39a34db..d4b703c40 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 @@ -75,6 +75,11 @@ public class SessionPlayerEntity extends PlayerEntity { valid = true; } + @Override + protected void setClientSideSilent() { + // Do nothing, since we want the session player to hear their own footstep sounds for example. + } + @Override public void spawnEntity() { // Already logged in diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/SoundMapping.java b/core/src/main/java/org/geysermc/geyser/registry/type/SoundMapping.java index 4120b6eb5..27b5e631d 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/SoundMapping.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/SoundMapping.java @@ -38,10 +38,10 @@ public class SoundMapping { public SoundMapping(String java, String bedrock, String playsound, int extraData, String identifier, boolean levelEvent) { this.java = java; - this.bedrock = bedrock == null || bedrock.equalsIgnoreCase("") ? null : bedrock; - this.playsound = playsound == null || playsound.equalsIgnoreCase("") ? null : playsound; + this.bedrock = bedrock == null || bedrock.isEmpty() ? null : bedrock; + this.playsound = playsound == null || playsound.isEmpty() ? null : playsound; this.extraData = extraData; - this.identifier = identifier == null || identifier.equalsIgnoreCase("") ? ":" : identifier; + this.identifier = identifier == null || identifier.isEmpty() ? ":" : identifier; this.levelEvent = levelEvent; } } \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java index de4a2c22b..ee342ce3f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.translator.protocol.java.entity; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundEntityEventPacket; -import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.LevelEventType; import com.nukkitx.protocol.bedrock.data.SoundEvent; import com.nukkitx.protocol.bedrock.data.entity.EntityData; @@ -42,7 +41,6 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; -import java.util.Random; import java.util.concurrent.ThreadLocalRandom; @Translator(packet = ClientboundEntityEventPacket.class) @@ -50,6 +48,7 @@ public class JavaEntityEventTranslator extends PacketTranslator