84 lines
2.6 KiB
GDScript
84 lines
2.6 KiB
GDScript
extends RefCounted
|
|
class_name Task
|
|
|
|
var name: String
|
|
#var source: TaskManager
|
|
var solicitation_time: float = 1.0
|
|
var priority: int = TASK_PRIORITY_ANYTIME
|
|
var min_worker_count: int = 1
|
|
var max_worker_count: int = 1
|
|
var potential_workers: Dictionary[Citizen, float] = {}
|
|
var workers: Array[Citizen] = []
|
|
|
|
const FLOAT64_MAX: float = 2.0**1023 * (2 - 2.0**-52)
|
|
const TASK_PRIORITY_ANYTIME = 0
|
|
const TASK_PRIORITY_BY_WAVE_START = 10
|
|
const TASK_PRIORITY_ASAP = 20
|
|
|
|
func is_ready_to_start() -> bool:
|
|
return true
|
|
func get_location() -> Vector3:
|
|
return Vector3()
|
|
func run() -> void:
|
|
for worker in workers:
|
|
worker.assign_task(self)
|
|
func execute(worker: Citizen) -> bool:
|
|
return false
|
|
func interrupt(worker: Citizen) -> void:
|
|
workers.erase(worker)
|
|
if workers.size() < min_worker_count:
|
|
cancel()
|
|
func cancel() -> void:
|
|
pass
|
|
|
|
static func sort_tasks(a: Task, b: Task) -> bool:
|
|
return a.priority > b.priority
|
|
|
|
class BuildTask extends Task:
|
|
var building: Building
|
|
func _init() -> void:
|
|
priority = 1
|
|
func get_task_name() -> String:
|
|
return "Build " + building.name
|
|
func is_ready_to_start() -> bool:
|
|
return super() and building.can_build()
|
|
func get_location() -> Vector3:
|
|
return building.global_position
|
|
func execute(worker: Citizen) -> bool:
|
|
if !await worker.go_to_destination(building.position): return false
|
|
if !await worker.build_building(building): return false
|
|
return true
|
|
|
|
class FetchItemTask extends Task:
|
|
var building: Building
|
|
var item: Item
|
|
func get_task_name() -> String:
|
|
return "Transfer " + item.name + " to " + building.name
|
|
func execute(worker: Citizen) -> bool:
|
|
# find the item from nearby buildings
|
|
# TODO: also look for items on the floor?
|
|
var storage_building: Building = null
|
|
var closest: float = FLOAT64_MAX
|
|
|
|
for building2 in worker.get_tree().get_nodes_in_group("Buildings"):
|
|
if building2 is not Building:
|
|
continue
|
|
if building2.consumer == null:
|
|
continue
|
|
if building2.consumer.check_storage_for_item(item):
|
|
var distance_sqr: float = building2.global_position.distance_squared_to(worker.position)
|
|
if distance_sqr < closest:
|
|
storage_building = building2
|
|
closest = distance_sqr
|
|
|
|
if storage_building == null: return false
|
|
# go to the storage
|
|
if !await worker.go_to_destination(storage_building.global_position): return false
|
|
# pick up the item
|
|
if !await worker.take_item_from_building(item, storage_building): return false
|
|
# carry the item to the construction site
|
|
if !await worker.go_to_destination(building.global_position): return false
|
|
# store the item in the construction site
|
|
if !await worker.put_item_in_building_materials(building): return false
|
|
return true
|