feat: update shop
This commit is contained in:
+75
-3
@@ -521,21 +521,93 @@ func _apply_outline_recursive(node: Node):
|
||||
for child in node.get_children():
|
||||
_apply_outline_recursive(child)
|
||||
|
||||
const COSMETIC_MAPPING = {
|
||||
"head_hat1": {
|
||||
"hide": ["helm_default", "helm1", "helm2", "helm3"],
|
||||
"show": ["head_hat1"],
|
||||
"materials": {}
|
||||
},
|
||||
"head_crown": {
|
||||
"hide": ["helm_default", "helm1", "helm2", "helm3"],
|
||||
"show": ["head_crown"],
|
||||
"materials": {}
|
||||
},
|
||||
"costume_red": {
|
||||
"hide": [],
|
||||
"show": [],
|
||||
"materials": {
|
||||
"body": "res://assets/materials/body_red.tres",
|
||||
"arm": "res://assets/materials/body_red.tres"
|
||||
}
|
||||
},
|
||||
"costume_gold": {
|
||||
"hide": [],
|
||||
"show": [],
|
||||
"materials": {
|
||||
"body": "res://assets/materials/body_gold.tres",
|
||||
"arm": "res://assets/materials/body_gold.tres"
|
||||
}
|
||||
},
|
||||
"glove_leather": {
|
||||
"hide": ["hands", "glove_default"],
|
||||
"show": ["glove_leather"],
|
||||
"materials": {}
|
||||
},
|
||||
"acc_glasses": {
|
||||
"hide": [],
|
||||
"show": ["acc_glasses"],
|
||||
"materials": {}
|
||||
}
|
||||
}
|
||||
|
||||
func apply_loadout(character_node: Node3D) -> void:
|
||||
"""Apply equipped cosmetics from UserProfileManager.loadout onto the active character model.
|
||||
Items are expected as child nodes named matching the item ID (e.g. 'head_hat1', 'acc_glasses').
|
||||
All nodes in the cosmetic category groups are hidden first, then the equipped one is shown."""
|
||||
It uses COSMETIC_MAPPING to dynamically swap visibility and materials of internal meshes."""
|
||||
if not has_node("/root/UserProfileManager"):
|
||||
return
|
||||
|
||||
var loadout: Dictionary = UserProfileManager.loadout
|
||||
var all_meshes = _get_all_mesh_instances(character_node)
|
||||
|
||||
for category in ["head", "costume", "glove", "accessory"]:
|
||||
var equipped: String = loadout.get(category, "")
|
||||
|
||||
# Fallback basic logic for direct children
|
||||
for child in character_node.get_children():
|
||||
# Only manage nodes that start with the category prefix
|
||||
if child.name.begins_with(category):
|
||||
child.visible = (child.name == equipped)
|
||||
|
||||
# Advanced mapping logic for deep node part swapping and materials
|
||||
if equipped and COSMETIC_MAPPING.has(equipped):
|
||||
var mapping = COSMETIC_MAPPING[equipped]
|
||||
|
||||
# Visibility overrides
|
||||
var to_hide = mapping.get("hide", [])
|
||||
var to_show = mapping.get("show", [])
|
||||
|
||||
for mesh in all_meshes:
|
||||
if mesh.name in to_hide:
|
||||
mesh.visible = false
|
||||
if mesh.name in to_show:
|
||||
mesh.visible = true
|
||||
|
||||
# Material overrides
|
||||
var mats = mapping.get("materials", {})
|
||||
for mesh_name in mats:
|
||||
var mat_path = mats[mesh_name]
|
||||
for mesh in all_meshes:
|
||||
if mesh.name == mesh_name:
|
||||
if ResourceLoader.exists(mat_path):
|
||||
var new_mat = load(mat_path)
|
||||
mesh.material_override = new_mat
|
||||
|
||||
func _get_all_mesh_instances(node: Node) -> Array:
|
||||
var result = []
|
||||
if node is MeshInstance3D or node.get_class() == "SkinnedMeshInstance3D":
|
||||
result.append(node)
|
||||
for child in node.get_children():
|
||||
result.append_array(_get_all_mesh_instances(child))
|
||||
return result
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func sync_character(character_name: String) -> void:
|
||||
|
||||
Reference in New Issue
Block a user