From 9f19c0a9f614d9e40141fb490163aa3ca2d66cd2 Mon Sep 17 00:00:00 2001 From: Ethan <68365423+letsgoawaydev@users.noreply.github.com> Date: Sat, 6 Jul 2024 17:58:54 +0800 Subject: [PATCH] Fix: Trial Spawner Level Events (#4821) * commit every thing i could do, couldnt get it to work with ominous stuff * Fix trial spawner events to work correctly. * Update mappings to latest * fix comment * Workaround for buggy trial chamber particles * Fix positioning and also fix become ominous event * Fix sounds and positioning again * Fix random new line * Update mappings * update cloudburst library to 20240704.153116-14 * Fix accidental random line --- .../java/level/JavaLevelEventTranslator.java | 134 +++++++++++++++--- core/src/main/resources/mappings | 2 +- gradle/libs.versions.toml | 2 +- 3 files changed, 116 insertions(+), 22 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java index d4e317af4..542af1598 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java @@ -28,9 +28,16 @@ package org.geysermc.geyser.translator.protocol.java.level; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.data.ParticleType; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; -import org.cloudburstmc.protocol.bedrock.packet.*; +import org.cloudburstmc.protocol.bedrock.packet.LevelEventGenericPacket; +import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; +import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket; +import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket; +import org.cloudburstmc.protocol.bedrock.packet.SpawnParticleEffectPacket; +import org.cloudburstmc.protocol.bedrock.packet.StopSoundPacket; +import org.cloudburstmc.protocol.bedrock.packet.TextPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.level.JukeboxSong; import org.geysermc.geyser.registry.Registries; @@ -40,13 +47,27 @@ import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.level.event.LevelEventTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.geyser.util.DimensionUtils; import org.geysermc.geyser.util.SoundUtils; import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; -import org.geysermc.mcprotocollib.protocol.data.game.level.event.*; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.BonemealGrowEventData; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.BreakBlockEventData; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.BreakPotionEventData; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.ComposterEventData; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.DragonFireballEventData; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEventType; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.RecordEventData; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.SculkBlockChargeEventData; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.SmokeEventData; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.TrialSpawnerDetectEventData; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.UnknownLevelEventData; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; import java.util.Collections; +import java.util.Optional; +import java.util.Random; import java.util.Set; +import java.util.concurrent.ThreadLocalRandom; @Translator(packet = ClientboundLevelEventPacket.class) public class JavaLevelEventTranslator extends PacketTranslator { @@ -291,6 +312,20 @@ public class JavaLevelEventTranslator extends PacketTranslator effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.ANIMATION_SPAWN_COBWEB); + case ANIMATION_VAULT_ACTIVATE -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.ANIMATION_VAULT_ACTIVATE); + case ANIMATION_VAULT_DEACTIVATE -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.ANIMATION_VAULT_DEACTIVATE); + case ANIMATION_VAULT_EJECT_ITEM -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.ANIMATION_VAULT_EJECT_ITEM); + case ANIMATION_TRIAL_SPAWNER_EJECT_ITEM -> { + Random random = ThreadLocalRandom.current(); + PlaySoundPacket playSoundPacket = new PlaySoundPacket(); + playSoundPacket.setSound("trial_spawner.eject_item"); + playSoundPacket.setPosition(pos); + playSoundPacket.setVolume(1.0f); + playSoundPacket.setPitch(0.8f + random.nextFloat() * 0.3f); + session.sendUpstreamPacket(playSoundPacket); + return; + } case DRIPSTONE_DRIP -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_DRIPSTONE_DRIP); case PARTICLES_ELECTRIC_SPARK -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_ELECTRIC_SPARK); // Matches with a Bedrock server but doesn't seem to match up with Java case PARTICLES_AND_SOUND_WAX_ON -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_WAX_ON); @@ -303,22 +338,22 @@ public class JavaLevelEventTranslator extends PacketTranslator 0) { levelEventPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.SCULK_CHARGE); levelEventPacket.setTag( - NbtMap.builder() - .putInt("x", packet.getPosition().getX()) - .putInt("y", packet.getPosition().getY()) - .putInt("z", packet.getPosition().getZ()) - .putShort("charge", (short) eventData.getCharge()) - .putShort("facing", encodeFacing(eventData.getBlockFaces())) // TODO check if this is actually correct - .build() + NbtMap.builder() + .putInt("x", packet.getPosition().getX()) + .putInt("y", packet.getPosition().getY()) + .putInt("z", packet.getPosition().getZ()) + .putShort("charge", (short) eventData.getCharge()) + .putShort("facing", encodeFacing(eventData.getBlockFaces())) // TODO check if this is actually correct + .build() ); } else { levelEventPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.SCULK_CHARGE_POP); levelEventPacket.setTag( - NbtMap.builder() - .putInt("x", packet.getPosition().getX()) - .putInt("y", packet.getPosition().getY()) - .putInt("z", packet.getPosition().getZ()) - .build() + NbtMap.builder() + .putInt("x", packet.getPosition().getX()) + .putInt("y", packet.getPosition().getY()) + .putInt("z", packet.getPosition().getZ()) + .build() ); } session.sendUpstreamPacket(levelEventPacket); @@ -328,11 +363,11 @@ public class JavaLevelEventTranslator extends PacketTranslator { + // Particles spawn here + TrialSpawnerDetectEventData eventData = (TrialSpawnerDetectEventData) packet.getData(); + effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_TRIAL_SPAWNER_DETECTION); + // 0.75 is used here for Y instead of 0.5 to match Java Positioning. + // 0.5 is what the BDS uses for positioning. + effectPacket.setPosition(pos.sub(0.5f, 0.75f, 0.5f)); + effectPacket.setData(eventData.getDetectedPlayers()); + } + case PARTICLES_TRIAL_SPAWNER_DETECT_PLAYER_OMINOUS -> { + effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_TRIAL_SPAWNER_DETECTION_CHARGED); + effectPacket.setPosition(pos.sub(0.5f, 0.75f, 0.5f)); + /* + Particles don't spawn here for some reason, only sound plays + This seems to be a bug in v1.21.0 and v1.21.1: see https://bugs.mojang.com/browse/MCPE-181465 + If this gets fixed, the spawnOminousTrialSpawnerParticles function can be removed. + The positioning should be the same as normal activation. + */ + spawnOminousTrialSpawnerParticles(session, pos); + } + case PARTICLES_TRIAL_SPAWNER_BECOME_OMINOUS -> { + effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_TRIAL_SPAWNER_BECOME_CHARGED); + effectPacket.setPosition(pos.sub(0.5f, 0.5f, 0.5f)); + // Same issue as above here + spawnOminousTrialSpawnerParticles(session, pos); + } + case PARTICLES_TRIAL_SPAWNER_SPAWN_MOB_AT -> { + // This should be its own class in MCProtocolLib. + // if 0, use Orange Flames, + // if 1, use Blue Flames for ominous spawners + UnknownLevelEventData eventData = (UnknownLevelEventData) packet.getData(); + effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_TRIAL_SPAWNER_SPAWNING); + effectPacket.setData(eventData.getData()); + } + case PARTICLES_TRIAL_SPAWNER_SPAWN -> { + UnknownLevelEventData eventData = (UnknownLevelEventData) packet.getData(); + effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_TRIAL_SPAWNER_SPAWNING); + effectPacket.setData(eventData.getData()); + + Random random = ThreadLocalRandom.current(); + PlaySoundPacket playSoundPacket = new PlaySoundPacket(); + playSoundPacket.setSound("trial_spawner.spawn_mob"); + playSoundPacket.setPosition(pos); + playSoundPacket.setVolume(1.0f); + playSoundPacket.setPitch(0.8f + random.nextFloat() * 0.3f); + session.sendUpstreamPacket(playSoundPacket); + } + case PARTICLES_TRIAL_SPAWNER_SPAWN_ITEM -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_TRIAL_SPAWNER_EJECTING); case SOUND_STOP_JUKEBOX_SONG -> { String bedrockSound = session.getWorldCache().removeActiveRecord(origin); if (bedrockSound == null) { @@ -396,4 +479,15 @@ public class JavaLevelEventTranslator extends PacketTranslator