From 32c52122092b4e958b4387ef748817c0e527c33a Mon Sep 17 00:00:00 2001 From: Segey Lapin Date: Wed, 15 Apr 2020 12:16:14 +0300 Subject: [PATCH] Implemented simple quest system --- proto3/godot/autoloads/global.gd | 47 ++++++ proto3/godot/autoloads/quests.gd | 213 +++++++++++++++++++++++++ proto3/godot/autoloads/world.gd | 22 +++ proto3/godot/project.godot | 1 + proto3/godot/scenes/main.gd | 17 ++ proto3/godot/scenes/maps/dungeon.gd | 5 - proto3/godot/scenes/maps/stairs.tscn | 29 +++- proto3/godot/scenes/meta-ai.gd | 1 + proto3/godot/system/quest.gd | 92 ----------- proto3/godot/system/quest_objective.gd | 14 -- proto3/godot/system/stats_quest.gd | 29 ---- proto3/godot/system/walk_quest.gd | 61 ------- proto3/godot/ui/quest_indicator.gd | 27 ++++ proto3/godot/ui/quest_indicator.tscn | 10 ++ 14 files changed, 366 insertions(+), 202 deletions(-) create mode 100644 proto3/godot/autoloads/quests.gd create mode 100644 proto3/godot/autoloads/world.gd delete mode 100644 proto3/godot/system/quest.gd delete mode 100644 proto3/godot/system/quest_objective.gd delete mode 100644 proto3/godot/system/stats_quest.gd delete mode 100644 proto3/godot/system/walk_quest.gd create mode 100644 proto3/godot/ui/quest_indicator.gd create mode 100644 proto3/godot/ui/quest_indicator.tscn diff --git a/proto3/godot/autoloads/global.gd b/proto3/godot/autoloads/global.gd index 3300db6..49a90a2 100644 --- a/proto3/godot/autoloads/global.gd +++ b/proto3/godot/autoloads/global.gd @@ -1,11 +1,51 @@ extends Node +signal new_day var raycasts_count = 100 var raycast_queue = [] +var astar: AStar func _ready(): set_save_slot(0) +enum periods {MORNING, DAY, EVENING, NIGHT} +var game_day: int = 0 +var day_period: int = periods.MORNING +var game_hour: int = 0 +var game_minute: int = 0 + +var acc_time:float = 0.0 +var time_active = false + +func _process(delta): + if time_active: + update_time(delta) + +func update_time(delta): + acc_time += delta + if acc_time >= 1.0: + game_minute += 1 + acc_time -= 1.0 + if game_minute == 60: + game_minute = 0 + game_hour += 1 + if game_hour == 24: + game_hour = 0 + game_day += 1 + match(game_hour): + 23,0,1,2,3: + day_period = periods.NIGHT + 4,5,6,7,8,9,10,11: + day_period = periods.MORNING + 12,13,14,15,16: + day_period = periods.DAY + 17,18,19,20,21,22: + day_period = periods.EVENING +func start_time(): + time_active = true +func stop_time(): + time_active = false + func visibility_check(ch1, ch2): var direction: Vector3 = -ch1.global_transform.basis[2].normalized() var to_ch2: Vector3 = (ch2.global_transform.origin - ch1.global_transform.origin).normalized() @@ -38,6 +78,10 @@ func save_characters(): spawner.set_meta("stats", stats) func save_game(): + print("save game") + save_data.game_day = game_day + save_data.game_hour = game_hour + save_data.day_period = day_period assert(save_slot.length() > 0) var fd = File.new() fd.open(save_slot, File.WRITE) @@ -51,4 +95,7 @@ func load_game(): var data = fd.get_as_text() var parse: = JSON.parse(data) save_data = parse.result + game_day = save_data.game_day + game_hour = save_data.game_hour + day_period = save_data.day_period fd.close() diff --git a/proto3/godot/autoloads/quests.gd b/proto3/godot/autoloads/quests.gd new file mode 100644 index 0000000..8ba79b6 --- /dev/null +++ b/proto3/godot/autoloads/quests.gd @@ -0,0 +1,213 @@ +extends Node + +signal new_quest + +var quests = [] + +func save(): + var data = [] + for k in quests: + data.push_back(k.save()) + global.save_data.quests = data +func restore_quest(d): + var q = Quest.new(d.title, d.desc) +func restore(): + for k in global.save_data.quests: + quests.push_back(restore_quest(k)) + + +var quest_triggers = [ + { + "title": "Something is not right.", + "desc": "You wake up from noise. Explore the building to find the source.", + "trigger": ["once", 0, 0, 10], + "objectives": [ + ["walkto_room", "Check enterance.", "Check enterance room.", "exit_room", 8.0] + ] + } +] + +class QuestObjective extends Reference: + var _title + var _desc + var quest + var complete = false + var active = false + func update(): + pass + func activate(): + active = true + func finish(): + active = false + func set_quest(q): + quest = q + func _init(title, desc): + _title = title + _desc = desc + func save(): + var save_data = {} + save_data.create = ["obj", _desc, _title] + save_data.active = active + save_data.complete = complete + return save_data + +class Quest extends Reference: + signal quest_complete + var _title + var _description + var objectives = [] + var children = [] + var complete = false + var cur_objective: int = -1 + func _init(title, desc): + _title = title + _description = desc + func add_objective(obj): + objectives.push_back(obj) + + func remove_objective(obj): + objectives.erase(obj) + func add_child(obj): + children.push_back(obj) + func remove_child(obj: Quest): + children.erase(obj) + func save(): + var save_data = {} + save_data.title = _title + save_data.desc = _description + return save_data + func update(): + for k in children: + k.update() + for k in objectives: + k.update() + var old_objective:int = cur_objective + complete = true + for k in range(objectives.size()): + if !objectives[k].complete: + cur_objective = k + complete = false + break + for k in children: + if !k.complete: + complete = false + if complete: + emit_signal("quest_complete", self) + if cur_objective != old_objective: + if old_objective >= 0: + objectives[old_objective].finish() + objectives[cur_objective].activate() + func get_title(): + return _title + func get_description(): + return _title +class ObjectiveWalkto extends QuestObjective: + var where = Vector3() + var meta = "" + var radius = 0.0 + var indicator = preload("res://ui/quest_indicator.tscn") + var ind_i: Node2D + var old_pos = Vector3() + func _init(t, d, w, r).(t, d): + meta = w + radius = r + func activate(): + active = true + ind_i = indicator.instance() + var player_pos: Vector3 = global.player.global_transform.origin + var base = global.astar.get_closest_point(player_pos) + var tgt = global.astar.get_closest_point(where) + var path = global.astar.get_point_path(base, tgt) + if path.size() > 1: + ind_i.target = path[1] + Vector3(0, 1, 0) * 0.3 + else: + ind_i.target = where + Vector3(0, 1, 0) * 0.3 + global.get_viewport().add_child(ind_i) + print(_title, "ACTIVATED") + old_pos = player_pos + func finish(): + active = false + ind_i.queue_free() + func update(): + if !active: + return + var player_pos: Vector3 = global.player.global_transform.origin + if old_pos.distance_to(player_pos) > 0.5: + var base = global.astar.get_closest_point(player_pos) + var tgt = global.astar.get_closest_point(where) + var path = global.astar.get_point_path(base, tgt) + if path.size() > 1: + var ind = 0 + var pt = path[ind] + while ind < path.size() - 1: + pt = path[ind] + if pt.distance_to(player_pos) > 2.0: + ind_i.target = pt + Vector3(0, 1, 0) * 0.3 + break + ind += 1 + else: + ind_i.target = where + Vector3(0, 1, 0) * 0.3 + old_pos = player_pos + func save(): + var save_data = {} + save_data.create = ["walkto_room", _title, _desc, meta, radius] + save_data.active = active + save_data.complete = complete + return save_data + +func _ready(): + pass + + +func check_trigger(t): + var t_type = t[0] + match(t_type): + "once": + var t_day = t[1] + var t_hour = t[2] + var t_minute = t[3] + if global.game_day != t_day: + return false + if global.game_hour != t_hour: + return false + if int(global.game_minute / 10) != int(t_minute / 10): + return false + return true + return false +func create_objective(v): + var o_type = v[0] + match(o_type): + "walkto_room": + var o_title = v[1] + var o_desc = v[2] + var o_meta = v[3] + var o_radius = v[4] + var obj = ObjectiveWalkto.new(o_title, o_desc, o_meta, o_radius) + return obj + return null + +var up_time = 0.0 +var state: int = 0 +func _process(delta): + up_time += delta + if up_time > 1000.0: + up_time = 0.0 + if int(up_time * 10.0) % 10 == 1: + var processed = [] + while quest_triggers.size() > 0: + var k = quest_triggers.pop_front() + if check_trigger(k.trigger): + print("quest triggered: ", k.title) + var q = Quest.new(k.title, k.desc) + quests.push_back(q) + for r in k.objectives: + var obj = create_objective(r) + if obj: + q.add_objective(obj) + emit_signal("new_quest", q) + else: + processed.push_back(k) + quest_triggers = processed + for k in quests: + k.update() + diff --git a/proto3/godot/autoloads/world.gd b/proto3/godot/autoloads/world.gd new file mode 100644 index 0000000..fcb7493 --- /dev/null +++ b/proto3/godot/autoloads/world.gd @@ -0,0 +1,22 @@ +extends Node +signal level_up +signal new_quest + +var money: int = 2000 +var master_node +var current_room +var team = {} +var line = {} +var training = false +# warning-ignore:unused_class_variable +var quests : = [] +# warning-ignore:unused_class_variable +var team_train_count : = 0 +# warning-ignore:unused_class_variable +var arrow: Spatial +# warning-ignore:unused_class_variable +var next_scene: String +var player_visual = { + "gender": "male" +} + diff --git a/proto3/godot/project.godot b/proto3/godot/project.godot index e448554..9943195 100644 --- a/proto3/godot/project.godot +++ b/proto3/godot/project.godot @@ -218,6 +218,7 @@ global="*res://autoloads/global.gd" rpg="*res://autoloads/rpg.gd" combat="*res://autoloads/combat.gd" phy_bones="*res://autoloads/phy_bones.gd" +quests="*res://autoloads/quests.gd" [input] diff --git a/proto3/godot/scenes/main.gd b/proto3/godot/scenes/main.gd index 0d88522..c1eba85 100644 --- a/proto3/godot/scenes/main.gd +++ b/proto3/godot/scenes/main.gd @@ -1,5 +1,11 @@ extends Spatial var loading + +func new_quest(q): + var title = q.get_title() + var desc = q.get_description() + print("title: ", title) + print("desc: ", desc) func _ready(): loading = preload("res://ui/loading.tscn").instance() get_tree().get_root().add_child(loading) @@ -12,6 +18,8 @@ func _ready(): global.set_save_slot(0) e = $dungeon.connect("prepared", self, "start_ai") assert(e == OK) + e = quests.connect("new_quest", self, "new_quest") + assert(e == OK) var default_meta = { "grabbing": false, @@ -32,6 +40,12 @@ func start_ai(): print("prepared") $"meta-ai".start() +func save(): + global.save_characters() + $dungeon.save() + quests.save() + global.save_game() + func spawn_player(spawner): print("spawned player") loading.queue_free() @@ -50,6 +64,7 @@ func spawn_player(spawner): player.set_meta("spawner", spawner) player.add_to_group("player") $cam_target/cam_rot/offset/Camera.current = true + global.start_time() func spawn_npc(spawner): var npc var g @@ -221,3 +236,5 @@ func _process(delta): $cam_target.rotate_y(-angle * delta) else: cam_fixup_cooldown -= delta + if Input.is_action_just_pressed("save_game"): + save() diff --git a/proto3/godot/scenes/maps/dungeon.gd b/proto3/godot/scenes/maps/dungeon.gd index e42695b..d5c0be3 100644 --- a/proto3/godot/scenes/maps/dungeon.gd +++ b/proto3/godot/scenes/maps/dungeon.gd @@ -23,12 +23,10 @@ var dungeon_save = {} var spawn_save = {} var prepared = false func save(): - global.save_characters() for k in range(dungeon.size()): dungeon[k].save() dungeon_save[str(k)] = dungeon[k].save_data global.save_data.dungeon = dungeon_save - global.save_game() var window_rooms = [] func build_rooms(): print("build_rooms") @@ -214,6 +212,3 @@ func _process(_delta): state = 50 prepared = true emit_signal("prepared") - _: - if Input.is_action_just_pressed("save_game"): - save() diff --git a/proto3/godot/scenes/maps/stairs.tscn b/proto3/godot/scenes/maps/stairs.tscn index ac8043d..4fb6ceb 100644 --- a/proto3/godot/scenes/maps/stairs.tscn +++ b/proto3/godot/scenes/maps/stairs.tscn @@ -1,10 +1,22 @@ -[gd_scene load_steps=3 format=2] +[gd_scene load_steps=5 format=2] [ext_resource path="res://scenes/maps/stairs.escn" type="PackedScene" id=1] [sub_resource type="BoxShape" id=1] extents = Vector3( 1.13086, 0.0458848, 0.64188 ) +[sub_resource type="Curve3D" id=2] +_data = { +"points": PoolVector3Array( 0, 0, 0, 0, 0, 0, -3.40015, 0.239252, 1.85913, 0, 0, 0, 0, 0, 0, -1.97383, 0.257656, 1.88403, 0, 0, 0, 0, 0, 0, -1.45852, 0.423293, 1.90918, 0, 0, 0, 0, 0, 0, -0.13343, 1.49073, 1.93433, 0, 0, 0, 0, 0, 0, 0.24645, 1.77444, 1.93433, 0, 0, 0, 0, 0, 0, 1.75415, 1.76855, 1.87302, 0, 0, 0, 0, 0, 0, 1.66716, 1.85563, 0.244141, 0, 0, 0, 0, 0, 0, 1.66137, 1.75269, -0.562487, 0, 0, 0, 0, 0, 0, 1.65557, 1.76514, -1.72805, 0, 0, 0, 0, 0, 0, 0.974322, 1.71509, -1.75141, 0, 0, 0, 0, 0, 0, 0.287957, 2.12817, -1.72775, 0, 0, 0, 0, 0, 0, -0.201176, 2.55396, -1.71986, 0, 0, 0, 0, 0, 0, -0.666642, 3.04525, -1.72119, 0, 0, 0, 0, 0, 0, -1.27411, 3.41605, -1.72168, 0, 0, 0, 0, 0, 0, -2.65473, 3.40816, -1.73389 ), +"tilts": PoolRealArray( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) +} + +[sub_resource type="Curve3D" id=3] +_data = { +"points": PoolVector3Array( 0, 0, 0, 0, 0, 0, -4.5026, 0.332731, -0.0107422, 0, 0, 0, 0, 0, 0, -3.99813, 0.375664, -0.0107422, 0, 0, 0, 0, 0, 0, -4.07327, 0.375664, -1.81396, 0, 0, 0, 0, 0, 0, -4.084, 0.36493, -2.81201, 0, 0, 0, 0, 0, 0, -3.81567, 0.375664, -3.27344, 0, 0, 0, 0, 0, 0, -1.64755, 0.343464, -3.28418, 0, 0, 0, 0, 0, 0, -0.520562, 0.407863, -3.32715, 0, 0, 0, 0, 0, 0, 0.101966, 0.482996, -3.68164, 0, 0, 0, 0, 0, 0, 0.917692, 0.440063, -3.30566, 0, 0, 0, 0, 0, 0, 1.86222, 0.504463, -3.27344, 0, 0, 0, 0, 0, 0, 3.33267, 0.547396, -3.30566, 0, 0, 0, 0, 0, 0, 3.7298, 0.504463, -3.31641, 0, 0, 0, 0, 0, 0, 3.62247, 0.515196, -2.55469, 0, 0, 0, 0, 0, 0, 3.65467, 0.568862, -1.3418, 0, 0, 0, 0, 0, 0, 3.93373, 0.622528, -0.665527, 0, 0, 0, 0, 0, 0, 4.245, 0.547396, -0.236328, 0, 0, 0, 0, 0, 0, 4.55626, 0.547396, -0.0429688, 0, 0, 0, 0, 0, 0, 4.406, 0.558129, 0.0751953, 0, 0, 0, 0, 0, 0, 4.0518, 0.525929, 1.0625, 0, 0, 0, 0, 0, 0, 3.8586, 0.504463, 2.66187, 0, 0, 0, 0, 0, 0, 3.5688, 0.504463, 3.14478, 0, 0, 0, 0, 0, 0, 2.17348, 0.515196, 3.06982, 0, 0, 0, 0, 0, 0, 0.552762, 0.407863, 3.00537, 0, 0, 0, 0, 0, 0, 0.316631, 0.42933, 3.55273, 0, 0, 0, 0, 0, 0, -0.252232, 0.42933, 2.94092, 0, 0, 0, 0, 0, 0, -1.29336, 0.375664, 2.9624, 0, 0, 0, 0, 0, 0, -3.28974, 0.386397, 3.01611, 0, 0, 0, 0, 0, 0, -3.9552, 0.418597, 2.95166, 0, 0, 0, 0, 0, 0, -4.16987, 0.354197, 2.52222, 0, 0, 0, 0, 0, 0, -4.3416, 0.375664, 1.42749, 0, 0, 0, 0, 0, 0, -4.2128, 0.289798, 0.493652 ), +"tilts": PoolRealArray( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) +} + [node name="stairs" instance=ExtResource( 1 )] [node name="StaticBody" type="StaticBody" parent="." index="4"] @@ -16,3 +28,18 @@ shape = SubResource( 1 ) [node name="CollisionShape2" type="CollisionShape" parent="StaticBody" index="1"] transform = Transform( -0.768529, 0.639815, -3.25444e-07, 0.639815, 0.768529, 1.60706e-08, 2.60396e-07, -1.95874e-07, -1, -0.0615042, 2.2555, -1.95211 ) shape = SubResource( 1 ) + +[node name="Path" type="Path" parent="." index="5" groups=[ +"path", +]] +curve = SubResource( 2 ) + +[node name="Path2" type="Path" parent="." index="6" groups=[ +"path", +]] +curve = SubResource( 3 ) + +[node name="Path3" type="Path" parent="." index="7" groups=[ +"path", +]] +curve = SubResource( 3 ) diff --git a/proto3/godot/scenes/meta-ai.gd b/proto3/godot/scenes/meta-ai.gd index bb96eb5..c8a3046 100644 --- a/proto3/godot/scenes/meta-ai.gd +++ b/proto3/godot/scenes/meta-ai.gd @@ -15,6 +15,7 @@ func start(): func _ready(): astar = AStar.new() + global.astar = astar func calc_visible_lists(): for g in get_tree().get_nodes_in_group("npc"): diff --git a/proto3/godot/system/quest.gd b/proto3/godot/system/quest.gd deleted file mode 100644 index a7be58b..0000000 --- a/proto3/godot/system/quest.gd +++ /dev/null @@ -1,92 +0,0 @@ -extends Reference -class_name Quest -signal complete -signal failed -signal started -var _objectives = [] -var _children = [] -var _title: String -var _description: String -var _active: bool = false -var _complete: bool = false -var _next_quest: Quest -func _init(title: String, description: String): - _title = title - _description = description -func add_child(quest: Quest): - _children.push_back(quest) -func is_complete(): - return _complete -func is_active(): - return _active -func update(): - if !_active: - return -# var m = get_meta("quest") -# if m != null: -# for k in _objectives: -# k.set_meta("quest", m) - for k in _objectives: - k.update() - for k in _children: - k.update() - _complete = true - for k in _objectives: - if !k.is_complete(): - _complete = false - break - if !_complete: - print("quest: ", _title, " objectives incomplete") - return - for k in _children: - if !k.is_complete(): - _complete = false - break - if !_complete: - print("quest: ", _title, " children incomplete") - if _complete: - emit_signal("complete", self) - _active = false - quest_complete() -func quest_complete_handler(quest: Quest): - var next = quest.get_next_quest() - if next != null: - add_child(next) - next.connect("complete", self, "quest_complete_handler") - next.start() -func start(): - _active = true - for k in _children: - k.connect("complete", self, "quest_complete_handler") - k.start() - emit_signal("started", self) - print("children: ", _children) - print("quest: ", _title, " started") -func get_cur_task_text(): - var ret: String = "No current task" - if _active: - for p in _children: - if p.is_active(): - ret = p.get_cur_task_text() - return ret - for p in _objectives: - if !p.is_complete(): - return get_title() + ": " + p.get_title() - return _title - return ret -func get_title(): - return _title -func get_description(): - return _description -func quest_complete(): - print("quest: ", _title, " complete") -func add_objective(obj: QuestObjective): - if !obj in _objectives: - _objectives.push_back(obj) -func remove_objective(obj: QuestObjective): - if obj in _objectives: - _objectives.erase(obj) -func set_next_quest(obj: Quest): - _next_quest = obj -func get_next_quest() -> Quest: - return _next_quest diff --git a/proto3/godot/system/quest_objective.gd b/proto3/godot/system/quest_objective.gd deleted file mode 100644 index bebdf54..0000000 --- a/proto3/godot/system/quest_objective.gd +++ /dev/null @@ -1,14 +0,0 @@ -extends Reference -class_name QuestObjective - -var _complete: bool = false -var _title: String - -func _init(title: String): - _title = title -func is_complete(): - return _complete -func update(): - pass -func get_title(): - return _title diff --git a/proto3/godot/system/stats_quest.gd b/proto3/godot/system/stats_quest.gd deleted file mode 100644 index 9c2c47e..0000000 --- a/proto3/godot/system/stats_quest.gd +++ /dev/null @@ -1,29 +0,0 @@ -extends Quest -class_name StatsQuest - -var stat_check: Dictionary - -class StatsCheckObjective extends QuestObjective: - var stat_check: Dictionary - func _init(title, stats: Dictionary).(title): - stat_check = stats - func update(): - _complete = true - for k in stat_check.keys(): - match(k): - "player_count": - if world.team.keys().size() < stat_check[k]: - _complete = false - print("player count: ", world.team.keys().size(), " < ", stat_check[k]) - "cheerleader_count": - if world.cheer_team.keys().size() < stat_check[k]: - _complete = false - "team_train_count": - if world.team_train_count < stat_check[k]: - _complete = false - _: - _complete = false - -func _init(title, desc, stats: Dictionary).(title, desc): - stat_check = stats - add_objective(StatsCheckObjective.new("Comply to team stats", stat_check)) diff --git a/proto3/godot/system/walk_quest.gd b/proto3/godot/system/walk_quest.gd deleted file mode 100644 index 73b39fd..0000000 --- a/proto3/godot/system/walk_quest.gd +++ /dev/null @@ -1,61 +0,0 @@ -extends Quest -class_name WalkQuest - -# Declare member variables here. Examples: -# var a = 2 -# var b = "text" - -# Called when the node enters the scene tree for the first time. -var destination: Spatial -var quest_marker: Spatial -class WalkQuestObjective extends QuestObjective: - var dest: Spatial - var arrow: Spatial - var nav: Navigation - func _init(title, destination: Spatial).(title): - dest = destination - arrow = world.arrow - nav = world.arrow.get_node("/root/main/nav") - func update(): - var org = world.master_node.global_transform.origin - var orgc = nav.get_closest_point(org) - var dst = dest.global_transform.origin - var dstc = nav.get_closest_point(dst) - var path = nav.get_simple_path(orgc, dstc) - var arrow_dir : = Vector3() - if path.size() > 1: - for e in path: - if (e - org).length() > 1.0: - arrow_dir = e - org - break - if arrow_dir.length() == 0 && arrow.visible: - arrow.hide() - elif arrow_dir.length() > 0: - if !arrow.visible: - arrow.show() - arrow_dir.y = 0 - arrow.look_at(arrow.global_transform.origin + arrow_dir, Vector3.UP) - - if org.distance_to(dest.global_transform.origin) < 2.5: - _complete = true - arrow.hide() -func _init(title, desc, dest).(title, desc): - destination = dest - add_objective(WalkQuestObjective.new("Walk to destination", dest)) -func update(): - .update() -func start(): - .start() - quest_marker = load("res://markers/quest_marker.tscn").instance() - world.master_node.get_node("/root/main").add_child(quest_marker) - quest_marker.global_transform.origin = destination.global_transform.origin - print("destination: ", quest_marker.global_transform.origin) - if world.arrow: - world.arrow.show() - - -func quest_complete(): - .quest_complete() - quest_marker.queue_free() - if world.arrow: - world.arrow.hide() diff --git a/proto3/godot/ui/quest_indicator.gd b/proto3/godot/ui/quest_indicator.gd new file mode 100644 index 0000000..efc9d9c --- /dev/null +++ b/proto3/godot/ui/quest_indicator.gd @@ -0,0 +1,27 @@ +extends Node2D + + +# Declare member variables here. Examples: +# var a = 2 +# var b = "text" + + +# Called when the node enters the scene tree for the first time. +var target: = Vector3() +var rect: = Rect2() +func _ready(): + var pos = get_viewport().get_camera().unproject_position(target) + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + var pos = get_viewport().get_camera().unproject_position(target) + rect = get_viewport_rect() + if rect.has_point(pos): + if !visible: + show() + else: + pos.x = clamp(pos.x, rect.position.x, rect.position.x + rect.size.x) + pos.y = clamp(pos.x, rect.position.x, rect.position.x + rect.size.x) + position = position.linear_interpolate(pos, delta) + diff --git a/proto3/godot/ui/quest_indicator.tscn b/proto3/godot/ui/quest_indicator.tscn new file mode 100644 index 0000000..5ed4b04 --- /dev/null +++ b/proto3/godot/ui/quest_indicator.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://ui/textures/minimapIcon_exclamationRed.png" type="Texture" id=1] +[ext_resource path="res://ui/quest_indicator.gd" type="Script" id=2] + +[node name="quest_indicator" type="Node2D"] +script = ExtResource( 2 ) + +[node name="Sprite" type="Sprite" parent="."] +texture = ExtResource( 1 )