@@ -4,16 +4,19 @@ import com.lambda.client.commons.extension.toRadian
44import com.lambda.client.event.SafeClientEvent
55import com.lambda.client.event.events.PacketEvent
66import com.lambda.client.event.events.PlayerTravelEvent
7+ import com.lambda.client.manager.managers.HotbarManager.resetHotbar
8+ import com.lambda.client.manager.managers.HotbarManager.serverSideItem
9+ import com.lambda.client.manager.managers.HotbarManager.spoofHotbar
710import com.lambda.client.manager.managers.PlayerPacketManager.sendPlayerPacket
8- import com.lambda.client.mixin.extension.boostedEntity
9- import com.lambda.client.mixin.extension.playerPosLookPitch
10- import com.lambda.client.mixin.extension.tickLength
11- import com.lambda.client.mixin.extension.timer
11+ import com.lambda.client.mixin.extension.*
1212import com.lambda.client.module.Category
1313import com.lambda.client.module.Module
1414import com.lambda.client.module.modules.player.LagNotifier
1515import com.lambda.client.util.MovementUtils.calcMoveYaw
1616import com.lambda.client.util.MovementUtils.speed
17+ import com.lambda.client.util.TickTimer
18+ import com.lambda.client.util.TimeUnit
19+ import com.lambda.client.util.items.*
1720import com.lambda.client.util.math.Vec2f
1821import com.lambda.client.util.text.MessageSendHelper.sendChatMessage
1922import com.lambda.client.util.threads.runSafe
@@ -24,9 +27,14 @@ import net.minecraft.client.audio.PositionedSoundRecord
2427import net.minecraft.entity.item.EntityFireworkRocket
2528import net.minecraft.init.Items
2629import net.minecraft.init.SoundEvents
30+ import net.minecraft.item.ItemFirework
31+ import net.minecraft.item.ItemStack
2732import net.minecraft.network.play.client.CPacketEntityAction
33+ import net.minecraft.network.play.client.CPacketPlayerTryUseItem
2834import net.minecraft.network.play.server.SPacketEntityMetadata
2935import net.minecraft.network.play.server.SPacketPlayerPosLook
36+ import net.minecraft.util.EnumHand
37+ import net.minecraft.util.math.RayTraceResult
3038import kotlin.math.*
3139
3240
@@ -99,10 +107,25 @@ object ElytraFlight : Module(
99107 private val downPitch by setting(" Down Pitch" , 0f , 0f .. 90f , 5f , { mode.value == ElytraFlightMode .VANILLA && page == Page .MODE_SETTINGS })
100108 private val rocketPitch by setting(" Rocket Pitch" , 50f , 0f .. 90f , 5f , { mode.value == ElytraFlightMode .VANILLA && page == Page .MODE_SETTINGS })
101109
110+ /* Fireworks */
111+ private val fireworkUseMode by setting(" Firework Use Mode" , FireworkUseMode .SPEED , { mode.value == ElytraFlightMode .FIREWORKS && page == Page .MODE_SETTINGS })
112+ private val delay by setting(" Fireworks Delay Ticks" , 30 , 0 .. 100 , 1 , { mode.value == ElytraFlightMode .FIREWORKS && fireworkUseMode == FireworkUseMode .DELAY && page == Page .MODE_SETTINGS })
113+ private val fireworkUseStartSpeed by setting (" Fireworks Use Min Speed" , 1.0 , 0.01 .. 3.0 , 0.01 , { mode.value == ElytraFlightMode .FIREWORKS && fireworkUseMode == FireworkUseMode .SPEED && page == Page .MODE_SETTINGS })
114+ private val fireworkBlockAvoid by setting(" Avoid Blocks" , false , { mode.value == ElytraFlightMode .FIREWORKS && page == Page .MODE_SETTINGS },
115+ description = " Don't use fireworks if player is facing into a block" )
116+ private val fireworkBlockAvoidDist by setting(" Avoid Blocks Raytrace Distance" , 2.0 , 1.0 .. 10.0 , 0.1 , { mode.value == ElytraFlightMode .FIREWORKS && page == Page .MODE_SETTINGS && fireworkBlockAvoid })
117+ private val fireworksVControl by setting(" Boosted V Control" , true , { mode.value == ElytraFlightMode .FIREWORKS && page == Page .MODE_SETTINGS })
118+ private val fireworksVSpeed by setting(" Boosted V Control Speed" , 1.0 , 0.0 .. 3.0 , 0.1 , { mode.value == ElytraFlightMode .FIREWORKS && fireworksVControl && page == Page .MODE_SETTINGS })
119+ private const val minFireworkUseDelayTicks = 20
120+
121+ enum class FireworkUseMode {
122+ DELAY , SPEED
123+ }
124+
102125 /* End of Mode Settings */
103126
104127 enum class ElytraFlightMode {
105- BOOST , CONTROL , CREATIVE , PACKET , VANILLA
128+ BOOST , CONTROL , CREATIVE , PACKET , VANILLA , FIREWORKS
106129 }
107130
108131 private enum class Page {
@@ -131,11 +154,14 @@ object ElytraFlight : Module(
131154 private var firstY = 0.0
132155 private var secondY = 0.0
133156
157+ /* Fireworks mode state */
158+ private var fireworkTickTimer: TickTimer = TickTimer (TimeUnit .TICKS )
159+
134160 /* Event Listeners */
135161 init {
136162 safeListener<PacketEvent .Receive > {
137163 if (player.isSpectator || ! elytraIsEquipped || elytraDurability <= 1 || ! isFlying || mode.value == ElytraFlightMode .BOOST ) return @safeListener
138- if (it.packet is SPacketPlayerPosLook && mode.value != ElytraFlightMode .PACKET ) {
164+ if (it.packet is SPacketPlayerPosLook && mode.value != ElytraFlightMode .PACKET && mode.value != ElytraFlightMode . FIREWORKS ) {
139165 val packet = it.packet
140166 packet.playerPosLookPitch = player.rotationPitch
141167 }
@@ -166,6 +192,7 @@ object ElytraFlight : Module(
166192 ElytraFlightMode .CREATIVE -> creativeMode()
167193 ElytraFlightMode .PACKET -> packetMode(it)
168194 ElytraFlightMode .VANILLA -> vanillaMode()
195+ ElytraFlightMode .FIREWORKS -> fireworksMode()
169196 }
170197 }
171198 spoofRotation()
@@ -205,7 +232,7 @@ object ElytraFlight : Module(
205232 /* Holds player in the air if run out of durability */
206233 if (! player.onGround && elytraDurability <= 1 && outOfDurability) {
207234 holdPlayer(event)
208- } else if (outOfDurability) outOfDurability = false /* Reset if players is on ground or replace with a new elytra */
235+ } else if (outOfDurability) outOfDurability = false /* Reset if player is on the ground or replace with a new elytra */
209236
210237 /* wasInLiquid check */
211238 if (player.isInWater || player.isInLava) {
@@ -359,6 +386,7 @@ object ElytraFlight : Module(
359386 ElytraFlightMode .CREATIVE -> speedCreative
360387 ElytraFlightMode .PACKET -> speedPacket
361388 ElytraFlightMode .VANILLA -> 1f
389+ ElytraFlightMode .FIREWORKS -> 1f
362390 }
363391 }
364392
@@ -372,16 +400,29 @@ object ElytraFlight : Module(
372400 private fun SafeClientEvent.boostMode () {
373401 val yaw = player.rotationYaw.toDouble().toRadian()
374402 player.motionX - = player.movementInput.moveForward * sin(yaw) * speedBoost / 20
375- if (player.movementInput.jump) player.motionY + = upSpeedBoost / 15 else if (player.movementInput.sneak) player.motionY - = downSpeedBoost / 15
403+ if (player.movementInput.jump) {
404+ player.motionY + = upSpeedBoost / 15
405+ } else if (player.movementInput.sneak) {
406+ player.motionY - = downSpeedBoost / 15
407+ }
376408 player.motionZ + = player.movementInput.moveForward * cos(yaw) * speedBoost / 20
377409 }
378410
379411 /* Control Mode */
380412 private fun SafeClientEvent.controlMode (event : PlayerTravelEvent ) {
381413 /* States and movement input */
382414 val currentSpeed = sqrt(player.motionX * player.motionX + player.motionZ * player.motionZ)
383- val moveUp = if (! legacyLookBoost) player.movementInput.jump else player.rotationPitch < - 10.0f && ! isStandingStillH
384- val moveDown = if (InventoryMove .isEnabled && ! InventoryMove .sneak && mc.currentScreen != null || moveUp) false else player.movementInput.sneak
415+ val moveUp = if (! legacyLookBoost) {
416+ player.movementInput.jump
417+ } else {
418+ player.rotationPitch < - 10.0f && ! isStandingStillH
419+ }
420+
421+ val moveDown = if (InventoryMove .isEnabled && ! InventoryMove .sneak && mc.currentScreen != null || moveUp) {
422+ false
423+ } else {
424+ player.movementInput.sneak
425+ }
385426
386427 /* Dynamic down speed */
387428 val calcDownSpeed = if (dynamicDownSpeed) {
@@ -393,8 +434,13 @@ object ElytraFlight : Module(
393434 } else downSpeedControl.toDouble()
394435
395436 /* Hover */
396- if (hoverTarget < 0.0 || moveUp) hoverTarget = player.posY else if (moveDown) hoverTarget = player.posY - calcDownSpeed
397- hoverState = (if (hoverState) player.posY < hoverTarget else player.posY < hoverTarget - 0.1 ) && altitudeHoldControl
437+ if (hoverTarget < 0.0 || moveUp) {
438+ hoverTarget = player.posY
439+ } else if (moveDown) {
440+ hoverTarget = player.posY - calcDownSpeed
441+ }
442+ hoverState = (if (hoverState) player.posY < hoverTarget else player.posY < hoverTarget - 0.1 )
443+ && altitudeHoldControl
398444
399445 /* Set velocity */
400446 if (! isStandingStillH || moveUp) {
@@ -492,8 +538,69 @@ object ElytraFlight : Module(
492538 firstY = player.posY
493539 }
494540
541+ private fun SafeClientEvent.fireworksMode () {
542+ val isBoosted = world.getLoadedEntityList().any { it is EntityFireworkRocket && it.boostedEntity == player }
543+ val currentSpeed = sqrt(player.motionX * player.motionX + player.motionZ * player.motionZ)
544+
545+ if (isBoosted) {
546+ if (fireworksVControl) {
547+ if (player.movementInput.jump) {
548+ player.motionY = fireworksVSpeed
549+ } else if (player.movementInput.sneak) {
550+ player.motionY = - fireworksVSpeed
551+ }
552+ }
553+ fireworkTickTimer.reset()
554+ } else when (fireworkUseMode) {
555+ FireworkUseMode .DELAY -> {
556+ if (fireworkTickTimer.tick(delay, true )) useFirework()
557+ }
558+ FireworkUseMode .SPEED -> {
559+ if (currentSpeed < fireworkUseStartSpeed
560+ && fireworkTickTimer.tick(minFireworkUseDelayTicks, true )
561+ ) useFirework()
562+ }
563+ }
564+ }
565+
566+ private fun SafeClientEvent.useFirework () {
567+ if (fireworkBlockAvoid) {
568+ player.rayTrace(fireworkBlockAvoidDist, 1f )?.let {
569+ if (it.typeOfHit == RayTraceResult .Type .BLOCK ) return
570+ }
571+ }
572+ playerController.syncCurrentPlayItem()
573+
574+ val holdingFireworksMainhand = isBoostingFirework(player.serverSideItem)
575+ val holdingFireworksOffhand = isBoostingFirework(player.offhandSlot.stack)
576+
577+ if (holdingFireworksMainhand) {
578+ connection.sendPacket(CPacketPlayerTryUseItem (EnumHand .MAIN_HAND ))
579+ } else if (holdingFireworksOffhand) {
580+ connection.sendPacket(CPacketPlayerTryUseItem (EnumHand .OFF_HAND ))
581+ } else {
582+ player.hotbarSlots.firstItem<ItemFirework , HotbarSlot > { isBoostingFirework(it) }?.let {
583+ spoofHotbar(it.hotbarSlot)
584+ connection.sendPacket(CPacketPlayerTryUseItem (EnumHand .MAIN_HAND ))
585+ resetHotbar()
586+ return
587+ }
588+
589+ swapToItemOrMove<ItemFirework >(this @ElytraFlight, { isBoostingFirework(it) })
590+ fireworkTickTimer.reset(minFireworkUseDelayTicks * 40L )
591+ }
592+ }
593+
594+ private fun isBoostingFirework (it : ItemStack ): Boolean {
595+ return it.item is ItemFirework
596+ && it.getSubCompound(" Fireworks" )?.hasKey(" Flight" ) == true
597+ }
598+
495599 fun shouldSwing (): Boolean {
496- return isEnabled && isFlying && ! autoLanding && (mode.value == ElytraFlightMode .CONTROL || mode.value == ElytraFlightMode .PACKET )
600+ return isEnabled
601+ && isFlying
602+ && ! autoLanding
603+ && (mode.value == ElytraFlightMode .CONTROL || mode.value == ElytraFlightMode .PACKET )
497604 }
498605
499606 private fun SafeClientEvent.spoofRotation () {
@@ -504,8 +611,13 @@ object ElytraFlight : Module(
504611
505612 if (autoLanding) {
506613 rotation = Vec2f (rotation.x, - 20f )
507- } else if (mode.value != ElytraFlightMode .BOOST && mode.value != ElytraFlightMode .VANILLA ) {
508- if (! isStandingStill && mode.value != ElytraFlightMode .CREATIVE ) rotation = Vec2f (packetYaw, rotation.y)
614+ } else if (mode.value != ElytraFlightMode .BOOST
615+ && mode.value != ElytraFlightMode .VANILLA
616+ && mode.value != ElytraFlightMode .FIREWORKS
617+ ) {
618+ if (! isStandingStill && mode.value != ElytraFlightMode .CREATIVE ) {
619+ rotation = Vec2f (packetYaw, rotation.y)
620+ }
509621 if (spoofPitch) {
510622 if (! isStandingStill) rotation = Vec2f (rotation.x, packetPitch)
511623
0 commit comments