Files
kicking-high/proto3/godot/autoloads/quests.gd
2020-04-15 12:16:14 +03:00

214 lines
5.0 KiB
GDScript

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()