TowerGame/scripts/task.gd

90 lines
2.8 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 get_task_name() -> String:
return ""
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
var item_found: bool = false
#if building2.consumer != null:
#item_found |= building2.consumer.check_storage_for_item(item)
if building2.producer != null:
item_found = building2.producer.produced_item == item
if item_found:
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