Skip to content

Commit 0bbcb0e

Browse files
committed
air place request inventory manager
1 parent a9202c2 commit 0bbcb0e

File tree

6 files changed

+69
-50
lines changed

6 files changed

+69
-50
lines changed

src/main/kotlin/com/lambda/config/groups/InventorySettings.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ class InventorySettings(
3434
Access("Access")
3535
}
3636

37-
override val actionsPerSecond by c.setting("Actions Per Tick", 20, 0..100, 1, "How many inventory actions can be performed per tick", visibility = vis).group(baseGroup, Group.General)
38-
override val tickStageMask by c.setting("Inventory Stage Mask", setOf<TickEvent>(TickEvent.Pre), description = "The sub-tick timing at which inventory actions are performed", visibility = vis).group(baseGroup, Group.General)
37+
override val actionsPerSecond by c.setting("Actions Per Second", 100, 0..100, 1, "How many inventory actions can be performed per tick", visibility = vis).group(baseGroup, Group.General)
38+
override val tickStageMask by c.setting("Inventory Stage Mask", setOf<TickEvent>(TickEvent.Pre, TickEvent.Input.Pre, TickEvent.Input.Post, TickEvent.Player.Post), description = "The sub-tick timing at which inventory actions are performed", visibility = vis).group(baseGroup, Group.General)
3939
override val disposables by c.setting("Disposables", ItemUtils.defaultDisposables, ItemUtils.defaultDisposables, "Items that will be ignored when checking for a free slot", vis).group(baseGroup, Group.Container)
4040
override val swapWithDisposables by c.setting("Swap With Disposables", true, "Swap items with disposable ones", vis).group(baseGroup, Group.Container)
4141
override val providerPriority by c.setting("Provider Priority", InventoryConfig.Priority.WithMinItems, "What container to prefer when retrieving the item from", vis).group(baseGroup, Group.Container)
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.interaction.request.inventory
19+
20+
import com.lambda.context.SafeContext
21+
22+
sealed interface InventoryAction {
23+
val action: SafeContext.() -> Unit
24+
25+
class Inventory(override val action: SafeContext.() -> Unit) : InventoryAction
26+
class Other(override val action: SafeContext.() -> Unit) : InventoryAction
27+
}

