mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2025-12-20 15:21:29 +00:00
126 lines
4.1 KiB
Plaintext
126 lines
4.1 KiB
Plaintext
/**
|
|
* An objective holder for minds, antag datums, and teams.
|
|
*/
|
|
|
|
/datum/objective_holder
|
|
/// Our list of current objectives
|
|
var/list/datum/objective/objectives = list()
|
|
/// Who do we belong to [mind, antagonist, team]
|
|
var/datum/objective_owner
|
|
/// A list of strings which contain [targets][/datum/objective/var/target] of the antagonist's objectives. Used to prevent duplicate objectives.
|
|
var/list/assigned_targets = list()
|
|
/// A callback invoked when a new objective is added. This is required because sometimes objectives are added directly without going through objective_owner. Not currently used.
|
|
var/datum/callback/on_add_callback
|
|
/// A callback invoked when a new objective is added. This is required because sometimes objectives are removed directly without going through objective_owner (EX: replace_objective(), clear()). Not currently used.
|
|
var/datum/callback/on_remove_callback
|
|
|
|
/datum/objective_holder/New(new_owner)
|
|
. = ..()
|
|
objective_owner = new_owner
|
|
|
|
/datum/objective_holder/Destroy(force, ...)
|
|
clear()
|
|
objective_owner = null
|
|
QDEL_NULL(on_add_callback)
|
|
QDEL_NULL(on_remove_callback)
|
|
return ..()
|
|
|
|
/**
|
|
* Clear all objectives of a certain type
|
|
* * checktype - The type to check, if null, remoe all objectives.
|
|
*/
|
|
/datum/objective_holder/proc/clear(check_type)
|
|
for(var/datum/objective/Objective as anything in objectives)
|
|
if(check_type && !istype(Objective, check_type))
|
|
return
|
|
remove_objective(Objective)
|
|
. = TRUE
|
|
|
|
/**
|
|
* Sets the callbacks, not on new because that can be irreliable for subtypes.
|
|
*/
|
|
/datum/objective_holder/proc/set_callbacks(_on_add_callback, _on_remove_callback)
|
|
on_add_callback = _on_add_callback
|
|
on_remove_callback = _on_remove_callback
|
|
|
|
/**
|
|
* Do we have any objectives
|
|
*/
|
|
/datum/objective_holder/proc/has_objectives()
|
|
return length(objectives) > 0
|
|
|
|
/**
|
|
* Get all of the objectives we own
|
|
*/
|
|
/datum/objective_holder/proc/get_objectives()
|
|
return objectives
|
|
|
|
/**
|
|
* Replace old_objective with new_objective
|
|
*/
|
|
/datum/objective_holder/proc/replace_objective(datum/objective/old_objective, datum/objective/new_objective)
|
|
new_objective = add_objective(new_objective, add_to_list = FALSE)
|
|
new_objective.owner = old_objective.owner
|
|
new_objective.team = old_objective.team
|
|
// Replace where the old objective was, with the new one
|
|
objectives.Insert(objectives.Find(old_objective), new_objective)
|
|
remove_objective(old_objective)
|
|
|
|
/**
|
|
* Add an objective.
|
|
*
|
|
* * Objective - The objective to add [/datum/objective, path]
|
|
* * _explanation_text - Optional, will assign this text to the objective
|
|
* * target_override - A target override, will prevent finding a target
|
|
* * add_to_list - Do we add the new objective to our list? Or will it be handled elsewhere (like replace_objective). Should not be set to false outside of this file.
|
|
*/
|
|
|
|
/datum/objective_holder/proc/add_objective(datum/objective/Objective, _explanation_text, mob/target_override, add_to_list = TRUE)
|
|
if(ispath(Objective))
|
|
Objective = new Objective()
|
|
|
|
Objective.holder = src
|
|
|
|
if(add_to_list)
|
|
objectives += Objective
|
|
|
|
if(target_override)
|
|
Objective.target = target_override
|
|
else if(Objective.needs_target && !Objective.found_target())
|
|
handle_objective(Objective)
|
|
|
|
var/found = Objective.found_target() // in case we are given a target override
|
|
if(found)
|
|
assigned_targets |= found
|
|
|
|
if(_explanation_text)
|
|
Objective.explanation_text = _explanation_text
|
|
|
|
on_add_callback?.Invoke(objective_owner, Objective)
|
|
return Objective
|
|
|
|
/**
|
|
* Handles the searching of targets for objectives that need it.
|
|
*/
|
|
|
|
/datum/objective_holder/proc/handle_objective(datum/objective/Objective)
|
|
for(var/loop in 1 to 5)
|
|
Objective.find_target(assigned_targets)
|
|
if(Objective.found_target()) // handles normal objectives, and steal objectives
|
|
return
|
|
|
|
// We failed to find any target. Oh well...
|
|
Objective.explanation_text = "Free Objective"
|
|
Objective.target = null
|
|
|
|
/**
|
|
* Remove an objective and deletes it. You should never need to transfer an objective.
|
|
*/
|
|
/datum/objective_holder/proc/remove_objective(datum/objective/Objective)
|
|
objectives -= Objective
|
|
assigned_targets -= Objective.found_target()
|
|
|
|
on_remove_callback?.Invoke(objective_owner, Objective)
|
|
if(!QDELETED(Objective))
|
|
qdel(Objective)
|