Add portable RV homes and decor prototype

This commit is contained in:
Alexander Sellite 2026-08-30 21:37:26 -04:00
parent 81decf2b71
commit fe099f47dd
56 changed files with 5459 additions and 112 deletions

View file

@ -60,6 +60,28 @@ func add_item(item_id: StringName, quantity: int = 1) -> bool:
return true
func add_item_to_storage(item_id: StringName, quantity: int = 1) -> bool:
var existing: OwnedItemType = get_owned_item(item_id)
if existing != null:
return add_item(item_id, quantity)
var item: ItemDataType = _resolve_available_item(item_id)
if (
item == null
or quantity <= 0
or quantity > (item.max_stack if item.stackable else 1)
or _inventory_layout == null
or not _inventory_layout.can_accept_item_in_storage(item_id)
):
return false
var owned := OwnedItemType.new()
owned.item_id = item_id
owned.quantity = quantity
owned.storage_slot = _first_available_storage_slot(item, _items)
_items.append(owned)
contents_changed.emit()
return true
func can_add_item(item_id: StringName, quantity: int = 1) -> bool:
var item: ItemDataType = _resolve_available_item(item_id)
if item == null or quantity <= 0:

View file

@ -314,6 +314,25 @@ func get_fish_slots() -> Array[StringName]:
return _fish_slots.duplicate()
func find_item_slot(item_id: StringName) -> int:
return _slots.find(item_id)
func find_first_empty_slot() -> int:
for slot_index: int in SLOT_COUNT:
if get_assignment_kind(slot_index) != AssignmentKind.EMPTY:
continue
if (
_inventory_layout == null
or _inventory_layout.get_key_at(
PlayerInventoryLayout.InventoryContainer.HOTBAR,
slot_index,
).is_empty()
):
return slot_index
return -1
func replace_state(
slots: Array[StringName],
selected_slot: int,

View file

@ -37,6 +37,7 @@ var _fish_inventory: FishInventoryType
var _item_catalog: ItemCatalogType
var _storage_capacity: PlayerCoolerCapacityType
var _placements: Dictionary[String, Dictionary] = {}
var _prepared_item_placements: Dictionary[String, Dictionary] = {}
var _reconciling: bool = false
var _backpack_level: int = 0
@ -72,7 +73,44 @@ func can_accept_item(item_id: StringName) -> bool:
if not is_managed_item(item_id):
return true
var key := item_key(item_id)
return _placements.has(key) or _first_free_slot(InventoryContainer.INVENTORY) >= 0
return (
_placements.has(key)
or _is_prepared_item_placement_available(key)
or _first_free_slot(InventoryContainer.INVENTORY) >= 0
)
func prepare_new_item_placement(
item_id: StringName,
target_container: InventoryContainer,
target_slot: int,
) -> bool:
if not is_managed_item(item_id):
return false
var key := item_key(item_id)
if (
_placements.has(key)
or not _is_slot_valid(target_container, target_slot)
or not _key_at(target_container, target_slot).is_empty()
or _prepared_slot_is_occupied(target_container, target_slot)
):
return false
_prepared_item_placements[key] = {
"container": int(target_container),
"slot": target_slot,
}
return true
func cancel_prepared_item_placement(item_id: StringName) -> void:
_prepared_item_placements.erase(item_key(item_id))
func can_accept_item_in_storage(item_id: StringName) -> bool:
if not is_managed_item(item_id):
return true
var key := item_key(item_id)
return _placements.has(key) or _first_free_slot(InventoryContainer.STORAGE) >= 0
func can_accept_catch(catch_id: StringName = StringName()) -> bool:
@ -332,6 +370,7 @@ func restore_from_save_data(data: Dictionary) -> bool:
"container": container,
"slot": slot,
}
_prepared_item_placements.clear()
_placements = restored
_reconcile(true)
return true
@ -340,6 +379,7 @@ func restore_from_save_data(data: Dictionary) -> bool:
func reset_to_defaults() -> void:
var capacity_changed := _backpack_level != 0
_backpack_level = 0
_prepared_item_placements.clear()
_placements.clear()
_reconcile(true)
if capacity_changed:
@ -402,8 +442,17 @@ func _reconcile(force_signal: bool) -> void:
for key: String in expected:
if _placements.has(key):
continue
var prepared: Dictionary = _prepared_item_placements.get(key, {})
var target_container := InventoryContainer.INVENTORY
var target_slot := _first_free_slot(target_container)
var target_slot: int = -1
if _is_prepared_item_placement_available(key):
target_container = int(
prepared["container"]
) as InventoryContainer
target_slot = int(prepared["slot"])
_prepared_item_placements.erase(key)
if target_slot < 0:
target_slot = _first_free_slot(target_container)
if target_slot < 0:
target_container = InventoryContainer.STORAGE
target_slot = _first_free_slot(target_container)
@ -484,6 +533,37 @@ func _first_free_slot(container: InventoryContainer) -> int:
return -1
func _is_prepared_item_placement_available(key: String) -> bool:
var placement: Dictionary = _prepared_item_placements.get(key, {})
if placement.is_empty():
return false
var container: int = int(placement.get("container", -1))
var slot: int = int(placement.get("slot", -1))
if (
container not in [
InventoryContainer.INVENTORY,
InventoryContainer.STORAGE,
InventoryContainer.HOTBAR,
]
or not _is_slot_valid(container as InventoryContainer, slot)
):
return false
return _key_at(container as InventoryContainer, slot).is_empty()
func _prepared_slot_is_occupied(
container: InventoryContainer,
slot: int,
) -> bool:
for placement: Dictionary in _prepared_item_placements.values():
if (
int(placement.get("container", -1)) == int(container)
and int(placement.get("slot", -1)) == slot
):
return true
return false
func _key_at(container: InventoryContainer, slot: int) -> String:
for key: String in _placements:
var placement: Dictionary = _placements[key]