Conversation
There was a problem hiding this comment.
Pull request overview
This PR aims to better match Java Edition’s reduced block breaking speed while flying in Survival by applying a temporary Bedrock Mining Fatigue effect during block break start.
Changes:
- Send a
MobEffectPacket(Mining Fatigue) when starting to break a block while flying in Survival. - Compute the effect duration based on the expected break time derived from
BlockUtils.getBlockMiningProgressPerTick(...).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (session.getGameMode() == GameMode.SURVIVAL && session.isFlying()) { | ||
| MobEffectPacket mobEffectPacket = new MobEffectPacket(); | ||
| mobEffectPacket.setAmplifier(0); | ||
| mobEffectPacket.setDuration((int) (1 / BlockUtils.getBlockMiningProgressPerTick(session, state.block(), item))); | ||
| mobEffectPacket.setEvent(session.getEffectCache().getEntityEffects().contains(Effect.MINING_FATIGUE) ? MobEffectPacket.Event.MODIFY : MobEffectPacket.Event.ADD); |
There was a problem hiding this comment.
This sends a MINING_FATIGUE packet with amplifier 0 and uses MODIFY when the Java effect cache already contains mining fatigue. If the server has applied Mining Fatigue (often at higher amplifiers), this will overwrite the client-side effect and effectively weaken/replace the server-intended debuff. Consider skipping this logic when the player already has mining fatigue, or preserving the existing amplifier/duration rather than forcing amplifier 0.
| if (session.getGameMode() == GameMode.SURVIVAL && session.isFlying()) { | |
| MobEffectPacket mobEffectPacket = new MobEffectPacket(); | |
| mobEffectPacket.setAmplifier(0); | |
| mobEffectPacket.setDuration((int) (1 / BlockUtils.getBlockMiningProgressPerTick(session, state.block(), item))); | |
| mobEffectPacket.setEvent(session.getEffectCache().getEntityEffects().contains(Effect.MINING_FATIGUE) ? MobEffectPacket.Event.MODIFY : MobEffectPacket.Event.ADD); | |
| if (session.getGameMode() == GameMode.SURVIVAL && session.isFlying() | |
| && !session.getEffectCache().getEntityEffects().contains(Effect.MINING_FATIGUE)) { | |
| MobEffectPacket mobEffectPacket = new MobEffectPacket(); | |
| mobEffectPacket.setAmplifier(0); | |
| mobEffectPacket.setDuration((int) (1 / BlockUtils.getBlockMiningProgressPerTick(session, state.block(), item))); | |
| mobEffectPacket.setEvent(MobEffectPacket.Event.ADD); |
core/src/main/java/org/geysermc/geyser/session/cache/BlockBreakHandler.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/geysermc/geyser/session/cache/BlockBreakHandler.java
Show resolved
Hide resolved
5f3628e to
20d4c0f
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import org.geysermc.geyser.translator.protocol.bedrock.BedrockInventoryTransactionTranslator; | ||
| import org.geysermc.geyser.translator.protocol.java.level.JavaBlockDestructionTranslator; | ||
| import org.geysermc.geyser.util.BlockUtils; | ||
| import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect; |
There was a problem hiding this comment.
org.geysermc.mcprotocollib.protocol.data.game.entity.Effect is imported but not used in this class. Unused imports cause compilation failures in Java; please remove it (or use it if intended).
| import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect; |
| // 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 | ||
| if (session.getGameMode() == GameMode.SURVIVAL && session.isFlying() && breakProgress > 0) { | ||
| MobEffectPacket mobEffectPacket = new MobEffectPacket(); | ||
| mobEffectPacket.setAmplifier(0); | ||
| mobEffectPacket.setDuration((int) BlockUtils.reciprocal(breakProgress)); | ||
| mobEffectPacket.setEvent(MobEffectPacket.Event.ADD); | ||
| mobEffectPacket.setRuntimeEntityId(session.getPlayerEntity().geyserId()); | ||
| mobEffectPacket.setEffectId(EffectType.MINING_FATIGUE.getBedrockId()); | ||
| session.sendUpstreamPacket(mobEffectPacket); | ||
| } | ||
|
|
There was a problem hiding this comment.
The injected MINING_FATIGUE effect is added when starting to break a block while flying, but it is never removed when the block is successfully broken (destroyBlock path). This can leave the Bedrock client with mining fatigue after the break completes (until the duration expires), affecting subsequent gameplay. Consider explicitly removing the effect when breaking finishes (and when state is cleared) instead of relying on duration.
| // 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 | |
| if (session.getGameMode() == GameMode.SURVIVAL && session.isFlying() && breakProgress > 0) { | |
| MobEffectPacket mobEffectPacket = new MobEffectPacket(); | |
| mobEffectPacket.setAmplifier(0); | |
| mobEffectPacket.setDuration((int) BlockUtils.reciprocal(breakProgress)); | |
| mobEffectPacket.setEvent(MobEffectPacket.Event.ADD); | |
| mobEffectPacket.setRuntimeEntityId(session.getPlayerEntity().geyserId()); | |
| mobEffectPacket.setEffectId(EffectType.MINING_FATIGUE.getBedrockId()); | |
| session.sendUpstreamPacket(mobEffectPacket); | |
| } |
| // Remove effect again which is applied to simulate survival fly block breaking | ||
| if (session.getGameMode() == GameMode.SURVIVAL && session.isFlying()) { | ||
| MobEffectPacket mobEffectPacket = new MobEffectPacket(); | ||
| mobEffectPacket.setEvent(MobEffectPacket.Event.REMOVE); | ||
| mobEffectPacket.setRuntimeEntityId(session.getPlayerEntity().geyserId()); | ||
| mobEffectPacket.setEffectId(EffectType.MINING_FATIGUE.getBedrockId()); | ||
| session.sendUpstreamPacket(mobEffectPacket); | ||
| } |
There was a problem hiding this comment.
The effect removal is conditional on session.isFlying(). If the player starts breaking while flying (effect applied) but lands before ABORT_BREAK (or a forced abort), this condition will skip removal and leave mining fatigue applied. Track whether the temporary effect was applied and remove it based on that flag (or remove unconditionally when aborting/clearing), rather than checking the current flying state.
|
Also seem to have issues with tools |
20d4c0f to
8832df4
Compare
This simulates the mining speed for survival fly on Bedrock by using effects.
There is no restore yet, as it the penalty would be x11.1 and we certainly have to tick the effects, as the duration might be less and other calculations ignore this fact anyway.