Skip to content

Commit

Permalink
Fix toggleable block opening sounds (doors, trapdoors, fence gates) (G…
Browse files Browse the repository at this point in the history
…eyserMC#4815)

* Initial Commit

* Fix minor copy and paste comment mistake

* Remove debug log

Co-authored-by: chris <github@onechris.mozmail.com>

* Remove iron check on fence gate sound translator

iron fence gates dont exist lol

* Remove iron check from fence gate sound translator.

Iron fence gates dont exist (yet)

* Remove unnecessary curly braces

* Rewrite the code, now functioning correctly with the runtime id

* Update mappings

* Better formatting

Co-authored-by: chris <github@onechris.mozmail.com>

* fix comment because it is referring to code that has been changed

* Hopefully fix double closing

* Seems like the double closing issue isnt from my code and from somewhere else

* Fix issue where doors would update twice when opening/closing them using the upper half

* change weird variable name

---------

Co-authored-by: chris <github@onechris.mozmail.com>
  • Loading branch information
letsgoawaydev and onebeastchris authored Jul 6, 2024
1 parent 9f19c0a commit 3c35fd3
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,22 @@ public DoorBlock(String javaIdentifier, Builder builder) {

@Override
public void updateBlock(GeyserSession session, BlockState state, Vector3i position) {
// Needed to check whether we must force the client to update the door state.
String doubleBlockHalf = state.getValue(Properties.DOUBLE_BLOCK_HALF);

if (doubleBlockHalf.equals("lower")) {
BlockState oldBlockState = session.getGeyser().getWorldManager().blockAt(session, position);
// If these are the same, it means that we already updated the lower door block (manually in the workaround below),
// and we do not need to update the block in the cache/on the client side using the super.updateBlock() method again.
// Otherwise, we send the door updates twice which will cause visual glitches on the client side
if (oldBlockState == state) {
return;
}
}

super.updateBlock(session, state, position);

if (state.getValue(Properties.DOUBLE_BLOCK_HALF).equals("upper")) {
if (doubleBlockHalf.equals("upper")) {
// Update the lower door block as Bedrock client doesn't like door to be closed from the top
// See https://github.com/GeyserMC/Geyser/issues/4358
Vector3i belowDoorPosition = position.sub(0, 1, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ private void checkInteract(GeyserSession session, ClientboundBlockUpdatePacket p
|| lastInteractPos.getZ() != packet.getEntry().getPosition().getZ())) {
return;
}
String identifier = BlockState.of(packet.getEntry().getBlock()).toString(); // This will be yeeted soon. Thanks Chris.
BlockState state = BlockState.of(packet.getEntry().getBlock());
session.setInteracting(false);
BlockSoundInteractionTranslator.handleBlockInteraction(session, lastInteractPos.toFloat(), identifier);
BlockSoundInteractionTranslator.handleBlockInteraction(session, lastInteractPos.toFloat(), state);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import org.cloudburstmc.math.vector.Vector3f;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.registry.Registries;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
Expand All @@ -37,17 +38,16 @@
/**
* Sound interaction handler for when a block is right-clicked.
*/
public interface BlockSoundInteractionTranslator extends SoundInteractionTranslator<String> {

public interface BlockSoundInteractionTranslator extends SoundInteractionTranslator<BlockState> {
/**
* Handles the block interaction when a player
* right-clicks a block.
*
* @param session the session interacting with the block
* @param position the position of the block
* @param identifier the identifier of the block
* @param state the state of the block
*/
static void handleBlockInteraction(GeyserSession session, Vector3f position, String identifier) {
static void handleBlockInteraction(GeyserSession session, Vector3f position, BlockState state) {
// If we need to get the hand identifier, only get it once and save it to a variable
String handIdentifier = null;

Expand All @@ -58,7 +58,7 @@ static void handleBlockInteraction(GeyserSession session, Vector3f position, Str
if (interactionEntry.getKey().blocks().length != 0) {
boolean contains = false;
for (String blockIdentifier : interactionEntry.getKey().blocks()) {
if (identifier.contains(blockIdentifier)) {
if (state.toString().contains(blockIdentifier)) {
contains = true;
break;
}
Expand Down Expand Up @@ -87,7 +87,7 @@ static void handleBlockInteraction(GeyserSession session, Vector3f position, Str
continue;
}
}
((BlockSoundInteractionTranslator) interactionEntry.getValue()).translate(session, position, identifier);
((BlockSoundInteractionTranslator) interactionEntry.getValue()).translate(session, position, state);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.sound.BlockSoundInteractionTranslator;
import org.geysermc.geyser.translator.sound.SoundTranslator;
Expand All @@ -37,7 +38,8 @@
public class BucketSoundInteractionTranslator implements BlockSoundInteractionTranslator {

@Override
public void translate(GeyserSession session, Vector3f position, String identifier) {
public void translate(GeyserSession session, Vector3f position, BlockState state) {
String identifier = state.toString();
if (!session.isPlacedBucket()) {
return; // No bucket was really interacted with
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.sound.BlockSoundInteractionTranslator;
import org.geysermc.geyser.translator.sound.SoundTranslator;
Expand All @@ -36,7 +37,8 @@
public class ComparatorSoundInteractionTranslator implements BlockSoundInteractionTranslator {

@Override
public void translate(GeyserSession session, Vector3f position, String identifier) {
public void translate(GeyserSession session, Vector3f position, BlockState state) {
String identifier = state.toString();
boolean powered = identifier.contains("mode=compare");
LevelEventPacket levelEventPacket = new LevelEventPacket();
levelEventPacket.setPosition(position);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket;
import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.sound.BlockSoundInteractionTranslator;
import org.geysermc.geyser.translator.sound.SoundTranslator;
Expand All @@ -36,7 +37,7 @@
public class FlintAndSteelInteractionTranslator implements BlockSoundInteractionTranslator {

@Override
public void translate(GeyserSession session, Vector3f position, String identifier) {
public void translate(GeyserSession session, Vector3f position, BlockState state) {
LevelSoundEventPacket levelSoundEventPacket = new LevelSoundEventPacket();
levelSoundEventPacket.setPosition(position);
levelSoundEventPacket.setBabySound(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket;
import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.sound.BlockSoundInteractionTranslator;
Expand All @@ -37,7 +38,8 @@
public class GrassPathInteractionTranslator implements BlockSoundInteractionTranslator {

@Override
public void translate(GeyserSession session, Vector3f position, String identifier) {
public void translate(GeyserSession session, Vector3f position, BlockState state) {
String identifier = state.toString();
LevelSoundEventPacket levelSoundEventPacket = new LevelSoundEventPacket();
levelSoundEventPacket.setPosition(position);
levelSoundEventPacket.setBabySound(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket;
import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.sound.BlockSoundInteractionTranslator;
Expand All @@ -37,7 +38,8 @@
public class HoeInteractionTranslator implements BlockSoundInteractionTranslator {

@Override
public void translate(GeyserSession session, Vector3f position, String identifier) {
public void translate(GeyserSession session, Vector3f position, BlockState state) {
String identifier = state.toString();
LevelSoundEventPacket levelSoundEventPacket = new LevelSoundEventPacket();
levelSoundEventPacket.setPosition(position);
levelSoundEventPacket.setBabySound(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.sound.BlockSoundInteractionTranslator;
import org.geysermc.geyser.translator.sound.SoundTranslator;
Expand All @@ -36,7 +37,8 @@
public class LeverSoundInteractionTranslator implements BlockSoundInteractionTranslator {

@Override
public void translate(GeyserSession session, Vector3f position, String identifier) {
public void translate(GeyserSession session, Vector3f position, BlockState state) {
String identifier = state.toString();
boolean powered = identifier.contains("powered=true");
LevelEventPacket levelEventPacket = new LevelEventPacket();
levelEventPacket.setPosition(position);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,42 @@

import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket;
import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.sound.BlockSoundInteractionTranslator;
import org.geysermc.geyser.translator.sound.SoundTranslator;

@SoundTranslator(blocks = {"door", "fence_gate"})
public class DoorSoundInteractionTranslator implements BlockSoundInteractionTranslator {
public class OpenableSoundInteractionTranslator implements BlockSoundInteractionTranslator {

@Override
public void translate(GeyserSession session, Vector3f position, String identifier) {
public void translate(GeyserSession session, Vector3f position, BlockState state) {
String identifier = state.toString();
if (identifier.contains("iron")) return;
LevelEventPacket levelEventPacket = new LevelEventPacket();
levelEventPacket.setType(LevelEvent.SOUND_DOOR_OPEN);
levelEventPacket.setPosition(position);
levelEventPacket.setData(0);
session.sendUpstreamPacket(levelEventPacket);
SoundEvent event = getSound(identifier.contains("open=true"), identifier);
LevelSoundEventPacket levelSoundEventPacket = new LevelSoundEventPacket();
levelSoundEventPacket.setPosition(position.add(0.5, 0.5, 0.5));
levelSoundEventPacket.setBabySound(false);
levelSoundEventPacket.setRelativeVolumeDisabled(false);
levelSoundEventPacket.setIdentifier(":");
levelSoundEventPacket.setSound(event);
levelSoundEventPacket.setExtraData(session.getBlockMappings().getBedrockBlock(state).getRuntimeId());
session.sendUpstreamPacket(levelSoundEventPacket);
}

private SoundEvent getSound(boolean open, String identifier) {
if (identifier.contains("_door")) {
return open ? SoundEvent.DOOR_OPEN : SoundEvent.DOOR_CLOSE;
}

if (identifier.contains("_trapdoor")) {
return open ? SoundEvent.TRAPDOOR_OPEN : SoundEvent.TRAPDOOR_CLOSE;
}

// Fence Gate
return open ? SoundEvent.FENCE_GATE_OPEN : SoundEvent.FENCE_GATE_CLOSE;
}
}
4 changes: 2 additions & 2 deletions core/src/main/java/org/geysermc/geyser/util/SoundUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public static void playSound(GeyserSession session, Sound javaSound, Vector3f po
}
if (sound == null) {
session.getGeyser().getLogger().debug("[Builtin] Sound for original '" + soundIdentifier + "' to mappings '" + soundMapping.getBedrock()
+ "' was not a playable level sound, or has yet to be mapped to an enum in SoundEvent.");
+ "' was not a playable level sound, or has yet to be mapped to an enum in SoundEvent.");
return;
}

Expand All @@ -144,7 +144,7 @@ public static void playSound(GeyserSession session, Sound javaSound, Vector3f po
// Minecraft Wiki: 2^(x/12) = Java pitch where x is -12 to 12
// Java sends the note value as above starting with -12 and ending at 12
// Bedrock has a number for each type of note, then proceeds up the scale by adding to that number
soundPacket.setExtraData(soundMapping.getExtraData() + (int)(Math.round((Math.log10(pitch) / Math.log10(2)) * 12)) + 12);
soundPacket.setExtraData(soundMapping.getExtraData() + (int) (Math.round((Math.log10(pitch) / Math.log10(2)) * 12)) + 12);
} else if (sound == SoundEvent.PLACE && soundMapping.getExtraData() == -1) {
if (!soundMapping.getIdentifier().equals(":")) {
int javaId = BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getOrDefault(soundMapping.getIdentifier(), Block.JAVA_AIR_ID);
Expand Down

0 comments on commit 3c35fd3

Please sign in to comment.