Skip to content

Commit dd762a6

Browse files
committed
basic bounce elytra fly in ElytraFly, and NoJumpCooldown module
1 parent 9d2dc38 commit dd762a6

File tree

7 files changed

+116
-12
lines changed

7 files changed

+116
-12
lines changed

src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import com.lambda.event.events.TickEvent;
2525
import com.lambda.interaction.PlayerPacketHandler;
2626
import com.lambda.interaction.managers.rotating.RotationManager;
27+
import com.lambda.module.modules.movement.ElytraFly;
28+
import com.lambda.module.modules.movement.NoJumpCooldown;
2729
import com.lambda.module.modules.player.PortalGui;
2830
import com.lambda.module.modules.render.ViewModel;
2931
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
@@ -76,6 +78,11 @@ void processMovement(Input input, Operation<Void> original) {
7678
EventFlow.post(new MovementEvent.InputUpdate(input));
7779
}
7880

81+
@Inject(method = "tickMovement", at = @At("RETURN"))
82+
private void injectTickMovement(CallbackInfo ci) {
83+
if (NoJumpCooldown.INSTANCE.isEnabled() || (ElytraFly.INSTANCE.isEnabled() && ElytraFly.getMode() == ElytraFly.FlyMode.Bounce)) jumpingCooldown = 0;
84+
}
85+
7986
@Inject(method = "sendMovementPackets", at = @At("HEAD"))
8087
private void injectSendMovementPackets(CallbackInfo ci) {
8188
PlayerPacketHandler.sendPlayerPackets();

src/main/java/com/lambda/mixin/entity/EntityMixin.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.lambda.event.events.EntityEvent;
2323
import com.lambda.event.events.PlayerEvent;
2424
import com.lambda.interaction.managers.rotating.RotationManager;
25+
import com.lambda.module.modules.movement.ElytraFly;
2526
import com.lambda.module.modules.render.NoRender;
2627
import com.lambda.util.math.Vec2d;
2728
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
@@ -37,6 +38,7 @@
3738
import org.spongepowered.asm.mixin.injection.At;
3839
import org.spongepowered.asm.mixin.injection.Inject;
3940
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
41+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
4042

4143
@Mixin(Entity.class)
4244
public abstract class EntityMixin {
@@ -154,4 +156,11 @@ private boolean wrapSetYaw(Entity instance, float yaw) {
154156
private boolean wrapSetPitch(Entity instance, float yaw) {
155157
return RotationManager.getLockPitch() == null;
156158
}
159+
160+
@Inject(method = "isSprinting()Z", at = @At("HEAD"), cancellable = true)
161+
private void injectIsSprinting(CallbackInfoReturnable<Boolean> cir) {
162+
var player = Lambda.getMc().player;
163+
if ((Object) this != Lambda.getMc().player) return;
164+
if (ElytraFly.INSTANCE.isEnabled() && ElytraFly.getSprint() && player.isGliding()) cir.setReturnValue(true);
165+
}
157166
}

src/main/java/com/lambda/mixin/entity/FireworkRocketEntityMixin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
public class FireworkRocketEntityMixin {
3131
@WrapOperation(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;setVelocity(Lnet/minecraft/util/math/Vec3d;)V"))
3232
private void wrapSetVelocity(LivingEntity shooter, Vec3d vec3d, Operation<Void> original) {
33-
if (ElytraFly.getDoBoost()) {
33+
if (ElytraFly.INSTANCE.isEnabled()) {
3434
ElytraFly.boostRocket();
3535
} else original.call(shooter, vec3d);
3636
}

src/main/java/com/lambda/mixin/entity/LivingEntityMixin.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.lambda.event.EventFlow;
2222
import com.lambda.event.events.MovementEvent;
2323
import com.lambda.interaction.managers.rotating.RotationManager;
24+
import com.lambda.module.modules.movement.ElytraFly;
2425
import com.lambda.module.modules.movement.Velocity;
2526
import com.lambda.module.modules.render.ViewModel;
2627
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
@@ -30,15 +31,15 @@
3031
import net.minecraft.entity.LivingEntity;
3132
import net.minecraft.util.math.MathHelper;
3233
import net.minecraft.util.math.Vec3d;
34+
import org.jetbrains.annotations.Nullable;
3335
import org.spongepowered.asm.mixin.Mixin;
3436
import org.spongepowered.asm.mixin.Shadow;
3537
import org.spongepowered.asm.mixin.Unique;
3638
import org.spongepowered.asm.mixin.injection.At;
37-
import org.spongepowered.asm.mixin.injection.Constant;
3839
import org.spongepowered.asm.mixin.injection.Inject;
39-
import org.spongepowered.asm.mixin.injection.ModifyConstant;
4040
import org.spongepowered.asm.mixin.injection.Slice;
4141
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
42+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
4243

4344
@Mixin(LivingEntity.class)
4445
public abstract class LivingEntityMixin extends EntityMixin {
@@ -184,4 +185,21 @@ private void wrapPushAwayFrom(Entity entity, Operation<Void> original) {
184185
Velocity.getPushed()) return;
185186
original.call(entity);
186187
}
188+
189+
@Nullable
190+
@Unique
191+
Boolean previouslyFlying = null;
192+
193+
@Inject(method = "isGliding", at = @At("HEAD"), cancellable = true)
194+
private void injectIsGliding(CallbackInfoReturnable<Boolean> cir) {
195+
if (lambda$instance != Lambda.getMc().player) return;
196+
var original = lambda$instance.getFlag(Entity.GLIDING_FLAG_INDEX);
197+
if (previouslyFlying == null) {
198+
previouslyFlying = original;
199+
return;
200+
}
201+
if (ElytraFly.INSTANCE.isEnabled() && ElytraFly.getMode() == ElytraFly.FlyMode.Bounce && previouslyFlying) {
202+
cir.setReturnValue(true);
203+
} else previouslyFlying = original;
204+
}
187205
}

src/main/kotlin/com/lambda/module/modules/movement/ElytraFly.kt

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,35 +17,69 @@
1717

1818
package com.lambda.module.modules.movement
1919

20+
import com.lambda.config.AutomationConfig.Companion.setDefaultAutomationConfig
21+
import com.lambda.config.applyEdits
2022
import com.lambda.event.events.ClientEvent
2123
import com.lambda.event.events.MovementEvent
24+
import com.lambda.event.events.TickEvent
2225
import com.lambda.event.listener.SafeListener.Companion.listen
26+
import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest
2327
import com.lambda.module.Module
2428
import com.lambda.module.tag.ModuleTag
2529
import com.lambda.threading.runSafe
2630
import com.lambda.util.extension.isElytraFlying
2731
import com.lambda.util.player.MovementUtils.addSpeed
32+
import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket
2833
import net.minecraft.sound.SoundEvents
2934

3035
object ElytraFly : Module(
3136
name = "ElytraFly",
3237
description = "Allows you to fly with an elytra",
3338
tag = ModuleTag.MOVEMENT,
3439
) {
35-
private val playerBoost by setting("Player Boost", true, description = "Boosts the player when flying")
36-
private val playerSpeed by setting("Player Speed", 0.02, 0.0..0.5, 0.005, description = "Speed to add when flying") { playerBoost }
37-
private val rocketBoost by setting("Rocket Boost", false, description = "Boosts the player when using a firework")
38-
private val rocketSpeed by setting("Rocket Speed", 2.0, 0.0 ..2.0, description = "Speed multiplier that the rocket gives you") { rocketBoost }
40+
@JvmStatic val mode by setting("Mode", FlyMode.Bounce)
3941

40-
private val mute by setting("Mute Elytra", false, "Mutes the elytra sound when gliding")
42+
//ToDo: Implement these commented out settings
43+
// private val takeoff by setting("Takeoff", true, "Automatically jumps and initiates gliding") { mode == FlyMode.Bounce }
44+
private val autoPitch by setting("Auto Pitch", true, "Automatically pitches the players rotation down to bounce at faster speeds") { mode == FlyMode.Bounce }
45+
private val pitch by setting("Pitch", 70, 0..90, 1) { autoPitch && mode == FlyMode.Bounce }
46+
private val jump by setting("Jump", true, "Automatically jumps") { mode == FlyMode.Bounce }
47+
@JvmStatic val sprint by setting("Sprint", true) { mode == FlyMode.Bounce }
48+
// private val passObstacles by setting("Pass Obstacles", true, "Automatically paths around obstacles using baritone") { mode == FlyMode.Bounce }
4149

42-
@JvmStatic
43-
val doBoost: Boolean get() = isEnabled && rocketBoost
50+
private val boostSpeed by setting("Boost", 0.02, 0.0..0.5, 0.005, description = "Speed to add when flying")
51+
private val rocketSpeed by setting("Rocket Speed", 0.0, 0.0 ..2.0, description = "Speed multiplier that the rocket gives you") { mode == FlyMode.Enhanced }
52+
53+
private val mute by setting("Mute Elytra", false, "Mutes the elytra sound when gliding")
4454

4555
init {
56+
setDefaultAutomationConfig {
57+
applyEdits {
58+
hideAllGroupsExcept(inventoryConfig)
59+
}
60+
}
61+
62+
listen<TickEvent.Pre> {
63+
if (mode != FlyMode.Bounce) return@listen
64+
if (autoPitch) {
65+
rotationRequest {
66+
pitch(pitch.toFloat())
67+
}.submit()
68+
}
69+
70+
if (mode == FlyMode.Bounce && player.isGliding)
71+
connection.sendPacket(ClientCommandC2SPacket(player, ClientCommandC2SPacket.Mode.START_FALL_FLYING))
72+
}
73+
74+
listen<MovementEvent.InputUpdate> { event ->
75+
if (player.isGliding && mode == FlyMode.Bounce && jump) {
76+
event.input.jump()
77+
}
78+
}
79+
4680
listen<MovementEvent.Player.Pre> {
47-
if (playerBoost && player.isElytraFlying && !player.isUsingItem) {
48-
addSpeed(playerSpeed)
81+
if (player.isElytraFlying && !player.isUsingItem) {
82+
addSpeed(boostSpeed)
4983
}
5084
}
5185

@@ -58,6 +92,7 @@ object ElytraFly : Module(
5892

5993
@JvmStatic
6094
fun boostRocket() = runSafe {
95+
if (mode == FlyMode.Bounce) return@runSafe
6196
val vec = player.rotationVector
6297
val velocity = player.velocity
6398

@@ -70,4 +105,9 @@ object ElytraFly : Module(
70105
vec.z * e + (vec.z * d - velocity.z) * 0.5
71106
)
72107
}
108+
109+
enum class FlyMode {
110+
Bounce,
111+
Enhanced
112+
}
73113
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.module.modules.movement
19+
20+
import com.lambda.module.Module
21+
import com.lambda.module.tag.ModuleTag
22+
23+
object NoJumpCooldown : Module(
24+
name = "NoJumpCooldown",
25+
description = "Removes delay between jumps",
26+
tag = ModuleTag.MOVEMENT
27+
)

src/main/resources/lambda.accesswidener

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ transitive-accessible field net/minecraft/state/State owner Ljava/lang/Object;
2929
# MOVED in 1.21.11: BackgroundRenderer$StatusEffectFogModifier -> net/minecraft/client/render/fog/StatusEffectFogModifier
3030
transitive-accessible class net/minecraft/client/render/fog/StatusEffectFogModifier
3131
transitive-accessible field net/minecraft/client/particle/NoRenderParticleRenderer EMPTY Lnet/minecraft/client/render/Submittable;
32+
transitive-accessible field net/minecraft/entity/Entity GLIDING_FLAG_INDEX I
33+
transitive-accessible method net/minecraft/entity/Entity getFlag (I)Z
3234

3335
# Entity
3436
transitive-accessible field net/minecraft/entity/projectile/FireworkRocketEntity shooter Lnet/minecraft/entity/LivingEntity;
@@ -55,6 +57,7 @@ transitive-accessible field net/minecraft/screen/ScreenHandler revision I
5557
transitive-accessible field net/minecraft/entity/Entity world Lnet/minecraft/world/World;
5658
transitive-accessible class net/minecraft/screen/slot/ArmorSlot
5759
transitive-accessible field net/minecraft/screen/slot/ArmorSlot equipmentSlot Lnet/minecraft/entity/EquipmentSlot;
60+
transitive-accessible field net/minecraft/entity/Entity FLAGS Lnet/minecraft/entity/data/TrackedData;
5861

5962
# Camera
6063
transitive-accessible method net/minecraft/client/render/Camera setPos (DDD)V

0 commit comments

Comments
 (0)