Connect paid food purchasing, kitchen production, and porter deliveries
This commit is contained in:
@@ -48,6 +48,7 @@ var _dispatcher := TaskDispatcherType.new()
|
||||
var _item_reserver := Callable()
|
||||
var _item_releaser := Callable()
|
||||
var _travel_estimator := Callable()
|
||||
var _external_task_driver := Callable()
|
||||
|
||||
|
||||
func configure_callbacks(
|
||||
@@ -62,6 +63,49 @@ func configure_callbacks(
|
||||
return self
|
||||
|
||||
|
||||
## External operations own their work-completion transaction while retaining
|
||||
## ordinary Staff movement, shifts, and bidirectional Task ownership.
|
||||
func configure_external_task_driver(driver: Callable = Callable()) -> void:
|
||||
_external_task_driver = driver
|
||||
|
||||
|
||||
func is_externally_driven_task(task_id: StringName) -> bool:
|
||||
return _external_task_driver.is_valid() and bool(_external_task_driver.call(task_id))
|
||||
|
||||
|
||||
func assign_task_to_staff(task_id: StringName, staff_id: StringName, absolute_minute: int) -> CommandResult:
|
||||
var task := get_task(task_id)
|
||||
var staff := get_staff(staff_id)
|
||||
if task == null or staff == null or not task.is_dispatchable():
|
||||
return _conflict("Task or employee is unavailable for assignment.")
|
||||
if not task.required_items.is_empty() or not task.reservation_ids.is_empty():
|
||||
return _conflict("Explicit assignment requires externally reserved operation inputs.")
|
||||
if not staff.is_available_for_dispatch() or not staff.meets_task_requirements(task):
|
||||
return _conflict("Employee is busy or does not meet the Task requirements.")
|
||||
if not task.reserve(staff_id, [], absolute_minute):
|
||||
return _conflict("Task could not reserve its employee.")
|
||||
if not staff.reserve_task(task_id, absolute_minute):
|
||||
task.reopen(&"ASSIGNMENT_ROLLED_BACK", absolute_minute, true)
|
||||
return _conflict("Employee could not reserve its Task.")
|
||||
task_assigned.emit(task_id, staff_id)
|
||||
return _success({&"task_id": task_id, &"staff_id": staff_id})
|
||||
|
||||
|
||||
func retarget_external_task(task_id: StringName, target_cell: Vector3i, absolute_minute: int) -> CommandResult:
|
||||
var task := get_task(task_id)
|
||||
if task == null or not is_externally_driven_task(task_id) or task.is_terminal():
|
||||
return _conflict("Only an active externally driven Task can be retargeted.")
|
||||
var staff := get_staff(task.assigned_staff_id)
|
||||
if staff == null or staff.current_task_id != task_id:
|
||||
return _conflict("Task and employee ownership differ.")
|
||||
task.target_cell = target_cell
|
||||
task.state = StaffTaskType.State.MOVING
|
||||
task.progress_minutes = 0
|
||||
task.state_changed_at = absolute_minute
|
||||
staff.transition_to(StaffRuntimeType.State.MOVING_TO_TASK, &"TASK_RETARGETED", absolute_minute)
|
||||
return _success({&"task_id": task_id})
|
||||
|
||||
|
||||
func register_staff(value: Variant) -> CommandResult:
|
||||
if value == null or not value is StaffRuntime:
|
||||
return _invalid("Staff runtime is missing or has an invalid type.")
|
||||
@@ -678,8 +722,11 @@ func begin_task(task_id: StringName, absolute_minute: int = -1) -> CommandResult
|
||||
func progress_task(
|
||||
task_id: StringName,
|
||||
minutes: int = 1,
|
||||
absolute_minute: int = -1
|
||||
absolute_minute: int = -1,
|
||||
externally_driven := false
|
||||
) -> CommandResult:
|
||||
if is_externally_driven_task(task_id) and not externally_driven:
|
||||
return _conflict("Task completion belongs to its external operation.")
|
||||
var task := get_task(task_id)
|
||||
if task == null:
|
||||
return _not_found("Task", task_id)
|
||||
@@ -755,6 +802,8 @@ func _advance_assigned_tasks(absolute_minute: int) -> Array[Dictionary]:
|
||||
&"action": &"BEGAN_WORK",
|
||||
})
|
||||
StaffTaskType.State.WORKING:
|
||||
if is_externally_driven_task(task_id):
|
||||
continue
|
||||
var progress_result := progress_task(task.task_id, 1, absolute_minute)
|
||||
if progress_result.is_success():
|
||||
actions.append({
|
||||
@@ -773,8 +822,11 @@ func _advance_assigned_tasks(absolute_minute: int) -> Array[Dictionary]:
|
||||
func cancel_task(
|
||||
task_id: StringName,
|
||||
reason: StringName = &"CANCELLED",
|
||||
absolute_minute: int = -1
|
||||
absolute_minute: int = -1,
|
||||
externally_driven := false
|
||||
) -> CommandResult:
|
||||
if is_externally_driven_task(task_id) and not externally_driven:
|
||||
return _conflict("External operation must release its cargo before cancellation.")
|
||||
var task := get_task(task_id)
|
||||
if task == null:
|
||||
return _not_found("Task", task_id)
|
||||
@@ -801,6 +853,8 @@ func remove_staff(
|
||||
var staff := get_staff(staff_id)
|
||||
if staff == null:
|
||||
return _not_found("Staff", staff_id)
|
||||
if is_externally_driven_task(staff.current_task_id):
|
||||
return _conflict("Finish the employee external operation before removal.")
|
||||
var minute := current_minute if absolute_minute < 0 else absolute_minute
|
||||
if not staff.current_task_id.is_empty():
|
||||
var task := get_task(staff.current_task_id)
|
||||
@@ -842,6 +896,8 @@ func retire_staff(staff_id: StringName, absolute_minute: int = -1) -> CommandRes
|
||||
var staff := get_staff(staff_id)
|
||||
if staff == null:
|
||||
return _not_found("Staff", staff_id)
|
||||
if is_externally_driven_task(staff.current_task_id):
|
||||
return _conflict("Finish the employee external operation before retirement.")
|
||||
staff.is_retiring = true
|
||||
return remove_staff(staff_id, &"RETIRED", true, absolute_minute)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user