diff --git a/scripts/avatar/avatar_loadout.gd b/scripts/avatar/avatar_loadout.gd index 84d60b6..f4acc87 100644 --- a/scripts/avatar/avatar_loadout.gd +++ b/scripts/avatar/avatar_loadout.gd @@ -28,20 +28,20 @@ var skin_tone: Color = Color.TRANSPARENT # --------------------------------------------------------------------------- -# Inner class: SlotItem +# Inner classes # --------------------------------------------------------------------------- -## Represents a single equipped slot item in a loadout. -## Used by AvatarVisualizer to access slot data. +## Represents a single equipped item in a slot. +## Used by AvatarVisualizer to iterate over equipped items. class SlotItem: - ## The asset ID of the equipped item. - var asset_id: String = "" - ## The slot key this item belongs to. - var slot_key: String = "" + ## The slot this item belongs to. + var slot_id: String + ## The catalog asset ID of the equipped item. + var asset_id: String - func _init(p_asset_id: String = "", p_slot_key: String = "") -> void: + func _init(p_slot_id: String, p_asset_id: String) -> void: + slot_id = p_slot_id asset_id = p_asset_id - slot_key = p_slot_key # --------------------------------------------------------------------------- @@ -52,6 +52,10 @@ func _init() -> void: validation_errors = [] +# --------------------------------------------------------------------------- +# Serialization +# --------------------------------------------------------------------------- + ## Create a loadout from a JSON string. static func from_json(json_string: String) -> AvatarLoadout: var loadout := AvatarLoadout.new() @@ -119,6 +123,10 @@ func to_json() -> String: return JSON.stringify(data, " ") +# --------------------------------------------------------------------------- +# Validation +# --------------------------------------------------------------------------- + ## Validate this loadout against the slot registry. ## Returns true if valid; populates validation_errors if not. func validate() -> bool: @@ -182,6 +190,10 @@ func is_valid() -> bool: return validate() +# --------------------------------------------------------------------------- +# Accessors +# --------------------------------------------------------------------------- + ## Check if a specific slot is equipped with a non-null item. func is_equipped(slot_id: String) -> bool: if not AvatarSlotRegistry.has_slot(slot_id): @@ -254,6 +266,32 @@ func remove_accessory(asset_id: String) -> bool: return false +## Iterate over equipped items as SlotItem objects. +## Returns an array of SlotItem for each equipped slot. +func get_equipped_items() -> Array[SlotItem]: + var items: Array[SlotItem] = [] + + for slot_id in AvatarSlotRegistry.SLOT_IDS: + var value = slots.get(slot_id) + if value == null: + continue + + if typeof(value) == TYPE_STRING: + var asset_id = value as String + if not asset_id.is_empty(): + items.append(SlotItem.new(slot_id, asset_id)) + elif typeof(value) == TYPE_ARRAY: + for item_id in value: + if item_id is String and not item_id.is_empty(): + items.append(SlotItem.new(slot_id, item_id)) + + return items + + +# --------------------------------------------------------------------------- +# Hashing +# --------------------------------------------------------------------------- + ## Compute a hash of this loadout for change detection. ## Mirrors the server's loadout_hash concept. func compute_hash() -> int: