214 lines
5.8 KiB
GDScript
214 lines
5.8 KiB
GDScript
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)
|