Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/main/java/com/zenith/event/client/BotPrePhysicsTick.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.zenith.event.client;

// Posted once per bot tick, after the bot has applied the server's latest entity metadata sync
// (e.g. fall-flying/pose/abilities) for this tick, but before the bot's local physics/movement step runs.
// Intended for plugins that need to influence tick-local physics-affecting state (e.g. fall-flying) at this
// exact point, so that client-side prediction stays consistent with what the server confirms a moment later.
public record BotPrePhysicsTick() {
public static final BotPrePhysicsTick INSTANCE = new BotPrePhysicsTick();
}
17 changes: 17 additions & 0 deletions src/main/java/com/zenith/feature/player/Bot.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.zenith.cache.data.entity.EntityLiving;
import com.zenith.cache.data.entity.EntityPlayer;
import com.zenith.cache.data.inventory.Container;
import com.zenith.event.client.BotPrePhysicsTick;
import com.zenith.event.client.ClientBotTick;
import com.zenith.event.client.ClientTickEvent;
import com.zenith.feature.spectator.SpectatorSync;
Expand Down Expand Up @@ -374,6 +375,12 @@ && canPlayerFitWithinBlocksAndEntitiesWhen(getCollisionBox(Pose.SNEAKING))
if (movementInput.jumping && !didUpdateFlyState && !wasJumpPressed && !onClimbable() && tryToStartFallFlying()) {
sendClientPacketAsync(new ServerboundPlayerCommandPacket(CACHE.getPlayerCache().getEntityId(), PlayerState.START_ELYTRA_FLYING));
}
// Extension point for plugins: the server's latest entity metadata for this tick (fall-flying included)
// has just been applied above via updateFallFlying(), but the physics/movement step below hasn't run yet.
// Plugins implementing their own movement/flight logic can hook this to adjust tick-local physics-affecting
// state (e.g. via setFallFlying) at the one point in the tick where doing so stays consistent with what
// the server will confirm next, instead of racing the next metadata sync.
EVENT_BUS.post(BotPrePhysicsTick.INSTANCE);
if (isFlying) {
int verticalDirection = 0;
if (this.movementInput.isSneaking()) {
Expand Down Expand Up @@ -1746,6 +1753,16 @@ boolean tryToStartFallFlying() {
}
}

// Public entry point for plugins (e.g. via a BotPrePhysicsTick subscriber) to set local fall-flying state
// directly, without going through tryToStartFallFlying()'s canGlide() gating.
public void setFallFlying(boolean value) {
if (value) {
startFallFlying();
} else {
stopFallFlying();
}
}

void startFallFlying() {
var metadata0 = CACHE.getPlayerCache().getThePlayer().getMetadata().get(0);
if (metadata0 instanceof ByteEntityMetadata bmd0) {
Expand Down