Skip to content

Commit

Permalink
Combine inventory data with inventories #497
Browse files Browse the repository at this point in the history
  • Loading branch information
GregHib committed Mar 23, 2024
1 parent 0395799 commit a002b03
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class InterfaceHandler(
return null
}
val inventory = componentDefinition["inventory", ""]
if (!player.inventories.containsKey(inventory)) {
if (!player.inventories.contains(inventory)) {
logger.info { "Player doesn't have interface inventory [$player, interface=$id, inventory=$inventory]" }
return null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class PlayerAccounts(
player.inventories.validItemRule = validItems
player.inventories.normalStack = DependentOnItem(itemDefinitions)
player.inventories.events = player
player.inventories.start()
player.previousTile = player.tile.add(Direction.WEST.delta)
player.experience.events = player
player.levels.link(player, PlayerLevels(player.experience))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ data class PlayerSave(
levels = Levels(levels),
body = BodyParts(male, looks, colours),
variables = variables.toMutableMap(),
inventories = Inventories(inventories.toMutableMap()),
inventories = Inventories(inventories),
friends = friends.toMutableMap(),
ignores = ignores.toMutableList(),
)
Expand Down Expand Up @@ -93,7 +93,7 @@ internal fun Player.copy() = PlayerSave(
looks = body.looks.copyOf(),
colours = body.colours.copyOf(),
variables = variables.data.toMap(),
inventories = inventories.inventories.mapValues { (inventories.instances[it.key]?.items ?: it.value).map { itm -> itm.copy() }.toTypedArray() },
inventories = inventories.instances.mapValues { it.value.items.map { itm -> itm.copy() }.toTypedArray() },
friends = friends,
ignores = ignores.toList()
)
69 changes: 42 additions & 27 deletions engine/src/main/kotlin/world/gregs/voidps/engine/inv/Inventories.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ import world.gregs.voidps.engine.inv.stack.DependentOnItem
import world.gregs.voidps.engine.inv.stack.NeverStack

class Inventories(
val inventories: MutableMap<String, Array<Item>> = mutableMapOf()
) : MutableMap<String, Array<Item>> by inventories {
private val inventories: Map<String, Array<Item>> = mutableMapOf(),
) {

fun contains(key: String): Boolean = instances.containsKey(key)

val instances: MutableMap<String, Inventory> = mutableMapOf()

Expand All @@ -28,6 +30,13 @@ class Inventories(
lateinit var events: EventDispatcher
lateinit var normalStack: DependentOnItem

fun start() {
for ((id, value) in inventories) {
instances[id] = create(id, value, definitions.get(id.removePrefix("_")))
}
(inventories as MutableMap<*, *>).clear()
}

fun inventory(definition: InventoryDefinition, secondary: Boolean = false): Inventory {
return inventory(definition.stringId, definition, secondary)
}
Expand All @@ -38,40 +47,46 @@ class Inventories(
}

fun inventory(id: String, def: InventoryDefinition, secondary: Boolean = false): Inventory {
val shop = def["shop", false]
val inventoryId = if (secondary) "_$id" else id
return instances.getOrPut(inventoryId) {
val removalCheck = if (shop) ShopItemRemovalChecker else DefaultItemRemovalChecker
val data = inventories.getOrPut(inventoryId) {
val ids = def.ids
val amounts = def.amounts
if (ids != null && amounts != null) {
Array(def.length) { Item(itemDefinitions.get(ids[it]).stringId, amounts[it]) }
} else {
Array(def.length) { Item("", removalCheck.getMinimum(it)) }
}
}
val stackRule = if (shop) AlwaysStack else when (def["stack", "normal"].lowercase()) {
"always" -> AlwaysStack
"never" -> NeverStack
else -> normalStack
}
Inventory(
data = data,
id = inventoryId,
itemRule = if (shop) ShopRestrictions(data) else validItemRule,
stackRule = stackRule,
removalCheck = removalCheck,
).apply {
transaction.changes.bind(events)
val ids = def.ids
val amounts = def.amounts
val data = if (ids != null && amounts != null) {
Array(def.length) { Item(itemDefinitions.get(ids[it]).stringId, amounts[it]) }
} else {
val removalCheck = if (def["shop", false]) ShopItemRemovalChecker else DefaultItemRemovalChecker
Array(def.length) { Item("", removalCheck.getMinimum(it)) }
}
create(inventoryId, data, def)
}
}

private fun create(
inventoryId: String,
data: Array<Item>,
def: InventoryDefinition
): Inventory {
val shop = def["shop", false]
val removalCheck = if (shop) ShopItemRemovalChecker else DefaultItemRemovalChecker
val stackRule = if (shop) AlwaysStack else when (def["stack", "normal"].lowercase()) {
"always" -> AlwaysStack
"never" -> NeverStack
else -> normalStack
}
return Inventory(
data = data,
id = inventoryId,
itemRule = if (shop) ShopRestrictions(data) else validItemRule,
stackRule = stackRule,
removalCheck = removalCheck,
).apply {
transaction.changes.bind(events)
}
}

fun clear(id: String, secondary: Boolean = false) {
val inventoryId = if (secondary) "_$id" else id
instances.remove(inventoryId)
inventories.remove(inventoryId)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ timerStart("shop_restock") {
}

timerTick("shop_restock") { player ->
for (name in player.inventories.keys) {
val inventory = player.inventories.inventory(name)
for ((name, inventory) in player.inventories.instances) {
val def = inventoryDefinitions.get(name)
if (!def["shop", false]) {
continue
Expand All @@ -42,16 +41,20 @@ timerTick("shop_restock") { player ->

// Remove restocked shops to save space
playerDespawn { player ->
val removal = mutableListOf<String>()
for ((name, inventory) in player.inventories.instances) {
val def = inventoryDefinitions.get(name)
if (!def["shop", false]) {
continue
}
val amounts = def.amounts ?: continue
if (inventory.items.withIndex().all { (index, item) -> item.amount == amounts.getOrNull(index) }) {
player.inventories.remove(name)
removal.add(name)
}
}
for (name in removal) {
player.inventories.instances.remove(name)
}
}

worldSpawn {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ fun openShopInventory(player: Player, id: String): Inventory {
return if (id.endsWith("general_store")) {
GeneralStores.bind(player, id)
} else {
val new = !player.inventories.containsKey(id)
val new = !player.inventories.contains(id)
val inventory = player.inventories.inventory(id)
if (new) {
fillShop(inventory, id)
Expand Down

0 comments on commit a002b03

Please sign in to comment.