extends Node var marker_list = [] var label_count = 10 var labels = [] var max_dist = 4 var current_marker var cam func node_added(node): if node.name.begins_with("marker_"): if !node in marker_list: marker_list.push_back(node) func node_removed(node): marker_list.erase(node) var state = 0 func _ready(): get_tree().connect("node_added", self, "node_added") get_tree().connect("node_removed", self, "node_removed") var root = get_tree().get_root() var queue = [root] while queue.size() > 0: var item = queue.pop_front() if item.name.begins_with("marker_"): marker_list.push_back(item) for e in item.get_children(): queue.push_back(e) func see_through_marker(m): if !m.has_meta("marker_data"): return false var md = m.get_meta("marker_data") if md.has("see_through") && md.see_through == true: return true return false func _process(delta): if state == 0: var root = get_tree().get_root() for _e in range(label_count): var tl = Label.new() root.add_child(tl) tl.hide() labels.push_back(tl) state = 1 if state == 1: var cam = get_viewport().get_camera() if !cam.has_meta("player"): return var player = cam.get_meta("player") assert(player) var size = get_viewport().size var center = size/2 var visible_markers = [] var wstate = cam.get_world().direct_space_state for e in marker_list: var cam_pos = cam.global_transform.origin var player_pos = player.global_transform.origin var marker_pos = e.global_transform.origin if player_pos.distance_squared_to(marker_pos) < max_dist * max_dist: var lpos = cam.global_transform.xform_inv(marker_pos) if lpos.z < 0: if see_through_marker(e) && e.visible: visible_markers.push_back(e) elif e.visible: var xlist = [player] if e.has_meta("marker_data"): var md = e.get_meta("marker_data") if !md.has("obj"): e.hide() else: if md.obj is PhysicsBody: xlist.push_back(md.obj) else: e.hide() var result = wstate.intersect_ray(cam_pos, marker_pos, xlist) if !result.has("collider") || !result.collider: visible_markers.push_back(e) var free_labels = [] var process_markers = visible_markers.duplicate() for e in labels: var l: Label = e if l.has_meta("marker"): # var n = l.get_meta("marker") # if n in visible_markers: # process_markers.erase(n) # else: l.remove_meta("marker") free_labels.push_back(l) l.hide() else: free_labels.push_back(l) l.hide() if free_labels.size() == 0: state = 2 return for e in process_markers: if free_labels.size() == 0: break var pos = cam.unproject_position(e.global_transform.origin) var l = free_labels.pop_front() var t = InputMap.get_action_list("activate")[0].as_text() + ": " if e.name.ends_with("_door"): t += "Open" elif e.name.ends_with("_container"): t += "Access" elif e.name.ends_with("_pickup"): t += "Pick up" elif e.name.ends_with("_vehicleseat") || e.name.ends_with("_seat"): t += "Sit" elif e.name.ends_with("_exit"): t += "Exit" elif e.name.ends_with("_talk"): t += "Talk" elif e.name.ends_with("_action"): t += "Action" elif e.name.ends_with("_grab"): t += "Grab" elif e.name.ends_with("_take"): t += "Take" elif e.name.ends_with("_sacrifice"): t += "Sacrifice" l.set_meta("marker", e) l.text = t l.add_color_override("font_color", Color(0.6,0.6,1,1)) l.rect_position = pos - l.rect_size / 2.0 l.show() var current = null var cur_d = INF for l in labels: if l.visible: var d = l.rect_position.distance_squared_to(center) if !current: cur_d = d current = l else: if cur_d > d: current = l cur_d = d if current: current.add_color_override("font_color", Color(0.9,0.9,1,1)) current_marker = current.get_meta("marker") else: current_marker = null state = 2 if state == 2: state = 1 # var player = get_viewport().get_camera().get_meta("player") # if !controls.is_gui && !player.has_meta("group_behavior") && !player.has_meta("") # if Input.is_action_just_pressed("activate"): # var marker = current_marker # if marker && marker.has_meta("marker_data"): # var md = marker.get_meta("marker_data") # print("marker_data: ", md) # if md.has("obj"): # print("obj: ", md.obj.name) # if md.has("obj") && md.has("method"): # print("activate ", md.obj.name, " ", md.method) # md.obj.call_deferred(md.method, md) func activate_marker(): print("Activate marker") var marker = current_marker if marker && marker.has_meta("marker_data"): var md = marker.get_meta("marker_data") print("marker_data: ", md) if md.has("obj"): print("obj: ", md.obj.name) if md.has("obj") && md.has("method"): print("activate ", md.obj.name, " ", md.method) md.obj.call_deferred(md.method, md) func init_markers(obj, marker_info): var queue = [obj] while queue.size() > 0: var item = queue.pop_front() if item.name.begins_with("marker_"): if marker_info.has(item.name): marker_info[item.name].marker_obj = item for e in item.get_children(): queue.push_back(e) queue = [obj] while queue.size() > 0: var item = queue.pop_front() if item.name.begins_with("marker_"): var marker_data = {} marker_data.obj = obj if marker_info.has(item.name): var o = marker_info[item.name] for k in o.keys(): marker_data[k] = o[k] if o.has("see_through") && o.see_through: item.hide() item.set_meta("marker_data", marker_data) for e in item.get_children(): queue.push_back(e) func init_marker(m, obj, data): assert(m) assert(obj) assert(data) var marker_data = {} marker_data.obj = m for e in data.keys(): marker_data[e] = data[e] if data.has("see_through") && data.see_through: obj.hide() obj.set_meta("marker_data", marker_data) if !obj in marker_list: marker_list.push_back(obj)