#define MIN_LATE_TARGET_TIME 600 //lower bound of re-rolled timer, 1 min
#define MAX_LATE_TARGET_TIME 6000 //upper bound of re-rolled timer, 10 min
#define LATE_TARGET_HIT_CHANCE 70 //How often would the find_target succeed, otherwise it re-rolls later and tries again.
//Hit chance is here to avoid people checking github and then hovering around new arrivals within the max minute range every round.
/datum/objective/assassinate/late
martyr_compatible = FALSE
/datum/objective/assassinate/late/find_target()
var/list/possible_targets = list()
for(var/mob/M in GLOB.latejoiners)
var/datum/mind/possible_target = M.mind
if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != 2) && is_unique_objective(possible_target))
possible_targets += possible_target
if(possible_targets.len > 0 && prob(LATE_TARGET_HIT_CHANCE))
target = pick(possible_targets)
martyr_compatible = TRUE //Might never matter, but I guess if an admin gives another random objective, this should now be compatible
update_explanation_text()
message_admins("[target] has been selected as the assassination target of [owner].")
log_game("[target] has been selected as the assassination target of [owner].")
to_chat(owner, "You hear a crackling noise in your ears, as a one-way syndicate message plays:")
to_chat(owner, "You target has been located. To succeed, find and eliminate [target], the [!target_role_type ? target.assigned_role : target.special_role].")
return target
else
update_explanation_text()
addtimer(CALLBACK(src, .proc/find_target),rand(MIN_LATE_TARGET_TIME, MAX_LATE_TARGET_TIME))
return null
/datum/objective/assassinate/late/find_target_by_role(role, role_type=0, invert=0)
var/list/possible_targets = list()
for(var/mob/M in GLOB.latejoiners)
var/datum/mind/possible_target = M.mind
if((possible_target != owner) && ishuman(possible_target.current))
var/is_role = 0
if(role_type)
if(possible_target.special_role == role)
is_role++
else
if(possible_target.assigned_role == role)
is_role++
if(invert)
if(is_role)
continue
possible_targets += possible_target
//break
else if(is_role)
possible_targets += possible_target
//break
if(possible_targets && prob(LATE_TARGET_HIT_CHANCE))
target = pick(possible_targets)
update_explanation_text()
message_admins("[target] has been selected as the assassination target of [owner].")
log_game("[target] has been selected as the assassination target of [owner].")
to_chat(owner, "You hear a crackling noise in your ears, as a one-way syndicate message plays:")
to_chat(owner, "You target has been located. To succeed, find and eliminate [target], the [!target_role_type ? target.assigned_role : target.special_role].")
else
update_explanation_text()
addtimer(CALLBACK(src, .proc/find_target_by_role, role, role_type, invert),rand(MIN_LATE_TARGET_TIME, MAX_LATE_TARGET_TIME))
/datum/objective/assassinate/late/check_completion()
if(target && target.current) //If target WAS assigned
if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current) || target.current.z > 6 || !target.current.ckey) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite
return TRUE
return FALSE
else //If no target was ever given
if(!owner.current || owner.current.stat == DEAD || isbrain(owner.current))
return FALSE
if(!is_special_character(owner.current))
return FALSE
return TRUE
/datum/objective/assassinate/late/update_explanation_text()
//..()
if(target && target.current)
explanation_text = "Assassinate [target.name], the [!target_role_type ? target.assigned_role : target.special_role]."
else
explanation_text = "Stay alive until your target arrives on the station, you will be notified when the target has been identified."
//BORER STUFF
//Because borers didn't use to have objectives
/datum/objective/normal_borer //Default objective, should technically never be used unmodified but CAN work unmodified.
explanation_text = "You must escape with at least one borer with host on the shuttle."
target_amount = 1
martyr_compatible = 0
/datum/objective/normal_borer/check_completion()
var/total_borer_hosts = 0
for(var/mob/living/carbon/C in GLOB.mob_list)
var/mob/living/simple_animal/borer/D = C.has_brain_worms()
var/turf/location = get_turf(C)
if(location.z == ZLEVEL_CENTCOM && D && D.stat != DEAD)
total_borer_hosts++
if(target_amount <= total_borer_hosts)
return TRUE
else
return FALSE