Skip to content

Commit 8bba416

Browse files
committed
Item flow management
1 parent 55a6b8d commit 8bba416

File tree

21 files changed

+1043
-1
lines changed

21 files changed

+1043
-1
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package com.lambda.interaction.building.manager
2+
3+
import com.lambda.context.SafeContext
4+
import com.lambda.interaction.building.material.SourceSelection
5+
import com.lambda.interaction.building.material.SourceSelection.Companion.selectSource
6+
import com.lambda.interaction.building.material.source.MaterialSource
7+
import com.lambda.interaction.building.material.source.Source
8+
import com.lambda.module.modules.client.TaskFlow.disposables
9+
import com.lambda.interaction.building.material.StackSelection
10+
import com.lambda.interaction.building.material.StackSelection.Companion.select
11+
import com.lambda.util.ItemUtils
12+
import com.lambda.util.player.SlotUtils.combined
13+
import net.minecraft.block.BlockState
14+
import net.minecraft.inventory.Inventories
15+
import net.minecraft.item.BlockItem
16+
import net.minecraft.item.Item
17+
import net.minecraft.item.ItemStack
18+
import net.minecraft.nbt.NbtElement
19+
import net.minecraft.util.collection.DefaultedList
20+
21+
/**
22+
* Caches all the item sources and destinations and gives a simple interface to check if an item is available and where.
23+
* Sources are:
24+
* 1. Player inventory
25+
* 2. Shulker boxes
26+
* 3. Ender chest
27+
* 4. Stash
28+
*/
29+
object MaterialSourceManager {
30+
31+
val cache: MutableSet<MaterialSource> = mutableSetOf()
32+
33+
val SafeContext.enderChestContent: List<ItemStack>
34+
get() = emptyList()
35+
36+
val SafeContext.stashContent: List<ItemStack>
37+
get() = emptyList()
38+
39+
val SafeContext.playerSources: Set<MaterialSource>
40+
get() {
41+
if (player.isCreative) {
42+
return Source.CREATIVE.gather(player)
43+
}
44+
45+
return Source.INVENTORY.gather(player)
46+
}
47+
48+
val SafeContext.enderChestSources: Set<MaterialSource>
49+
get() = Source.ENDER_CHEST.gather(player)
50+
51+
val SafeContext.stashSources: Set<MaterialSource>
52+
get() = Source.STASH.gather(player)
53+
54+
val SafeContext.sources: Set<MaterialSource>
55+
get() = playerSources + enderChestSources + stashSources
56+
57+
fun SafeContext.getAvailableCount(stackSelection: StackSelection): Int {
58+
return sources.sumOf { it.available(stackSelection) }
59+
}
60+
61+
fun SafeContext.getSourcesWith(stackSelection: StackSelection): List<MaterialSource> {
62+
return sources.filter { it.available(stackSelection) >= stackSelection.count }
63+
}
64+
65+
fun SafeContext.getAvailableStacks(selection: SourceSelection): List<ItemStack> {
66+
return sources.filter(selection.selection).flatMap { it.stacks }
67+
}
68+
69+
fun SafeContext.getGroupedAvailableStacks(): Map<MaterialSource, List<ItemStack>> {
70+
return sources.associateWith { it.stacks }
71+
}
72+
73+
fun getShulkerBoxContents(itemStack: ItemStack) =
74+
BlockItem.getBlockEntityNbt(itemStack)?.takeIf {
75+
it.contains("Items", NbtElement.LIST_TYPE.toInt())
76+
}?.let {
77+
val list = DefaultedList.ofSize(27, ItemStack.EMPTY)
78+
Inventories.readNbt(it, list)
79+
list
80+
} ?: emptyList()
81+
82+
fun SafeContext.getBestAvailableTool(
83+
blockState: BlockState,
84+
availableTools: Set<Item> = ItemUtils.tools,
85+
) =
86+
availableTools.map {
87+
it to it.getMiningSpeedMultiplier(it.defaultStack, blockState)
88+
}.filter { (item, speed) ->
89+
speed > 1.0 &&
90+
item.isSuitableFor(blockState) &&
91+
selectSource {
92+
hasItem(item)
93+
}?.let {
94+
it.available(item.select()) > 0
95+
} == true
96+
}.maxByOrNull {
97+
it.second
98+
}?.first
99+
100+
fun SafeContext.nextDisposable() = player.combined.firstOrNull { it.item in disposables }
101+
102+
// fun SafeContext.nextDisposable() = TaskFlow.disposables.firstOrNull {
103+
// val selection = selectStack { isItem(it) }
104+
// (selectSource { matching(selection) }?.available(selection) ?: 0) > 0
105+
// }
106+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.lambda.task.flow.building.material
2+
3+
import net.minecraft.item.ItemStack
4+
import net.minecraft.util.math.Box
5+
6+
sealed class MaterialDestination {
7+
data object MainHand : MaterialDestination()
8+
data object OffHand : MaterialDestination()
9+
data object Hotbar : MaterialDestination()
10+
data class InventorySlot(val slot: Int) : MaterialDestination()
11+
data object Inventory : MaterialDestination()
12+
data class ShulkerBox(val shulkerStack: ItemStack) : MaterialDestination()
13+
data object EnderChest : MaterialDestination()
14+
data class Stash(val pos: Box) : MaterialDestination()
15+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package com.lambda.interaction.building.material
2+
3+
import com.lambda.context.SafeContext
4+
import com.lambda.interaction.building.manager.MaterialSourceManager.playerSources
5+
import com.lambda.interaction.building.manager.MaterialSourceManager.sources
6+
import com.lambda.interaction.building.material.source.MaterialSource
7+
import com.lambda.interaction.building.material.source.Source
8+
import com.lambda.interaction.building.material.source.sources.InventorySource
9+
import com.lambda.interaction.building.material.source.sources.ShulkerBoxSource
10+
import com.lambda.interaction.building.material.StackSelection.Companion.select
11+
import net.minecraft.enchantment.Enchantment
12+
import net.minecraft.item.Item
13+
import net.minecraft.item.ItemStack
14+
15+
class SourceSelection {
16+
var selection: (MaterialSource) -> Boolean = { true }
17+
18+
fun isSource(source: Source): (MaterialSource) -> Boolean {
19+
return { it.source == source }
20+
}
21+
22+
fun hasItem(item: Item, count: Int = 1): (MaterialSource) -> Boolean {
23+
return { source ->
24+
source.available(item.select()) >= count
25+
}
26+
}
27+
28+
fun hasEnchantment(enchantment: Enchantment, count: Int = 1): (MaterialSource) -> Boolean {
29+
return { source ->
30+
val a = StackSelection().hasEnchantment(enchantment, count)
31+
source.stacks.any { a(it) }
32+
}
33+
}
34+
35+
fun hasStack(stack: ItemStack, count: Int = 1): (MaterialSource) -> Boolean {
36+
return { source ->
37+
source.available(stack.select()) >= count
38+
}
39+
}
40+
41+
fun matching(stackSelection: StackSelection, count: Int = 1): (MaterialSource) -> Boolean {
42+
return { source ->
43+
source.available(stackSelection) >= count
44+
}
45+
}
46+
47+
infix fun ((MaterialSource) -> Boolean).and(other: (MaterialSource) -> Boolean): (MaterialSource) -> Boolean {
48+
return { this(it) && other(it) }
49+
}
50+
51+
infix fun ((MaterialSource) -> Boolean).or(other: (MaterialSource) -> Boolean): (MaterialSource) -> Boolean {
52+
return { this(it) || other(it) }
53+
}
54+
55+
fun ((MaterialSource) -> Boolean).not(): (MaterialSource) -> Boolean {
56+
return { !this(it) }
57+
}
58+
59+
companion object {
60+
fun SafeContext.selectSource(block: SourceSelection.() -> (MaterialSource) -> Boolean): MaterialSource? {
61+
return sources.filter(SourceSelection().block()).minOrNull()
62+
}
63+
64+
fun SafeContext.selectSourceStacks(
65+
count: Int = StackSelection.DEFAULT_AMOUNT,
66+
selection: StackSelection.() -> (ItemStack) -> Boolean,
67+
): MaterialSource? {
68+
val stackSelection = StackSelection()
69+
stackSelection.selector = stackSelection.selection()
70+
stackSelection.count = count
71+
return selectSource { matching(stackSelection) }
72+
}
73+
74+
fun SafeContext.selectPlayerSource(block: SourceSelection.() -> (MaterialSource) -> Boolean): MaterialSource? {
75+
return playerSources.filter(SourceSelection().block()).minOrNull()
76+
}
77+
78+
fun SafeContext.selectInventorySource(block: SourceSelection.() -> (MaterialSource) -> Boolean): InventorySource? {
79+
return playerSources
80+
.filterIsInstance<InventorySource>()
81+
.filter(SourceSelection().block()).minOrNull()
82+
}
83+
84+
fun SafeContext.selectShulkerSource(block: SourceSelection.() -> (MaterialSource) -> Boolean): ShulkerBoxSource? {
85+
return sources
86+
.filterIsInstance<ShulkerBoxSource>()
87+
.filter(SourceSelection().block()).minOrNull()
88+
}
89+
}
90+
}

0 commit comments

Comments
 (0)