155 lines
3.5 KiB
GDScript
155 lines
3.5 KiB
GDScript
class_name Quest extends Object
|
|
|
|
|
|
enum Status{
|
|
OPEN,
|
|
TAKEN,
|
|
IN_PROGRESS,
|
|
COMPLETED,
|
|
FAILED,
|
|
CLOSED
|
|
}
|
|
|
|
class Event:
|
|
enum Type{
|
|
WAIT,
|
|
COMBAT,
|
|
CHOICE
|
|
}
|
|
var type : Type = Type.WAIT
|
|
var enemies : Array[String] = []
|
|
var time : float = 1
|
|
var time_elapsed
|
|
signal completed()
|
|
|
|
var participants : Array = []
|
|
var turn_queue : Array = []
|
|
var busy_list : Array = []
|
|
var dex_speed : int
|
|
|
|
func start_combat(adventurers : Array, enemies : Array) -> void:
|
|
participants = []
|
|
participants.append_array(adventurers)
|
|
participants.append_array(enemies)
|
|
|
|
var c_order : Array = []
|
|
var dex_speed = 0
|
|
for p in participants:
|
|
c_order.append([p, p.stats.dex])
|
|
if p.stats.dex > dex_speed:
|
|
dex_speed = p.stats.dex
|
|
|
|
c_order.sort_custom(func(a,b): return a[1] > b[1])
|
|
var delay = 5
|
|
var last_time = 0
|
|
for c in c_order:
|
|
var time = delay * dex_speed / c[1]
|
|
turn_queue.append({"combatant":c[0], "time": time - last_time})
|
|
last_time = time
|
|
|
|
func execute_attack(combatant, target) -> void:
|
|
busy_list.append(target)
|
|
#TODO: Make the combatant execute an attack
|
|
#TODO: Make the target take damage
|
|
|
|
func execute_action(combatant) -> void:
|
|
busy_list = [combatant]
|
|
#TODO: Come up with other options than just swinging at each other
|
|
var enemies : Array = get_enemy_list(combatant)
|
|
var target = enemies.pick_random()
|
|
execute_attack(combatant, target)
|
|
|
|
func get_enemy_list(combatant) -> Array:
|
|
var lst = []
|
|
for p in participants:
|
|
if p != combatant:
|
|
lst.append(p)
|
|
return lst
|
|
|
|
func resolve_combat() -> void:
|
|
pass
|
|
|
|
func process(delta : float) -> void:
|
|
#TODO: Make quest combat work
|
|
if type == Type.COMBAT:
|
|
if len(busy_list) < 1:
|
|
if len(turn_queue) > 0:
|
|
turn_queue[0].time -= delta
|
|
if turn_queue[0].time <= 0:
|
|
var c = turn_queue.pop_front()
|
|
if len(turn_queue) > 0:
|
|
turn_queue[0].time += c.time
|
|
execute_action(c.combatant)
|
|
else:
|
|
resolve_combat()
|
|
|
|
time_elapsed += delta
|
|
if time_elapsed >= time:
|
|
completed.emit()
|
|
|
|
var name : String = "A Basic Quest"
|
|
var desc : String = "The default quest, with no special anything."
|
|
var difficulty : int = 1
|
|
var location : String
|
|
var steps : int = 1
|
|
var rewards : Dictionary
|
|
var length : float = 10
|
|
var events : Array[Event] = []
|
|
|
|
|
|
var progress : float = 0
|
|
var current_step : int = 0
|
|
var taken : bool = false
|
|
var status : Status = Status.OPEN
|
|
|
|
var questor : AdventurerData = null
|
|
signal status_changed(status : Status)
|
|
|
|
func _init() -> void:
|
|
pass
|
|
|
|
func initiate(member : AdventurerData) -> void:
|
|
questor = member
|
|
status = Status.TAKEN
|
|
status_changed.emit(Status.TAKEN)
|
|
|
|
func fail() -> void:
|
|
status = Status.FAILED
|
|
status_changed.emit(Status.FAILED)
|
|
|
|
func complete() -> void:
|
|
status = Status.COMPLETED
|
|
status_changed.emit(Status.COMPLETED)
|
|
for reward in rewards.keys():
|
|
if reward == "gold":
|
|
questor.gain_gold(rewards[reward])
|
|
elif reward == "exp":
|
|
questor.gain_exp(rewards[reward])
|
|
#TODO: Implement other reward types
|
|
#elif rewards[reward] is Item:
|
|
# questor.gain_item()
|
|
#else it's a guild item they'll bring back for us
|
|
Game.notice("%s completed the quest '%s'!" % [questor.full_name(), name])
|
|
|
|
func num_events() -> int:
|
|
return len(events)
|
|
|
|
#TODO: Put in quest requirements
|
|
func is_eligible(member : AdventurerData) -> bool:
|
|
return !taken
|
|
|
|
func is_taken() -> bool:
|
|
return status == Status.TAKEN
|
|
|
|
|
|
|
|
func difficulty_name() -> String:
|
|
match(difficulty):
|
|
0: return "None"
|
|
1: return "Trivial"
|
|
2: return "Moderate"
|
|
3: return "Severe"
|
|
4: return "Extreme"
|
|
5: return "Legendary"
|
|
_: return "Unknown"
|