Randoloot/scripts/items/ship_inventory.gd

120 lines
3.8 KiB
GDScript

extends Node
class_name ShipInventory
signal inventory_changed
const CARGO_SIZE := 20
const WEAPON_SLOT_COUNT := 2
const MODULE_SLOT_COUNT := 6
var cargo: Array[ItemInstance] = []
var weapon_slots: Array[ItemInstance] = []
var module_slots: Array[ItemInstance] = []
@onready var ship: CharacterBody2D = get_parent()
func _ready() -> void:
add_to_group("ship_inventory")
cargo.resize(CARGO_SIZE)
weapon_slots.resize(WEAPON_SLOT_COUNT)
module_slots.resize(MODULE_SLOT_COUNT)
_add_starter_items()
_recalculate_ship_stats()
inventory_changed.emit()
func get_cargo_used() -> int:
var used := 0
for item in cargo:
if item != null:
used += 1
return used
func get_item(slot_kind: String, index: int) -> ItemInstance:
var slots := _get_slots(slot_kind)
if index < 0 or index >= slots.size():
return null
return slots[index]
func can_move_item(from_kind: String, from_index: int, to_kind: String, to_index: int) -> bool:
var source := _get_slots(from_kind)
var destination := _get_slots(to_kind)
if from_index < 0 or from_index >= source.size() or to_index < 0 or to_index >= destination.size():
return false
if from_kind == to_kind and from_index == to_index:
return false
var item := source[from_index]
if item == null or item.definition == null:
return false
if to_kind == "weapon" and item.definition.category != ItemDefinition.Category.WEAPON:
return false
if to_kind == "module" and item.definition.category == ItemDefinition.Category.WEAPON:
return false
var displaced := destination[to_index]
if displaced != null and displaced.definition != null:
if from_kind == "weapon" and displaced.definition.category != ItemDefinition.Category.WEAPON:
return false
if from_kind == "module" and displaced.definition.category == ItemDefinition.Category.WEAPON:
return false
return true
func move_item(from_kind: String, from_index: int, to_kind: String, to_index: int) -> bool:
if not can_move_item(from_kind, from_index, to_kind, to_index):
return false
var source := _get_slots(from_kind)
var destination := _get_slots(to_kind)
var displaced := destination[to_index]
destination[to_index] = source[from_index]
source[from_index] = displaced
_recalculate_ship_stats()
inventory_changed.emit()
return true
func _get_slots(slot_kind: String) -> Array[ItemInstance]:
match slot_kind:
"cargo":
return cargo
"weapon":
return weapon_slots
"module":
return module_slots
return []
func _recalculate_ship_stats() -> void:
var bonuses := {}
for item in weapon_slots + module_slots:
if item == null or item.definition == null:
continue
for stat_key in ["max_hull", "max_shields", "max_energy", "max_speed", "energy_regeneration", "shield_regeneration"]:
bonuses[stat_key] = float(bonuses.get(stat_key, 0.0)) + item.get_stat_total(stat_key)
ship.call("apply_equipment_bonuses", bonuses)
func _add_starter_items() -> void:
var starter_items := [
"res://resources/items/plasma_cannon.tres",
"res://resources/items/beam_laser.tres",
"res://resources/items/machine_gun.tres",
"res://resources/items/missile_launcher.tres",
"res://resources/items/reinforced_shield.tres",
"res://resources/items/hull_plating.tres",
"res://resources/items/compact_generator.tres",
"res://resources/items/engine_extension.tres",
"res://resources/items/tuned_thrusters.tres",
"res://resources/items/shield_recharger.tres",
]
var cargo_index := 0
var weapon_index := 0
for path in starter_items:
var definition := load(path) as ItemDefinition
if definition == null:
push_warning("Could not load starter item: %s" % path)
continue
var item := ItemInstance.new()
item.definition = definition
item.item_level = 1
if definition.category == ItemDefinition.Category.WEAPON and weapon_index < WEAPON_SLOT_COUNT:
weapon_slots[weapon_index] = item
weapon_index += 1
else:
cargo[cargo_index] = item
cargo_index += 1