100 lines
2.9 KiB
GDScript
100 lines
2.9 KiB
GDScript
extends Object
|
|
|
|
## NEO-25: spawns walkable interactable props + glow marker pairs from server descriptor dicts.
|
|
## Returns glow groups for [method InteractionRadiusIndicators.setup_glow_groups].
|
|
|
|
const _PROP_SIZE := Vector3(0.9, 1.0, 0.4)
|
|
const _MARKER_MESH_SIZE := Vector3(0.22, 0.35, 0.22)
|
|
const _MARKER_OFFSET_A := Vector3(1.1, 0.25, 0.9)
|
|
const _MARKER_OFFSET_B := Vector3(-0.95, 0.22, -1.05)
|
|
|
|
|
|
static func build_from_catalog(
|
|
descriptors: Array, interactables_root: Node3D, markers_root: Node3D
|
|
) -> Array:
|
|
for c in interactables_root.get_children():
|
|
c.free()
|
|
for c in markers_root.get_children():
|
|
c.free()
|
|
|
|
var glow_groups: Array = []
|
|
|
|
for row in descriptors:
|
|
if not row is Dictionary:
|
|
continue
|
|
var rd: Dictionary = row
|
|
var id: String = str(rd.get("interactableId", ""))
|
|
var kind: String = str(rd.get("kind", ""))
|
|
var anchor: Vector3 = _anchor_from_row(rd)
|
|
var radius: float = float(rd.get("interactionRadius", 0.0))
|
|
|
|
var body := StaticBody3D.new()
|
|
body.name = "Interactable_%s" % id
|
|
body.collision_mask = 3
|
|
body.add_to_group("walkable")
|
|
interactables_root.add_child(body)
|
|
body.global_position = anchor
|
|
|
|
var prop_mesh := MeshInstance3D.new()
|
|
var box_mesh := BoxMesh.new()
|
|
box_mesh.size = _PROP_SIZE
|
|
prop_mesh.mesh = box_mesh
|
|
prop_mesh.position = Vector3.ZERO
|
|
var prop_mat := StandardMaterial3D.new()
|
|
if kind == "resource_node":
|
|
prop_mat.albedo_color = Color(0.18, 0.55, 0.32, 1.0)
|
|
else:
|
|
prop_mat.albedo_color = Color(0.28, 0.38, 0.45, 1.0)
|
|
prop_mesh.material_override = prop_mat
|
|
body.add_child(prop_mesh)
|
|
|
|
var col := CollisionShape3D.new()
|
|
var box_shape := BoxShape3D.new()
|
|
box_shape.size = _PROP_SIZE
|
|
col.shape = box_shape
|
|
body.add_child(col)
|
|
|
|
var marker_parent := Node3D.new()
|
|
marker_parent.name = "Markers_%s" % id
|
|
markers_root.add_child(marker_parent)
|
|
marker_parent.global_position = anchor
|
|
|
|
var mi_a := _make_marker_mesh()
|
|
mi_a.position = _MARKER_OFFSET_A
|
|
marker_parent.add_child(mi_a)
|
|
var mi_b := _make_marker_mesh()
|
|
mi_b.position = _MARKER_OFFSET_B
|
|
marker_parent.add_child(mi_b)
|
|
|
|
var glow_mat := StandardMaterial3D.new()
|
|
glow_mat.albedo_color = Color(0.15, 0.4, 1.0, 1.0)
|
|
glow_mat.emission_enabled = true
|
|
glow_mat.emission = Color(0.3, 0.6, 1.0)
|
|
glow_mat.emission_energy_multiplier = 0.12
|
|
mi_a.material_override = glow_mat
|
|
mi_b.material_override = glow_mat
|
|
|
|
glow_groups.append(
|
|
{"anchor": anchor, "radius": radius, "material": glow_mat, "markers": [mi_a, mi_b]}
|
|
)
|
|
|
|
return glow_groups
|
|
|
|
|
|
static func _anchor_from_row(rd: Dictionary) -> Vector3:
|
|
var a: Variant = rd.get("anchor", null)
|
|
if not a is Dictionary:
|
|
return Vector3.ZERO
|
|
var ad: Dictionary = a
|
|
return Vector3(
|
|
float(ad.get("x", 0.0)), float(ad.get("y", 0.0)), float(ad.get("z", 0.0)))
|
|
)
|
|
|
|
|
|
static func _make_marker_mesh() -> MeshInstance3D:
|
|
var mi := MeshInstance3D.new()
|
|
var m := BoxMesh.new()
|
|
m.size = _MARKER_MESH_SIZE
|
|
mi.mesh = m
|
|
return mi
|