src/main/kotlin/com/lambda/interaction/request/inventory/InventoryManager.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ object InventoryManager : RequestHandler<InventoryRequest>(
4848
TickEvent.Input.Post,
4949
TickEvent.Player.Post
5050
), Logger {
51-
private var actions = mutableListOf<SafeContext.() -> Unit>()
51+
private var actions = mutableListOf<InventoryAction>()
5252

5353
private var slots = listOf<ItemStack>()
5454
private var alteredSlots = LimitedDecayQueue<Pair<Int, Pair<ItemStack, ItemStack>>>(
@@ -86,7 +86,8 @@ object InventoryManager : RequestHandler<InventoryRequest>(
8686
}
8787

8888
override fun AutomatedSafeContext.handleRequest(request: InventoryRequest) {
89-
if (request.actions.size >= request.inventoryConfig.actionsPerSecond - actionsThisSecond &&
89+
val inventoryActionCount = request.actions.count { it is InventoryAction.Inventory }
90+
if (inventoryActionCount >= request.inventoryConfig.actionsPerSecond - actionsThisSecond &&
9091
!request.settleForLess &&
9192
!request.mustPerform) return
9293
if (tickStage !in inventoryConfig.tickStageMask) return
@@ -99,7 +100,7 @@ object InventoryManager : RequestHandler<InventoryRequest>(
99100
val iterator = actions.iterator()
100101
while (iterator.hasNext()) {
101102
if (actionsThisSecond + 1 > maxActionsThisSecond && !request.mustPerform) break
102-
iterator.next()()
103+
iterator.next().action(this)
103104
if (avoidDesync) indexInventoryChanges()
104105
actionsThisTick++
105106
actionsThisSecond++

src/main/kotlin/com/lambda/interaction/request/inventory/InventoryRequest.kt

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import net.minecraft.util.math.Direction
3434
private annotation class InvRequestDsl
3535

3636
class InventoryRequest private constructor(
37-
val actions: List<SafeContext.() -> Unit>,
37+
val actions: List<InventoryAction>,
3838
val settleForLess: Boolean,
3939
val mustPerform: Boolean,
4040
automated: Automated,
@@ -55,27 +55,29 @@ class InventoryRequest private constructor(
5555

5656
@InvRequestDsl
5757
class InvRequestBuilder(val settleForLess: Boolean, val mustPerform: Boolean) {
58-
val actions = mutableListOf<SafeContext.() -> Unit>()
58+
val actions = mutableListOf<InventoryAction>()
5959
var onComplete: (SafeContext.() -> Unit)? = null
6060

6161
@InvRequestDsl
6262
fun click(slotId: Int, button: Int, actionType: SlotActionType) {
63-
actions.add { clickSlot(slotId, button, actionType) }
63+
InventoryAction.Inventory { clickSlot(slotId, button, actionType) }.addToActions()
6464
}
6565

6666
@InvRequestDsl
6767
fun pickFromInventory(slotId: Int) {
68-
actions.add { clickSlot(slotId, player.inventory.selectedSlot, SlotActionType.SWAP) }
68+
InventoryAction.Inventory {
69+
clickSlot(slotId, player.inventory.selectedSlot, SlotActionType.SWAP)
70+
}.addToActions()
6971
}
7072

7173
@InvRequestDsl
7274
fun dropItemInHand(entireStack: Boolean = true) {
73-
actions.add { player.dropSelectedItem(entireStack) }
75+
InventoryAction.Inventory { player.dropSelectedItem(entireStack) }.addToActions()
7476
}
7577

7678
@InvRequestDsl
7779
fun swapHands() {
78-
actions.add {
80+
InventoryAction.Inventory {
7981
val offhandStack = player.getStackInHand(Hand.OFF_HAND)
8082
player.setStackInHand(Hand.OFF_HAND, player.getStackInHand(Hand.MAIN_HAND))
8183
player.setStackInHand(Hand.MAIN_HAND, offhandStack)
@@ -86,12 +88,12 @@ class InventoryRequest private constructor(
8688
Direction.DOWN
8789
)
8890
)
89-
}
91+
}.addToActions()
9092
}
9193

9294
@InvRequestDsl
9395
fun clickCreativeStack(stack: ItemStack, slotId: Int) {
94-
actions.add { interaction.clickCreativeStack(stack, slotId) }
96+
InventoryAction.Inventory { interaction.clickCreativeStack(stack, slotId) }.addToActions()
9597
}
9698

9799
@InvRequestDsl
@@ -150,10 +152,20 @@ class InventoryRequest private constructor(
150152
pickup(targetSlotId, 0)
151153
}
152154

155+
@InvRequestDsl
156+
fun action(action: SafeContext.() -> Unit) {
157+
InventoryAction.Other(action).addToActions()
158+
}
159+
153160
@InvRequestDsl
154161
fun onComplete(callback: SafeContext.() -> Unit) {
155162
onComplete = callback
156163
}
164+
165+
@InvRequestDsl
166+
private fun InventoryAction.addToActions() {
167+
actions.add(this)
168+
}
157169
}
158170

159171
companion object {

src/main/kotlin/com/lambda/interaction/request/placing/PlaceManager.kt

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import com.lambda.interaction.request.PositionBlocking
3535
import com.lambda.interaction.request.RequestHandler
3636
import com.lambda.interaction.request.breaking.BreakManager
3737
import com.lambda.interaction.request.interacting.InteractionManager
38+
import com.lambda.interaction.request.inventory.InventoryRequest.Companion.inventoryRequest
3839
import com.lambda.interaction.request.placing.PlaceManager.activeRequest
3940
import com.lambda.interaction.request.placing.PlaceManager.maxPlacementsThisTick
4041
import com.lambda.interaction.request.placing.PlaceManager.placeBlock
@@ -59,14 +60,12 @@ import net.minecraft.item.BlockItem
5960
import net.minecraft.item.ItemPlacementContext
6061
import net.minecraft.item.ItemStack
6162
import net.minecraft.item.ItemUsageContext
62-
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket
6363
import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket
6464
import net.minecraft.sound.SoundCategory
6565
import net.minecraft.util.ActionResult
6666
import net.minecraft.util.Hand
6767
import net.minecraft.util.hit.BlockHitResult
6868
import net.minecraft.util.math.BlockPos
69-
import net.minecraft.util.math.Direction
7069
import net.minecraft.world.GameMode
7170
import kotlin.math.min
7271

@@ -328,21 +327,25 @@ object PlaceManager : RequestHandler<PlaceRequest>(
328327
return ActionResult.FAIL
329328
}
330329

331-
val stackInHand = player.getStackInHand(hand)
332-
val stackCountPre = stackInHand.count
333-
if (placeConfig.placeConfirmationMode != PlaceConfig.PlaceConfirmationMode.None) {
334-
PlaceInfo(placeContext, request.pendingInteractions, request.onPlace, placeConfig).startPending()
335-
}
336-
337330
if (placeConfig.airPlace == PlaceConfig.AirPlaceMode.Grim) {
338331
val placeHand = if (hand == Hand.MAIN_HAND) Hand.OFF_HAND else Hand.MAIN_HAND
339-
airPlaceOffhandSwap()
340-
sendPlacePacket(placeHand, hitResult)
341-
airPlaceOffhandSwap()
332+
val inventoryRequest = inventoryRequest {
333+
swapHands()
334+
action { sendPlacePacket(placeHand, hitResult) }
335+
swapHands()
336+
}.submit(queueIfClosed = false)
337+
if (!inventoryRequest.done) return ActionResult.FAIL
342338
} else {
343339
sendPlacePacket(hand, hitResult)
344340
}
345341

342+
if (placeConfig.placeConfirmationMode != PlaceConfig.PlaceConfirmationMode.None) {
343+
PlaceInfo(placeContext, request.pendingInteractions, request.onPlace, placeConfig).startPending()
344+
}
345+
346+
val stackInHand = player.getStackInHand(hand)
347+
val stackCountPre = stackInHand.count
348+
346349
if (placeConfig.swing) {
347350
swingHand(placeConfig.swingType, hand)
348351

@@ -407,18 +410,5 @@ object PlaceManager : RequestHandler<PlaceRequest>(
407410
)
408411
}
409412

410-
/**
411-
* Must be called before and after placing a block to bypass grim's air place checks.
412-
*/
413-
private fun SafeContext.airPlaceOffhandSwap() {
414-
connection.sendPacket(
415-
PlayerActionC2SPacket(
416-
PlayerActionC2SPacket.Action.SWAP_ITEM_WITH_OFFHAND,
417-
BlockPos.ORIGIN,
418-
Direction.DOWN
419-
)
420-
)
421-
}
422-
423413
override fun preEvent(): Event = UpdateManagerEvent.Place.post()
424414
}

src/main/kotlin/com/lambda/util/player/SlotUtils.kt

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,8 @@ object SlotUtils {
2929
val ClientPlayerEntity.hotbarAndStorage: List<ItemStack> get() = inventory.mainStacks
3030
val ClientPlayerEntity.combined: List<ItemStack> get() = hotbarAndStorage + equipment
3131

32-
fun SafeContext.clickSlot(
33-
slotId: Int,
34-
button: Int,
35-
actionType: SlotActionType,
36-
) {
32+
fun SafeContext.clickSlot(slotId: Int, button: Int, actionType: SlotActionType) {
3733
val syncId = player.currentScreenHandler?.syncId ?: return
38-
39-
interaction.clickSlot(
40-
syncId,
41-
slotId,
42-
button,
43-
actionType,
44-
player,
45-
)
34+
interaction.clickSlot(syncId, slotId, button, actionType, player)
4635
}
4736
}

0 commit comments

Comments
 (0)