@@ -30,11 +30,13 @@ import com.lambda.interaction.material.StackSelection.Companion.selectStack
3030import com.lambda.module.Module
3131import com.lambda.module.tag.ModuleTag
3232import com.lambda.threading.runSafe
33+ import com.lambda.util.Communication.warn
3334import com.lambda.util.KeyCode
3435import com.lambda.util.Mouse
3536import com.lambda.util.player.SlotUtils.hotbarAndInventoryStacks
3637import com.lambda.util.player.SlotUtils.hotbarStacks
3738import net.minecraft.client.network.ClientPlayerEntity
39+ import net.minecraft.entity.EquipmentSlot
3840import net.minecraft.entity.effect.StatusEffects
3941import net.minecraft.item.Items
4042import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket
@@ -43,35 +45,52 @@ import net.minecraft.util.Hand
4345import net.minecraft.util.hit.HitResult
4446
4547object BetterFirework : Module(
46- name = " BetterFirework" ,
47- description = " Automatic takeoff with fireworks" ,
48- tag = ModuleTag .MOVEMENT ,
48+ name = " BetterFirework" ,
49+ description = " Automatic takeoff with fireworks" ,
50+ tag = ModuleTag .MOVEMENT ,
4951) {
50- private var activateButton by setting(" Activate Key" , Bind (0 , 0 , Mouse .Middle .ordinal), " Button to activate Firework" )
51- .onPress {
52- if (takeoffState != TakeoffState .None ) return @onPress // Prevent using multiple times
53- // If already gliding use another firework
54- if (player.canOpenElytra || player.isGliding) takeoffState = TakeoffState .StartFlying
55- else if (player.canTakeoff) takeoffState = TakeoffState .Jumping
56- }
57- private var midFlightActivationKey by setting(" Mid-Flight Activation Key" , Bind .EMPTY , " Firework use key for mid flight activation" )
58- .onPress { if (player.isGliding) takeoffState = TakeoffState .StartFlying }
59- private var middleClickCancel by setting(" Middle Click Cancel" , false , description = " Cancel pick block action on middle mouse click" ) { activateButton.key != KeyCode .Unbound .code }
60- private var fireworkInteract by setting(" Right Click Fly" , true , " Automatically start flying when right clicking fireworks" )
61- private var fireworkInteractCancel by setting(" Right Click Cancel" , false , " Cancel block interactions while holding fireworks" ) { fireworkInteract }
62-
63- private var clientSwing by setting(" Swing" , true , " Swing hand client side" )
64- private var invUse by setting(" Inventory" , true , " Use fireworks from inventory" ) { activateButton.key != KeyCode .Unbound .code }
65-
66- private var takeoffState = TakeoffState .None
67-
68- val ClientPlayerEntity .canTakeoff: Boolean
69- get() = isOnGround || canOpenElytra
70-
71- val ClientPlayerEntity .canOpenElytra: Boolean
72- get() = ! abilities.flying && ! isClimbing && ! isGliding && ! isTouchingWater && ! isOnGround && ! hasVehicle() && ! hasStatusEffect(StatusEffects .LEVITATION )
73-
74- init {
52+ private var activateButton by setting(" Activate Key" , Bind (0 , 0 , Mouse .Middle .ordinal), " Button to activate Firework" )
53+ .onPress {
54+ if (! player.isElytraEquipped) {
55+ warn(" You need to equip an elytra to use this module!" )
56+ return @onPress
57+ }
58+ if (! player.hasFireworks) {
59+ warn(" You need to have fireworks in your inventory to use this module!" )
60+ return @onPress
61+ }
62+ // Prevent using multiple times
63+ if (takeoffState != TakeoffState .None ) return @onPress
64+ // If already gliding use another firework
65+ if (player.canOpenElytra || player.isGliding) takeoffState = TakeoffState .StartFlying
66+ else if (player.canTakeoff) takeoffState = TakeoffState .Jumping
67+ }
68+ private var midFlightActivationKey by setting(" Mid-Flight Activation Key" , Bind .EMPTY , " Firework use key for mid flight activation" )
69+ .onPress { if (player.isGliding) takeoffState = TakeoffState .StartFlying }
70+ private var middleClickCancel by setting(" Middle Click Cancel" , false , description = " Cancel pick block action on middle mouse click" ) { activateButton.key != KeyCode .Unbound .code }
71+ private var fireworkInteract by setting(" Right Click Fly" , true , " Automatically start flying when right clicking fireworks" )
72+ private var fireworkInteractCancel by setting(" Right Click Cancel" , false , " Cancel block interactions while holding fireworks" ) { fireworkInteract }
73+
74+ private var clientSwing by setting(" Swing" , true , " Swing hand client side" )
75+ private var invUse by setting(" Inventory" , true , " Use fireworks from inventory" ) { activateButton.key != KeyCode .Unbound .code }
76+
77+ private var takeoffState = TakeoffState .None
78+
79+ val ClientPlayerEntity .isElytraEquipped: Boolean
80+ get() = inventory.equipment.get(EquipmentSlot .CHEST )?.item == Items .ELYTRA
81+
82+ val ClientPlayerEntity .hasFireworks: Boolean
83+ get() = selectStack { isItem(Items .FIREWORK_ROCKET ) }
84+ .filterStacks(inventory.mainStacks)
85+ .isNotEmpty() || offHandStack.item == Items .FIREWORK_ROCKET
86+
87+ val ClientPlayerEntity .canTakeoff: Boolean
88+ get() = (isOnGround || canOpenElytra) && isElytraEquipped && hasFireworks
89+
90+ val ClientPlayerEntity .canOpenElytra: Boolean
91+ get() = ! abilities.flying && ! isClimbing && ! isGliding && ! isTouchingWater && ! isOnGround && ! hasVehicle() && ! hasStatusEffect(StatusEffects .LEVITATION )
92+
93+ init {
7594 setDefaultAutomationConfig {
7695 applyEdits {
7796 hideAllGroupsExcept(hotbarConfig, inventoryConfig)
@@ -80,117 +99,117 @@ object BetterFirework : Module(
8099 }
81100 }
82101
83- listen<TickEvent .Pre > {
84- when (takeoffState) {
85- TakeoffState .None -> {}
86-
87- TakeoffState .Jumping -> {
88- player.jump()
89- takeoffState = TakeoffState .StartFlying
90- }
91-
92- TakeoffState .StartFlying -> {
93- if (player.canOpenElytra) {
94- player.startGliding()
95- connection.sendPacket(ClientCommandC2SPacket (player, ClientCommandC2SPacket .Mode .START_FALL_FLYING ))
96- }
97- startFirework(invUse)
98- takeoffState = TakeoffState .None
99- }
100- }
101- }
102- }
103-
104- /* *
105- * Returns true if the mc item interaction should be canceled
106- */
107- @JvmStatic
108- fun onInteract () =
109- runSafe {
110- when {
111- ! fireworkInteract ||
112- player.inventory.selectedStack?.item != Items .FIREWORK_ROCKET ||
113- player.isGliding || // No need to do special magic if we are already holding fireworks and flying
114- (mc.crosshairTarget != null && mc.crosshairTarget!! .type != HitResult .Type .MISS && ! fireworkInteractCancel) -> false
115- else -> {
116- mc.itemUseCooldown + = 4
117- val cancelInteract = player.canTakeoff || fireworkInteractCancel
118- if (player.canTakeoff) {
119- takeoffState = TakeoffState .Jumping
120- } else if (player.canOpenElytra) {
121- takeoffState = TakeoffState .StartFlying
122- }
123- cancelInteract
124- }
125- }
126- } ? : false
127-
128- /* *
129- * Returns true when the pick interaction should be canceled.
130- */
131- @JvmStatic
132- fun onPick () =
133- runSafe {
134- when {
135- (mc.crosshairTarget?.type == HitResult .Type .BLOCK && ! middleClickCancel) ||
136- activateButton.mouse != mc.options.pickItemKey.boundKey.code ||
137- takeoffState != TakeoffState .None -> false // Prevent using multiple times
138- else -> middleClickCancel
139- }
140- } ? : false
141-
142- fun SafeContext.sendSwing () {
143- if (clientSwing) {
144- player.swingHand(Hand .MAIN_HAND )
145- } else {
146- connection.sendPacket(HandSwingC2SPacket (Hand .MAIN_HAND ))
147- }
148- }
149-
150- /* *
151- * Use a firework from the hotbar or inventory if possible.
152- * Return true if a firework has been used
153- */
154- @JvmStatic
155- fun SafeContext.startFirework (silent : Boolean ) {
156- val stack = selectStack(count = 1 ) { isItem(Items .FIREWORK_ROCKET ) }
157-
158- stack.bestItemMatch(player.hotbarStacks)
159- ?.let {
160- val request = HotbarRequest (player.hotbarStacks.indexOf(it), this @BetterFirework, keepTicks = 0 )
161- .submit(queueIfMismatchedStage = false )
162- if (request.done) {
163- interaction.interactItem(player, Hand .MAIN_HAND )
164- sendSwing()
165- }
166- return
167- }
168-
169- if (! silent) return
170-
171- stack.bestItemMatch(player.hotbarAndInventoryStacks)
172- ?.let {
173- val swapSlotId = player.hotbarAndInventoryStacks.indexOf(it)
174- val hotbarSlotToSwapWith = player.hotbarStacks.find { slot -> slot.isEmpty }?.let { slot -> player.hotbarStacks.indexOf(slot) } ? : 8
175-
176- inventoryRequest {
177- swap(swapSlotId, hotbarSlotToSwapWith)
178- action {
179- val request = HotbarRequest (hotbarSlotToSwapWith, this @BetterFirework, keepTicks = 0 , nowOrNothing = true )
180- .submit(queueIfMismatchedStage = false )
181- if (request.done) {
182- interaction.interactItem(player, Hand .MAIN_HAND )
183- sendSwing()
184- }
185- }
186- swap(swapSlotId, hotbarSlotToSwapWith)
187- }.submit()
188- }
189- }
190-
191- enum class TakeoffState {
192- None ,
193- Jumping ,
194- StartFlying
195- }
102+ listen<TickEvent .Pre > {
103+ when (takeoffState) {
104+ TakeoffState .None -> {}
105+
106+ TakeoffState .Jumping -> {
107+ player.jump()
108+ takeoffState = TakeoffState .StartFlying
109+ }
110+
111+ TakeoffState .StartFlying -> {
112+ if (player.canOpenElytra) {
113+ player.startGliding()
114+ connection.sendPacket(ClientCommandC2SPacket (player, ClientCommandC2SPacket .Mode .START_FALL_FLYING ))
115+ }
116+ startFirework(invUse)
117+ takeoffState = TakeoffState .None
118+ }
119+ }
120+ }
121+ }
122+
123+ /* *
124+ * Returns true if the mc item interaction should be canceled
125+ */
126+ @JvmStatic
127+ fun onInteract () =
128+ runSafe {
129+ when {
130+ ! fireworkInteract ||
131+ player.inventory.selectedStack?.item != Items .FIREWORK_ROCKET ||
132+ player.isGliding || // No need to do special magic if we are already holding fireworks and flying
133+ (mc.crosshairTarget != null && mc.crosshairTarget!! .type != HitResult .Type .MISS && ! fireworkInteractCancel) -> false
134+ else -> {
135+ mc.itemUseCooldown + = 4
136+ val cancelInteract = player.canTakeoff || fireworkInteractCancel
137+ if (player.canTakeoff) {
138+ takeoffState = TakeoffState .Jumping
139+ } else if (player.canOpenElytra) {
140+ takeoffState = TakeoffState .StartFlying
141+ }
142+ cancelInteract
143+ }
144+ }
145+ } ? : false
146+
147+ /* *
148+ * Returns true when the pick interaction should be canceled.
149+ */
150+ @JvmStatic
151+ fun onPick () =
152+ runSafe {
153+ when {
154+ (mc.crosshairTarget?.type == HitResult .Type .BLOCK && ! middleClickCancel) ||
155+ activateButton.mouse != mc.options.pickItemKey.boundKey.code ||
156+ takeoffState != TakeoffState .None -> false // Prevent using multiple times
157+ else -> middleClickCancel
158+ }
159+ } ? : false
160+
161+ fun SafeContext.sendSwing () {
162+ if (clientSwing) {
163+ player.swingHand(Hand .MAIN_HAND )
164+ } else {
165+ connection.sendPacket(HandSwingC2SPacket (Hand .MAIN_HAND ))
166+ }
167+ }
168+
169+ /* *
170+ * Use a firework from the hotbar or inventory if possible.
171+ * Return true if a firework has been used
172+ */
173+ @JvmStatic
174+ fun SafeContext.startFirework (silent : Boolean ) {
175+ val stack = selectStack(count = 1 ) { isItem(Items .FIREWORK_ROCKET ) }
176+
177+ stack.bestItemMatch(player.hotbarStacks)
178+ ?.let {
179+ val request = HotbarRequest (player.hotbarStacks.indexOf(it), this @BetterFirework, keepTicks = 0 )
180+ .submit(queueIfMismatchedStage = false )
181+ if (request.done) {
182+ interaction.interactItem(player, Hand .MAIN_HAND )
183+ sendSwing()
184+ }
185+ return
186+ }
187+
188+ if (! silent) return
189+
190+ stack.bestItemMatch(player.hotbarAndInventoryStacks)
191+ ?.let {
192+ val swapSlotId = player.hotbarAndInventoryStacks.indexOf(it)
193+ val hotbarSlotToSwapWith = player.hotbarStacks.find { slot -> slot.isEmpty }?.let { slot -> player.hotbarStacks.indexOf(slot) } ? : 8
194+
195+ inventoryRequest {
196+ swap(swapSlotId, hotbarSlotToSwapWith)
197+ action {
198+ val request = HotbarRequest (hotbarSlotToSwapWith, this @BetterFirework, keepTicks = 0 , nowOrNothing = true )
199+ .submit(queueIfMismatchedStage = false )
200+ if (request.done) {
201+ interaction.interactItem(player, Hand .MAIN_HAND )
202+ sendSwing()
203+ }
204+ }
205+ swap(swapSlotId, hotbarSlotToSwapWith)
206+ }.submit()
207+ }
208+ }
209+
210+ enum class TakeoffState {
211+ None ,
212+ Jumping ,
213+ StartFlying
214+ }
196215}
0 commit comments