Skip to content

Commit 7d8e384

Browse files
committed
Refactor inventory system configuration to enhance material handling.
Implemented prioritized material and space comparators in inventory. Replaced `name` property with `description` for detailed container info. Simplified transfer and debug logic for better readability and usability.
1 parent 9e0ba5a commit 7d8e384

23 files changed

+254
-96
lines changed

common/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ import com.lambda.brigadier.executeWithResult
2424
import com.lambda.brigadier.required
2525
import com.lambda.command.LambdaCommand
2626
import com.lambda.interaction.material.ContainerManager
27-
import com.lambda.interaction.material.ContainerManager.containerMatchSelection
27+
import com.lambda.interaction.material.ContainerManager.containerWithMaterial
28+
import com.lambda.interaction.material.ContainerManager.containerWithSpace
2829
import com.lambda.interaction.material.StackSelection.Companion.selectStack
2930
import com.lambda.interaction.material.transfer.TransferResult
3031
import com.lambda.task.TaskFlow.run
@@ -40,17 +41,15 @@ object TransferCommand : LambdaCommand(
4041

4142
override fun CommandBuilder.create() {
4243
required(itemStack("stack", registry)) { stack ->
43-
required(integer("amount")) { amount ->
44+
required(integer("amount", 1)) { amount ->
4445
required(string("from")) { from ->
4546
suggests { ctx, builder ->
4647
val count = amount(ctx).value()
4748
val selection = selectStack(count) {
4849
isItem(stack(ctx).value().item)
4950
}
50-
containerMatchSelection(selection).forEach {
51-
val available = it.available(selection)
52-
val availableMsg = if (available == Int.MAX_VALUE) "" else available.toString()
53-
builder.suggest("\"${it.name} with $availableMsg\"")
51+
containerWithMaterial(selection).forEachIndexed { i, container ->
52+
builder.suggest("\"${i + 1}. ${container.name}\"", container.description(selection))
5453
}
5554
builder.buildFuture()
5655
}
@@ -59,10 +58,8 @@ object TransferCommand : LambdaCommand(
5958
val selection = selectStack(amount(ctx).value()) {
6059
isItem(stack(ctx).value().item)
6160
}
62-
ContainerManager.container().forEach {
63-
val space = it.spaceLeft(selection)
64-
val spaceMsg = if (space == Int.MAX_VALUE) "" else space.toString()
65-
if (space > 0) builder.suggest("\"${it.name} with $spaceMsg space left\"")
61+
containerWithSpace(selection).forEachIndexed { i, container ->
62+
builder.suggest("\"${i + 1}. ${container.name}\"", container.description(selection))
6663
}
6764
builder.buildFuture()
6865
}
@@ -71,19 +68,19 @@ object TransferCommand : LambdaCommand(
7168
isItem(stack().value().item)
7269
}
7370
val fromContainer = ContainerManager.container().find {
74-
it.name == from().value().split(" with ").firstOrNull()
71+
it.name == from().value().split(".").last().trim()
7572
} ?: return@executeWithResult failure("From container not found")
7673

7774
val toContainer = ContainerManager.container().find {
78-
it.name == to().value().split(" with ").firstOrNull()
75+
it.name == to().value().split(".").last().trim()
7976
} ?: return@executeWithResult failure("To container not found")
8077

8178
when (val transaction = fromContainer.transfer(selection, toContainer)) {
8279
is TransferResult.Transfer -> {
83-
info("$transaction started.")
80+
info("${transaction.name} started.")
8481
lastTransfer = transaction
8582
transaction.finally {
86-
info("$lastTransfer completed.")
83+
info("${transaction.name} completed.")
8784
}.run()
8885
return@executeWithResult success()
8986
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 2024 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.config.groups
19+
20+
import com.lambda.interaction.material.MaterialContainer
21+
import com.lambda.interaction.material.StackSelection
22+
23+
interface InventoryConfig {
24+
val providerPriority: Priority
25+
val storePriority: Priority
26+
27+
enum class Priority {
28+
WITH_MIN_ITEMS,
29+
WITH_MAX_ITEMS;
30+
31+
fun materialComparator(selection: StackSelection) =
32+
when (this) {
33+
WITH_MAX_ITEMS -> compareBy<MaterialContainer> { it.rank }
34+
.thenByDescending { it.materialAvailable(selection) }
35+
.thenBy { it.name }
36+
WITH_MIN_ITEMS -> compareBy<MaterialContainer> { it.rank }
37+
.thenBy { it.materialAvailable(selection) }
38+
.thenBy { it.name }
39+
}
40+
41+
fun spaceComparator(selection: StackSelection) =
42+
when (this) {
43+
WITH_MAX_ITEMS -> compareBy<MaterialContainer> { it.rank }
44+
.thenByDescending { it.spaceAvailable(selection) }
45+
.thenBy { it.name }
46+
WITH_MIN_ITEMS -> compareBy<MaterialContainer> { it.rank }
47+
.thenBy { it.spaceAvailable(selection) }
48+
.thenBy { it.name }
49+
}
50+
}
51+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2024 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.config.groups
19+
20+
import com.lambda.config.Configurable
21+
22+
class InventorySettings(
23+
c: Configurable,
24+
vis: () -> Boolean = { true },
25+
) : InventoryConfig {
26+
override val providerPriority by c.setting("Provider Priority", InventoryConfig.Priority.WITH_MIN_ITEMS, "What container to prefer when retrieving the item from", vis)
27+
override val storePriority by c.setting("Store Priority", InventoryConfig.Priority.WITH_MIN_ITEMS, "What container to prefer when storing the item to", vis)
28+
}

common/src/main/kotlin/com/lambda/interaction/material/ContainerManager.kt

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import net.minecraft.block.entity.BlockEntity
3535
import net.minecraft.block.entity.ChestBlockEntity
3636
import net.minecraft.block.entity.EnderChestBlockEntity
3737
import net.minecraft.item.Item
38-
import net.minecraft.item.ItemStack
3938
import net.minecraft.screen.GenericContainerScreenHandler
4039
import net.minecraft.screen.ScreenHandlerType
4140

@@ -85,39 +84,38 @@ object ContainerManager : Loadable {
8584
}
8685
}
8786

88-
fun container() = container.flatMap {
89-
setOf(it) + it.shulkerContainer
90-
}.sorted()
87+
fun container() = container.flatMap { setOf(it) + it.shulkerContainer }.sorted()
9188

9289
fun StackSelection.transfer(destination: MaterialContainer) =
93-
findContainerWithSelection(this)?.transfer(this, destination)
90+
findContainerWithMaterial(this)?.transfer(this, destination)
9491

9592
fun findContainer(
9693
block: (MaterialContainer) -> Boolean
9794
): MaterialContainer? = container().find(block)
9895

99-
fun findContainerWithSelection(
96+
fun findContainerWithMaterial(
10097
selection: StackSelection
10198
): MaterialContainer? =
102-
container().find { it.available(selection) >= selection.count }
99+
containerWithMaterial(selection).firstOrNull()
103100

104-
fun containerMatchSelection(
101+
fun findContainerWithSpace(
105102
selection: StackSelection
106-
): Set<MaterialContainer> =
107-
container().filter { it.available(selection) >= selection.count }.toSet()
108-
109-
fun findContainerWithSelection(
110-
selectionBuilder: StackSelection.() -> Unit
111-
): MaterialContainer? {
112-
val selection = StackSelection().apply(selectionBuilder)
113-
return container().find { it.available(selection) >= selection.count }
114-
}
115-
116-
fun findContainerWithStacks(
117-
count: Int = StackSelection.DEFAULT_AMOUNT,
118-
selection: (ItemStack) -> Boolean,
119103
): MaterialContainer? =
120-
findContainerWithSelection(selection.select())
104+
containerWithSpace(selection).firstOrNull()
105+
106+
fun containerWithMaterial(
107+
selection: StackSelection
108+
): List<MaterialContainer> =
109+
container()
110+
.sortedWith(TaskFlowModule.inventory.providerPriority.materialComparator(selection))
111+
.filter { it.materialAvailable(selection) >= selection.count }
112+
113+
fun containerWithSpace(
114+
selection: StackSelection
115+
): List<MaterialContainer> =
116+
container()
117+
.sortedWith(TaskFlowModule.inventory.providerPriority.spaceComparator(selection))
118+
.filter { it.spaceAvailable(selection) >= selection.count }
121119

122120
fun findBestAvailableTool(
123121
blockState: BlockState,
@@ -127,13 +125,13 @@ object ContainerManager : Loadable {
127125
}.filter { (item, speed) ->
128126
speed > 1.0
129127
&& item.isSuitableFor(blockState)
130-
&& findContainerWithSelection(item.select()) != null
128+
&& containerWithMaterial(item.select()).isNotEmpty()
131129
}.maxByOrNull {
132130
it.second
133131
}?.first
134132

135133
fun findDisposable() = container().find { container ->
136-
TaskFlowModule.disposables.any { container.available(it.item.select()) >= 0 }
134+
TaskFlowModule.disposables.any { container.materialAvailable(it.item.select()) >= 0 }
137135
}
138136

139137
class NoContainerFound(selection: StackSelection) : Exception("No container found matching $selection")

common/src/main/kotlin/com/lambda/interaction/material/MaterialContainer.kt

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,41 @@ import com.lambda.util.item.ItemStackUtils.empty
2828
import com.lambda.util.item.ItemStackUtils.shulkerBoxContents
2929
import com.lambda.util.item.ItemStackUtils.spaceLeft
3030
import com.lambda.util.item.ItemUtils
31+
import com.lambda.util.text.*
3132
import net.minecraft.item.ItemStack
33+
import net.minecraft.text.Text
3234

3335
// ToDo: Make jsonable to persistently store them
3436
abstract class MaterialContainer(
35-
private val rank: Rank
37+
val rank: Rank
3638
) : Nameable, Comparable<MaterialContainer> {
3739
abstract var stacks: List<ItemStack>
40+
abstract val description: Text
41+
42+
@TextDsl
43+
fun TextBuilder.stock(selection: StackSelection) {
44+
literal("\n")
45+
literal("Contains ")
46+
val available = materialAvailable(selection)
47+
highlighted(if (available == Int.MAX_VALUE) "" else available.toString())
48+
literal(" of ")
49+
highlighted("${selection.optimalStack?.name?.string}")
50+
literal("\n")
51+
literal("Could store ")
52+
val left = spaceAvailable(selection)
53+
highlighted(if (left == Int.MAX_VALUE) "" else left.toString())
54+
literal(" of ")
55+
highlighted("${selection.optimalStack?.name?.string}")
56+
}
57+
58+
fun description(selection: StackSelection) =
59+
buildText {
60+
text(description)
61+
stock(selection)
62+
}
63+
64+
override val name: String
65+
get() = buildText { text(description) }.string
3866

3967
val shulkerContainer
4068
get() =
@@ -53,7 +81,7 @@ abstract class MaterialContainer(
5381
}
5482

5583
class Nothing : Task<Unit>() {
56-
override val name = "Nothing"
84+
override val name = this::class.simpleName ?: "Nothing"
5785
override fun SafeContext.onStart() {
5886
success()
5987
}
@@ -77,23 +105,23 @@ abstract class MaterialContainer(
77105
open fun matchingStacks(selection: (ItemStack) -> Boolean) =
78106
matchingStacks(selection.select())
79107

80-
open fun available(selection: StackSelection) =
108+
open fun materialAvailable(selection: StackSelection) =
81109
matchingStacks(selection).count
82110

83-
open fun spaceLeft(selection: StackSelection) =
111+
open fun spaceAvailable(selection: StackSelection) =
84112
matchingStacks(selection).spaceLeft + stacks.empty * selection.stackSize
85113

86114
fun transfer(selection: StackSelection, destination: MaterialContainer): TransferResult {
87-
val amount = available(selection)
115+
val amount = materialAvailable(selection)
88116
if (amount < selection.count) {
89117
return TransferResult.MissingItems(selection.count - amount)
90118
}
91119

92-
// val space = destination.spaceLeft(selection)
93-
// if (space == 0) {
94-
// return TransferResult.NoSpace
95-
// }
96-
//
120+
val space = destination.spaceAvailable(selection)
121+
if (space == 0) {
122+
return TransferResult.NoSpace
123+
}
124+
97125
// val transferAmount = minOf(amount, space)
98126
// selection.selector = { true }
99127
// selection.count = transferAmount

common/src/main/kotlin/com/lambda/interaction/material/container/ChestContainer.kt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ import com.lambda.task.tasks.InventoryTask.Companion.deposit
2323
import com.lambda.task.tasks.InventoryTask.Companion.withdraw
2424
import com.lambda.task.tasks.OpenContainer
2525
import com.lambda.util.Communication.info
26+
import com.lambda.util.text.TextBuilder
27+
import com.lambda.util.text.buildText
28+
import com.lambda.util.text.highlighted
29+
import com.lambda.util.text.literal
2630
import net.minecraft.item.ItemStack
2731
import net.minecraft.screen.ScreenHandler
2832
import net.minecraft.util.math.BlockPos
@@ -32,7 +36,16 @@ data class ChestContainer(
3236
val blockPos: BlockPos,
3337
val containedInStash: StashContainer? = null,
3438
) : MaterialContainer(Rank.CHEST) {
35-
override val name = "Chest at ${blockPos.toShortString()}"
39+
override val description =
40+
buildText {
41+
literal("Chest at ")
42+
highlighted(blockPos.toShortString())
43+
containedInStash?.let { stash ->
44+
literal(" (contained in ")
45+
highlighted(stash.name)
46+
literal(")")
47+
}
48+
}
3649

3750
// override fun prepare() =
3851
// moveIntoEntityRange(blockPos).onSuccess { _, _ ->

common/src/main/kotlin/com/lambda/interaction/material/container/CreativeContainer.kt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,30 @@
1818
package com.lambda.interaction.material.container
1919

2020
import com.lambda.Lambda.mc
21+
import com.lambda.brigadier.argument.literal
2122
import com.lambda.context.SafeContext
2223
import com.lambda.interaction.material.MaterialContainer
2324
import com.lambda.interaction.material.StackSelection
2425
import com.lambda.task.Task
2526
import com.lambda.util.item.ItemStackUtils.equal
27+
import com.lambda.util.text.buildText
28+
import com.lambda.util.text.highlighted
29+
import com.lambda.util.text.literal
2630
import net.minecraft.item.ItemStack
2731

2832
data object CreativeContainer : MaterialContainer(Rank.CREATIVE) {
2933
override var stacks = emptyList<ItemStack>()
30-
override val name = "Creative"
3134

32-
override fun available(selection: StackSelection): Int =
35+
override val description =
36+
buildText {
37+
literal("Creative")
38+
}
39+
40+
override fun materialAvailable(selection: StackSelection): Int =
3341
if (mc.player?.isCreative == true && selection.optimalStack != null) Int.MAX_VALUE else 0
3442

35-
override fun spaceLeft(selection: StackSelection) = Int.MAX_VALUE
43+
override fun spaceAvailable(selection: StackSelection): Int =
44+
if (mc.player?.isCreative == true && selection.optimalStack != null) Int.MAX_VALUE else 0
3645

3746
class CreativeDeposit @Ta5kBuilder constructor(val selection: StackSelection) : Task<Unit>() {
3847
override val name: String get() = "Removing $selection from creative inventory"

0 commit comments

Comments
 (0)