9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-23 17:09:19 +00:00

Merge pull request #382 from jhqwqmc/dev

fix(sound): 修复通过游戏事件触发的方块破坏音效被remap后未补包导致无声音的问题
This commit is contained in:
XiaoMoMi
2025-09-17 18:44:26 +08:00
committed by GitHub
7 changed files with 54 additions and 25 deletions

View File

@@ -188,16 +188,14 @@ public final class CraftEngineBlocks {
* @param player player who breaks the block
* @param dropLoot whether to drop block loots
* @param isMoving is moving
* @param playSound whether to play break sounds
* @param sendParticles whether to send break particles
* @param sendLevelEvent whether to send break particles and sounds
* @return success or not
*/
public static boolean remove(@NotNull Block block,
@Nullable Player player,
boolean isMoving,
boolean dropLoot,
boolean playSound,
boolean sendParticles) {
boolean sendLevelEvent) {
ImmutableBlockState state = getCustomBlockState(block);
if (state == null || state.isEmpty()) return false;
World world = new BukkitWorld(block.getWorld());
@@ -215,16 +213,34 @@ public final class CraftEngineBlocks {
world.dropItemNaturally(position, item);
}
}
if (playSound) {
world.playBlockSound(position, state.settings().sounds().breakSound());
}
if (sendParticles) {
if (sendLevelEvent) {
FastNMS.INSTANCE.method$LevelAccessor$levelEvent(world.serverWorld(), WorldEvents.BLOCK_BREAK_EFFECT, LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), state.customBlockState().registryId());
}
FastNMS.INSTANCE.method$Level$removeBlock(world.serverWorld(), LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), isMoving);
return true;
}
/**
* Removes a block from the world if it's custom
*
* @param block block to remove
* @param player player who breaks the block
* @param dropLoot whether to drop block loots
* @param isMoving is moving
* @param playSound whether to play break sounds
* @param sendParticles whether to send break particles
* @return success or not
*/
@Deprecated(forRemoval = true)
public static boolean remove(@NotNull Block block,
@Nullable Player player,
boolean isMoving,
boolean dropLoot,
boolean playSound,
boolean sendParticles) {
return remove(block, player, dropLoot, isMoving, playSound || sendParticles);
}
/**
* Checks if a block is custom
*

View File

@@ -7,7 +7,6 @@ import net.momirealms.craftengine.bukkit.util.LocationUtils;
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.world.BlockPos;
import net.momirealms.craftengine.core.world.Vec3d;
import net.momirealms.craftengine.core.world.WorldEvents;
import net.momirealms.craftengine.core.world.WorldPosition;
@@ -69,13 +68,8 @@ public abstract class AbstractCanSurviveBlockBehavior extends BukkitBlockBehavio
FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, blockPos, thisBlock, this.delay);
return state;
}
if (!canSurvive(thisBlock, new Object[] {state, level, blockPos}, () -> true)) {
BlockPos pos = LocationUtils.fromBlockPos(blockPos);
ImmutableBlockState customState = optionalCustomState.get();
net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level));
WorldPosition position = new WorldPosition(world, Vec3d.atCenterOf(pos));
world.playBlockSound(position, customState.settings().sounds().breakSound());
FastNMS.INSTANCE.method$LevelAccessor$levelEvent(level, WorldEvents.BLOCK_BREAK_EFFECT, blockPos, customState.customBlockState().registryId());
if (!FastNMS.INSTANCE.method$BlockStateBase$canSurvive(state, level, blockPos)) {
FastNMS.INSTANCE.method$LevelAccessor$levelEvent(level, WorldEvents.BLOCK_BREAK_EFFECT, blockPos, optionalCustomState.get().customBlockState().registryId());
return MBlocks.AIR$defaultState;
}
return state;

View File

@@ -50,10 +50,6 @@ public class DoubleHighBlockBehavior extends BukkitBlockBehavior {
if (anotherHalfCustomState != null && !anotherHalfCustomState.isEmpty()) return blockState;
// 破坏
BlockPos pos = LocationUtils.fromBlockPos(blockPos);
net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level));
WorldPosition position = new WorldPosition(world, Vec3d.atCenterOf(pos));
world.playBlockSound(position, customState.settings().sounds().breakSound());
FastNMS.INSTANCE.method$LevelAccessor$levelEvent(level, WorldEvents.BLOCK_BREAK_EFFECT, blockPos, customState.customBlockState().registryId());
return MBlocks.AIR$defaultState;
}

View File

@@ -66,10 +66,6 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior {
return MBlocks.AIR$defaultState;
}
ImmutableBlockState customState = optionalCustomState.get();
BlockPos pos = LocationUtils.fromBlockPos(blockPos);
net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level));
WorldPosition position = new WorldPosition(world, Vec3d.atCenterOf(pos));
world.playBlockSound(position, customState.settings().sounds().breakSound());
FastNMS.INSTANCE.method$LevelAccessor$levelEvent(level, WorldEvents.BLOCK_BREAK_EFFECT, blockPos, customState.customBlockState().registryId());
return MBlocks.AIR$defaultState;
}

View File

@@ -514,6 +514,29 @@ public class PacketConsumers {
int state = buf.readInt();
boolean global = buf.readBoolean();
int newState = user.clientModEnabled() ? remapMOD(state) : remap(state);
Object blockState = BlockStateUtils.idToBlockState(newState);
Object block = BlockStateUtils.getBlockOwner(blockState);
if (BukkitBlockManager.instance().isBlockSoundRemoved(block) && !FastNMS.INSTANCE.method$BlockStateBase$isAir(blockState)) {
Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState);
Object breakSound = FastNMS.INSTANCE.field$SoundType$breakSound(soundType);
Key soundId = Key.of(FastNMS.INSTANCE.field$SoundEvent$location(breakSound).toString());
Key mappedSoundId = BukkitBlockManager.instance().replaceSoundIfExist(soundId);
if (mappedSoundId != null) {
Object mappedBreakSound = FastNMS.INSTANCE.constructor$SoundEvent(KeyUtils.toResourceLocation(mappedSoundId), Optional.empty());
Object mappedBreakSoundHolder = FastNMS.INSTANCE.method$Holder$direct(mappedBreakSound);
Object packet = FastNMS.INSTANCE.constructor$ClientboundSoundPacket(
mappedBreakSoundHolder,
CoreReflections.instance$SoundSource$BLOCKS,
blockPos.x() + 0.5,
blockPos.y() + 0.5,
blockPos.z() + 0.5,
(FastNMS.INSTANCE.field$SoundType$volume(soundType) + 1.0F) / 2.0F,
FastNMS.INSTANCE.field$SoundType$pitch(soundType) * 0.8F,
RandomUtils.generateRandomLong()
);
user.sendPacket(packet, true);
}
}
if (newState == state) {
return;
}

View File

@@ -22,6 +22,10 @@ public final class RandomUtils {
return ThreadLocalRandom.current().nextBoolean();
}
public static long generateRandomLong() {
return ThreadLocalRandom.current().nextLong();
}
public static double triangle(double mode, double deviation) {
return mode + deviation * (generateRandomDouble(0,1) - generateRandomDouble(0,1));
}

View File

@@ -50,7 +50,7 @@ byte_buddy_version=1.17.5
ahocorasick_version=0.6.3
snake_yaml_version=2.5
anti_grief_version=0.20
nms_helper_version=1.0.89
nms_helper_version=1.0.90
evalex_version=3.5.0
reactive_streams_version=1.0.4
amazon_awssdk_version=2.33.1