|
40 | 40 | import org.cloudburstmc.protocol.bedrock.data.PlayerBlockActionData; |
41 | 41 | import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; |
42 | 42 | import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; |
| 43 | +import org.cloudburstmc.protocol.bedrock.packet.MobEffectPacket; |
43 | 44 | import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket; |
44 | 45 | import org.geysermc.geyser.GeyserImpl; |
45 | 46 | import org.geysermc.geyser.api.block.custom.CustomBlockState; |
46 | 47 | import org.geysermc.geyser.entity.EntityDefinitions; |
47 | 48 | import org.geysermc.geyser.entity.type.Entity; |
48 | 49 | import org.geysermc.geyser.entity.type.ItemFrameEntity; |
49 | 50 | import org.geysermc.geyser.inventory.GeyserItemStack; |
| 51 | +import org.geysermc.geyser.level.EffectType; |
50 | 52 | import org.geysermc.geyser.level.block.Blocks; |
51 | 53 | import org.geysermc.geyser.level.block.type.Block; |
52 | 54 | import org.geysermc.geyser.level.block.type.BlockState; |
|
60 | 62 | import org.geysermc.geyser.translator.protocol.java.level.JavaBlockDestructionTranslator; |
61 | 63 | import org.geysermc.geyser.util.BlockUtils; |
62 | 64 | import org.geysermc.mcprotocollib.protocol.data.game.entity.player.BlockBreakStage; |
| 65 | +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; |
63 | 66 | import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction; |
64 | 67 | import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerAction; |
65 | 68 | import org.geysermc.mcprotocollib.protocol.data.game.item.component.AdventureModePredicate; |
@@ -327,6 +330,17 @@ protected void handleStartBreak(@NonNull Vector3i position, @NonNull BlockState |
327 | 330 | this.serverSideBlockBreaking = true; |
328 | 331 | } |
329 | 332 |
|
| 333 | + // Survival fly in Bedrock doesn't come with a mining speed penalty, but we can use effects to lower the mining speed to match Java's one |
| 334 | + if (session.getGameMode() == GameMode.SURVIVAL && session.isFlying() && breakProgress > 0) { |
| 335 | + MobEffectPacket mobEffectPacket = new MobEffectPacket(); |
| 336 | + mobEffectPacket.setAmplifier(0); |
| 337 | + mobEffectPacket.setDuration((int) BlockUtils.reciprocal(breakProgress)); |
| 338 | + mobEffectPacket.setEvent(MobEffectPacket.Event.ADD); |
| 339 | + mobEffectPacket.setRuntimeEntityId(session.getPlayerEntity().geyserId()); |
| 340 | + mobEffectPacket.setEffectId(EffectType.MINING_FATIGUE.getBedrockId()); |
| 341 | + session.sendUpstreamPacket(mobEffectPacket); |
| 342 | + } |
| 343 | + |
330 | 344 | LevelEventPacket startBreak = new LevelEventPacket(); |
331 | 345 | startBreak.setType(LevelEvent.BLOCK_START_BREAK); |
332 | 346 | startBreak.setPosition(position.toFloat()); |
@@ -419,6 +433,15 @@ private void handleAbortBreaking(Vector3i position) { |
419 | 433 | session.sendDownstreamGamePacket(abortBreakingPacket); |
420 | 434 | } |
421 | 435 |
|
| 436 | + // Remove effect again which is applied to simulate survival fly block breaking |
| 437 | + if (session.getGameMode() == GameMode.SURVIVAL && session.isFlying()) { |
| 438 | + MobEffectPacket mobEffectPacket = new MobEffectPacket(); |
| 439 | + mobEffectPacket.setEvent(MobEffectPacket.Event.REMOVE); |
| 440 | + mobEffectPacket.setRuntimeEntityId(session.getPlayerEntity().geyserId()); |
| 441 | + mobEffectPacket.setEffectId(EffectType.MINING_FATIGUE.getBedrockId()); |
| 442 | + session.sendUpstreamPacket(mobEffectPacket); |
| 443 | + } |
| 444 | + |
422 | 445 | BlockUtils.sendBedrockStopBlockBreak(session, position.toFloat()); |
423 | 446 | this.clearCurrentVariables(); |
424 | 447 | } |
|
0 commit comments