Add gathering, unified inventory, and real-time world
This commit is contained in:
parent
173371e6fc
commit
fa57edca83
113 changed files with 6700 additions and 1307 deletions
|
|
@ -1,31 +1,7 @@
|
|||
extends SceneTree
|
||||
|
||||
const BagItemSpriteType = preload(
|
||||
"res://ui/components/bubble_menu/bag_item_sprite.gd"
|
||||
)
|
||||
const BagStorageSlotType = preload(
|
||||
"res://ui/components/bubble_menu/bag_storage_slot.gd"
|
||||
)
|
||||
const Catalog: ItemCatalog = preload(
|
||||
"res://items/catalog/item_catalog.tres"
|
||||
)
|
||||
const OwnedItemType = preload("res://items/owned_item.gd")
|
||||
const PlayerBagType = preload("res://inventory/player_bag.gd")
|
||||
const PlayerHotbarType = preload("res://inventory/player_hotbar.gd")
|
||||
const PlayerMenuScene = preload("res://ui/player_menu.tscn")
|
||||
const PlayerMenuType = preload("res://ui/player_menu.gd")
|
||||
|
||||
const EQUIPMENT_IDS: Array[StringName] = [
|
||||
&"basic_fishing_rod",
|
||||
&"art_kit",
|
||||
&"crab_net",
|
||||
&"magnet",
|
||||
]
|
||||
const ITEM_IDS: Array[StringName] = [
|
||||
&"coffee",
|
||||
&"energy_drink",
|
||||
&"snack",
|
||||
]
|
||||
const Catalog: ItemCatalog = preload("res://items/catalog/item_catalog.tres")
|
||||
const Bluegill: FishData = preload("res://fish/species/bluegill/bluegill.tres")
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
|
|
@ -33,140 +9,119 @@ func _initialize() -> void:
|
|||
|
||||
|
||||
func _run() -> void:
|
||||
root.size = Vector2i(1280, 720)
|
||||
var bag := PlayerBagType.new()
|
||||
var state := Node.new()
|
||||
root.add_child(state)
|
||||
var bag := PlayerBag.new()
|
||||
var catches := FishInventory.new()
|
||||
var storage_capacity := PlayerCoolerCapacity.new()
|
||||
var layout := PlayerInventoryLayout.new()
|
||||
var hotbar := PlayerHotbar.new()
|
||||
for node: Node in [bag, catches, storage_capacity, layout, hotbar]:
|
||||
state.add_child(node)
|
||||
bag.setup(Catalog)
|
||||
for item_id: StringName in EQUIPMENT_IDS + ITEM_IDS:
|
||||
assert(bag.add_item(item_id))
|
||||
for index: int in EQUIPMENT_IDS.size():
|
||||
assert(bag.get_storage_slot(EQUIPMENT_IDS[index]) == index)
|
||||
for index: int in ITEM_IDS.size():
|
||||
assert(bag.get_storage_slot(ITEM_IDS[index]) == index)
|
||||
layout.setup(bag, catches, Catalog, storage_capacity)
|
||||
bag.set_inventory_layout(layout)
|
||||
catches.set_inventory_layout(layout)
|
||||
hotbar.setup(bag, Catalog, catches, layout)
|
||||
|
||||
assert(bag.move_item_to_storage_slot(&"basic_fishing_rod", 14))
|
||||
assert(bag.get_storage_slot(&"basic_fishing_rod") == 14)
|
||||
assert(bag.move_item_to_storage_slot(&"crab_net", 14))
|
||||
assert(bag.get_storage_slot(&"crab_net") == 14)
|
||||
assert(bag.get_storage_slot(&"basic_fishing_rod") == 2)
|
||||
var saved_record: Dictionary = bag.get_owned_item(
|
||||
&"crab_net"
|
||||
).to_save_dict()
|
||||
assert(int(saved_record.get("storage_slot", -1)) == 14)
|
||||
assert(bag.add_item(&"basic_fishing_rod", 1))
|
||||
assert(bag.add_item(&"coffee", 3))
|
||||
var fish_catch := _make_bluegill()
|
||||
assert(catches.add_catch(fish_catch))
|
||||
|
||||
var legacy_equipment := OwnedItemType.new()
|
||||
legacy_equipment.item_id = &"basic_fishing_rod"
|
||||
var legacy_item := OwnedItemType.new()
|
||||
legacy_item.item_id = &"coffee"
|
||||
var legacy_records: Array[OwnedItemType] = [
|
||||
legacy_equipment,
|
||||
legacy_item,
|
||||
]
|
||||
var legacy_bag := PlayerBagType.new()
|
||||
legacy_bag.setup(Catalog)
|
||||
assert(legacy_bag.replace_all_items(legacy_records))
|
||||
assert(legacy_bag.get_storage_slot(&"basic_fishing_rod") == 0)
|
||||
assert(legacy_bag.get_storage_slot(&"coffee") == 0)
|
||||
legacy_bag.free()
|
||||
|
||||
var menu := PlayerMenuScene.instantiate() as PlayerMenu
|
||||
root.add_child(menu)
|
||||
await process_frame
|
||||
menu.set("_bag", bag)
|
||||
var hotbar := PlayerHotbarType.new()
|
||||
hotbar.setup(bag, Catalog)
|
||||
menu.set("_hotbar", hotbar)
|
||||
menu.set("_item_catalog", Catalog)
|
||||
menu.set("_bag_view", PlayerMenuType.BagView.EQUIPMENT)
|
||||
menu.visible = true
|
||||
menu.call("_show_section_immediate", PlayerMenuType.Section.BAG)
|
||||
menu.call("_set_content_interactive", true)
|
||||
menu.call("_refresh_bag")
|
||||
await process_frame
|
||||
_validate_grid(menu, EQUIPMENT_IDS.size())
|
||||
|
||||
var item_nodes: Dictionary = menu.get("_bag_item_nodes")
|
||||
var crab_node := item_nodes.get(&"crab_net") as BagItemSpriteType
|
||||
assert(crab_node != null)
|
||||
menu.set(
|
||||
"_controller_ownership",
|
||||
PlayerMenuType.ControllerOwnership.ITEM_LIST,
|
||||
var inventory_grid := GeneralInventoryGrid.new()
|
||||
inventory_grid.set_slot_presentation(Vector2(78.0, 78.0), 10)
|
||||
root.add_child(inventory_grid)
|
||||
inventory_grid.setup(
|
||||
layout,
|
||||
bag,
|
||||
catches,
|
||||
hotbar,
|
||||
Catalog,
|
||||
PlayerInventoryLayout.InventoryContainer.INVENTORY,
|
||||
)
|
||||
menu.call("_apply_inventory_controller_zone_focus_modes")
|
||||
crab_node.grab_focus()
|
||||
assert(bool(menu.call("_try_begin_controller_storage_placement")))
|
||||
await process_frame
|
||||
assert(
|
||||
menu.get("_controller_ownership")
|
||||
== PlayerMenuType.ControllerOwnership.STORAGE_PLACEMENT
|
||||
)
|
||||
var slots: Array = menu.get("_bag_slot_nodes")
|
||||
var bottom_slot := slots[12] as BagStorageSlotType
|
||||
bottom_slot.grab_focus()
|
||||
var down := InputEventAction.new()
|
||||
down.action = &"ui_down"
|
||||
down.pressed = true
|
||||
assert(bool(menu.call("_handle_controller_ownership_input", down)))
|
||||
assert(
|
||||
menu.get("_controller_ownership")
|
||||
== PlayerMenuType.ControllerOwnership.HOTBAR_PLACEMENT
|
||||
)
|
||||
var up := InputEventAction.new()
|
||||
up.action = &"ui_up"
|
||||
up.pressed = true
|
||||
assert(bool(menu.call("_handle_controller_ownership_input", up)))
|
||||
assert(
|
||||
menu.get("_controller_ownership")
|
||||
== PlayerMenuType.ControllerOwnership.STORAGE_PLACEMENT
|
||||
var storage_grid := GeneralInventoryGrid.new()
|
||||
root.add_child(storage_grid)
|
||||
storage_grid.setup(
|
||||
layout,
|
||||
bag,
|
||||
catches,
|
||||
hotbar,
|
||||
Catalog,
|
||||
PlayerInventoryLayout.InventoryContainer.STORAGE,
|
||||
)
|
||||
await process_frame
|
||||
assert(root.gui_get_focus_owner() == bottom_slot)
|
||||
assert(StringName(menu.get("_controller_storage_identity")) == &"crab_net")
|
||||
var target_slot := slots[7] as BagStorageSlotType
|
||||
target_slot.grab_focus()
|
||||
menu.call("_confirm_controller_storage_placement")
|
||||
await process_frame
|
||||
assert(bag.get_storage_slot(&"crab_net") == 7)
|
||||
assert(
|
||||
menu.get("_controller_ownership")
|
||||
== PlayerMenuType.ControllerOwnership.ITEM_LIST
|
||||
|
||||
var inventory_slots: Array = inventory_grid.get("_slots")
|
||||
var storage_slots: Array = storage_grid.get("_slots")
|
||||
assert(inventory_slots.size() == 36)
|
||||
assert(inventory_grid.get_slots().size() == 9)
|
||||
assert(inventory_grid.custom_minimum_size == Vector2(782.0, 342.0))
|
||||
assert(storage_capacity.get_capacity() == 9)
|
||||
assert(storage_slots.size() == 72)
|
||||
assert(storage_grid.get_slots().size() == 9)
|
||||
assert((storage_slots[0] as Control).custom_minimum_size == Vector2(52.0, 52.0))
|
||||
assert((storage_slots[9] as GeneralInventorySlot).disabled)
|
||||
|
||||
var coffee_slot := _find_slot(inventory_slots, &"coffee")
|
||||
assert(coffee_slot != null)
|
||||
(inventory_slots[7] as GeneralInventorySlot).call(
|
||||
"_drop_data",
|
||||
Vector2.ZERO,
|
||||
{"kind": "bag_item", "item_id": "coffee"},
|
||||
)
|
||||
assert(int(layout.get_entry(
|
||||
PlayerInventoryLayout.EntryKind.ITEM, &"coffee"
|
||||
).get("slot", -1)) == 7)
|
||||
assert(coffee_slot.entry_identity.is_empty())
|
||||
|
||||
menu.call("_show_bag_view", PlayerMenuType.BagView.CONSUMABLES)
|
||||
await process_frame
|
||||
_validate_grid(menu, ITEM_IDS.size())
|
||||
menu.call("_on_bag_item_dropped", &"coffee", 12)
|
||||
await process_frame
|
||||
assert(bag.get_storage_slot(&"coffee") == 12)
|
||||
(storage_slots[0] as GeneralInventorySlot).call(
|
||||
"_drop_data",
|
||||
Vector2.ZERO,
|
||||
{"kind": "cooler_fish", "catch_id": String(fish_catch.catch_id)},
|
||||
)
|
||||
assert(layout.get_container(
|
||||
PlayerInventoryLayout.EntryKind.CATCH, fish_catch.catch_id
|
||||
) == PlayerInventoryLayout.InventoryContainer.STORAGE)
|
||||
|
||||
assert(hotbar.assign_item(0, &"basic_fishing_rod"))
|
||||
assert(not layout.is_item_in_inventory(&"basic_fishing_rod"))
|
||||
(inventory_slots[8] as GeneralInventorySlot).call(
|
||||
"_drop_data",
|
||||
Vector2.ZERO,
|
||||
{"kind": "hotbar_slot", "slot_index": 0},
|
||||
)
|
||||
assert(hotbar.get_item_id(0).is_empty())
|
||||
assert(layout.is_item_in_inventory(&"basic_fishing_rod"))
|
||||
assert(int(layout.get_entry(
|
||||
PlayerInventoryLayout.EntryKind.ITEM, &"basic_fishing_rod"
|
||||
).get("slot", -1)) == 8)
|
||||
|
||||
menu.queue_free()
|
||||
hotbar.free()
|
||||
bag.free()
|
||||
await process_frame
|
||||
print("Inventory storage validation: PASS")
|
||||
state.free()
|
||||
inventory_grid.free()
|
||||
storage_grid.free()
|
||||
quit()
|
||||
|
||||
|
||||
func _validate_grid(menu: PlayerMenu, expected_items: int) -> void:
|
||||
var slots: Array = menu.get("_bag_slot_nodes")
|
||||
assert(slots.size() == PlayerBagType.MIN_STORAGE_SLOT_COUNT)
|
||||
var seen_positions: Dictionary[Vector2, bool] = {}
|
||||
for index: int in slots.size():
|
||||
var slot := slots[index] as BagStorageSlotType
|
||||
assert(slot != null)
|
||||
assert(slot.storage_slot_index == index)
|
||||
assert(not seen_positions.has(slot.position))
|
||||
seen_positions[slot.position] = true
|
||||
var normal := slot.get_theme_stylebox("normal") as StyleBoxFlat
|
||||
assert(normal != null)
|
||||
assert(normal.bg_color.a >= 0.7)
|
||||
assert((slots[1] as Control).position.x > (slots[0] as Control).position.x)
|
||||
assert((slots[5] as Control).position.y > (slots[0] as Control).position.y)
|
||||
var item_nodes := menu.get("_bag_item_nodes") as Dictionary
|
||||
assert(
|
||||
item_nodes.size() == expected_items,
|
||||
"expected %d visible bag items, found %d: %s" % [
|
||||
expected_items,
|
||||
item_nodes.size(),
|
||||
str(item_nodes.keys()),
|
||||
],
|
||||
func _make_bluegill() -> FishCatch:
|
||||
var fish_catch := FishCatch.new()
|
||||
fish_catch.fish = Bluegill
|
||||
fish_catch.fish_id = Bluegill.id
|
||||
fish_catch.catch_id = &"bluegill:inventory_storage_test"
|
||||
fish_catch.weight_lb = Bluegill.get_minimum_weight()
|
||||
fish_catch.display_scale = Bluegill.get_display_scale_for_weight(
|
||||
fish_catch.weight_lb
|
||||
)
|
||||
fish_catch.sale_value = Bluegill.get_sale_value_for_weight(
|
||||
fish_catch.weight_lb
|
||||
)
|
||||
return fish_catch
|
||||
|
||||
|
||||
func _find_slot(slots: Array, identity: StringName) -> GeneralInventorySlot:
|
||||
for candidate: Variant in slots:
|
||||
var slot := candidate as GeneralInventorySlot
|
||||
if slot != null and slot.entry_identity == identity:
|
||||
return slot
|
||||
return null
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue