diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 6eb6d523cdc..868cb3b3da4 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -706,12 +706,6 @@ return switch(new_obj_type) - if("download") - new_objective = new /datum/objective/download - new_objective.explanation_text = "Download [target_number] research levels." - if("capture") - new_objective = new /datum/objective/capture - new_objective.explanation_text = "Accumulate [target_number] capture points." if("absorb") new_objective = new /datum/objective/absorb new_objective.explanation_text = "Absorb [target_number] compatible genomes." diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm index aa498e817f7..04f9738745d 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction.dm @@ -50,7 +50,7 @@ team_names[team_number] = "Mothership [pick(GLOB.possible_changeling_IDs)]" //TODO Ensure unique and actual alieny names //Team Objective var/datum/objective/experiment/team_objective = new - team_objective.team = team_number + team_objective.abductor_team = team_number team_objectives[team_number] = team_objective //Team Members @@ -238,7 +238,7 @@ // OBJECTIVES /datum/objective/experiment target_amount = 6 - var/team + var/abductor_team /datum/objective/stay_hidden @@ -251,13 +251,12 @@ explanation_text = "Experiment on [target_amount] humans." /datum/objective/experiment/check_completion() - var/ab_team = team - if(owner) - if(!owner.current || !ishuman(owner.current)) - return FALSE - var/mob/living/carbon/human/H = owner.current - if(!isabductor(H)) + var/ab_team = abductor_team + var/list/owners = get_owners() + for(var/datum/mind/M in owners) + if(!M.current || !ishuman(M.current) || !isabductor(M.current)) return FALSE + var/mob/living/carbon/human/H = M.current var/datum/species/abductor/S = H.dna.species ab_team = S.team for(var/obj/machinery/abductor/experiment/E in GLOB.machines) diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index 1f6ee4b1fd3..e576920c2a2 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -322,15 +322,15 @@ ..() /datum/objective/revenant/check_completion() - if(!owner || !istype(owner.current, /mob/living/simple_animal/revenant)) - return 0 - var/mob/living/simple_animal/revenant/R = owner.current - if(!R || R.stat == DEAD) - return 0 - var/essence_stolen = R.essence_accumulated - if(essence_stolen < targetAmount) - return 0 - return 1 + var/total_essence = 0 + for(var/datum/mind/M in get_owners()) + if(!istype(M.current, /mob/living/simple_animal/revenant) || QDELETED(M.current)) + continue + var/mob/living/simple_animal/revenant/R = M.current + total_essence += R.essence_accumulated + if(total_essence >= targetAmount) + return FALSE + return TRUE /datum/objective/revenantFluff diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm index 962d44076bd..795e49ebe1f 100644 --- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm +++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm @@ -344,15 +344,15 @@ ..() /datum/objective/slaughter/check_completion() - if(!isslaughterdemon(owner.current) || !owner.current) - return 0 - var/mob/living/simple_animal/slaughter/R = owner.current - if(!R || R.stat == DEAD) - return 0 - var/deathCount = R.devoured - if(deathCount < targetKill) - return 0 - return 1 + var/kill_count = 0 + for(var/datum/mind/M in get_owners()) + if(!isslaughterdemon(M.current) || QDELETED(M.current)) + continue + var/mob/living/simple_animal/slaughter/R = M.current + kill_count += R.devoured + if(kill_count >= targetKill) + return TRUE + return FALSE /datum/objective/demonFluff diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 85a3a4461e6..20d8d8463f9 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -3,14 +3,20 @@ GLOBAL_LIST_EMPTY(all_objectives) GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) - /datum/theft_objective/steal - /datum/theft_objective/number - /datum/theft_objective/unique)) /datum/objective - /// Mind who owns the objective. - var/datum/mind/owner = null + /** + * Owner of the objective. + * Note that it's fine to set this directly, but when needing to check completion of the objective or otherwise check conditions on the owner of the objective, + * always use `get_owners()`, and check against ALL the owners. `get_owners()` accounts for objectives that may be team based and therefore have multiple owners. + */ + var/datum/mind/owner + /// The target of the objective. + var/datum/mind/target + /// The team the objective belongs to, if any. + var/datum/team/team /// What the owner is supposed to do to complete the objective. var/explanation_text = "Nothing" /// If the objective should have `find_target()` called for it. var/needs_target = TRUE - /// The target of the objective. - var/datum/mind/target = null /// If they are focused on a particular number. Steal objectives have their own counter. var/target_amount = 0 /// If the objective has been completed. @@ -18,18 +24,33 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /// If the objective is compatible with martyr objective, i.e. if you can still do it while dead. var/martyr_compatible = FALSE -/datum/objective/New(text) +/datum/objective/New(text, datum/team/team_to_join) GLOB.all_objectives += src if(text) explanation_text = text + if(team_to_join) + team = team_to_join /datum/objective/Destroy() GLOB.all_objectives -= src + owner = null + target = null + team = null return ..() /datum/objective/proc/check_completion() return completed +/** + * Get all owners of the objective, including ones from the objective's team, if it has one. + * + * Use this over directly referencing `owner` in most cases. + */ +/datum/objective/proc/get_owners() + . = length(team?.members) ? team.members.Copy() : list() + if(owner) + . += owner + /datum/proc/is_invalid_target(datum/mind/possible_target) // Originally an Objective proc. Changed to a datum proc to allow for the proc to be run on minds, before the objective is created if(!ishuman(possible_target.current)) return TARGET_INVALID_NOT_HUMAN @@ -47,10 +68,11 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) return TARGET_INVALID_EVENT /datum/objective/is_invalid_target(datum/mind/possible_target) - if(possible_target == owner) - return TARGET_INVALID_IS_OWNER - if(possible_target in owner.targets) - return TARGET_INVALID_IS_TARGET + for(var/datum/mind/M in get_owners()) + if(possible_target == M) + return TARGET_INVALID_IS_OWNER + if(possible_target in M.targets) + return TARGET_INVALID_IS_TARGET return ..() @@ -72,22 +94,25 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) * Called when the objective's target goes to cryo. */ /datum/objective/proc/on_target_cryo() - if(owner?.current) - to_chat(owner.current, "
You get the feeling your target is no longer within reach. Time for Plan [pick("A","B","C","D","X","Y","Z")]. Objectives updated!") - SEND_SOUND(owner.current, sound('sound/ambience/alarm4.ogg')) + var/list/owners = get_owners() + for(var/datum/mind/M in owners) + to_chat(M.current, "
You get the feeling your target is no longer within reach. Time for Plan [pick("A","B","C","D","X","Y","Z")]. Objectives updated!") + SEND_SOUND(M.current, sound('sound/ambience/alarm4.ogg')) target = null - INVOKE_ASYNC(src, PROC_REF(post_target_cryo)) + INVOKE_ASYNC(src, PROC_REF(post_target_cryo), owners) /** * Called a tick after when the objective's target goes to cryo. */ -/datum/objective/proc/post_target_cryo() +/datum/objective/proc/post_target_cryo(list/owners) find_target() if(!target) + for(var/datum/mind/M in owners) + M.remove_objective(src) GLOB.all_objectives -= src - owner?.objectives -= src qdel(src) - owner?.announce_objectives() + for(var/datum/mind/M in owners) + M.announce_objectives() /datum/objective/assassinate martyr_compatible = 1 @@ -103,13 +128,13 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/assassinate/check_completion() if(target && target.current) if(target.current.stat == DEAD) - return 1 + return TRUE if(issilicon(target.current) || isbrain(target.current)) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite - return 1 + return TRUE if(!target.current.ckey) - return 1 - return 0 - return 1 + return TRUE + return FALSE + return TRUE /datum/objective/mutiny @@ -126,12 +151,12 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/mutiny/check_completion() if(target && target.current) if(target.current.stat == DEAD || !ishuman(target.current) || !target.current.ckey || !target.current.client) - return 1 + return TRUE var/turf/T = get_turf(target.current) if(T && !is_station_level(T.z)) //If they leave the station they count as dead for this - return 1 - return 0 - return 1 + return TRUE + return FALSE + return TRUE /datum/objective/mutiny/on_target_cryo() // We don't want revs to get objectives that aren't for heads of staff. Letting @@ -152,18 +177,18 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/maroon/check_completion() if(target && target.current) if(target.current.stat == DEAD) - return 1 + return TRUE if(!target.current.ckey) - return 1 + return TRUE if(issilicon(target.current)) - return 1 + return TRUE if(isbrain(target.current)) - return 1 + return TRUE var/turf/T = get_turf(target.current) if(is_admin_level(T.z)) - return 0 - return 1 - return 1 + return FALSE + return TRUE + return TRUE /datum/objective/debrain //I want braaaainssss @@ -179,18 +204,16 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/debrain/check_completion() - if(!target)//If it's a free objective. - return 1 - if(!owner.current || owner.current.stat == DEAD) - return 0 + if(!target) // If it's a free objective. + return TRUE if(!target.current || !isbrain(target.current)) - return 0 - var/atom/A = target.current - while(A.loc) //check to see if the brainmob is on our person - A = A.loc - if(A == owner.current) - return 1 - return 0 + return FALSE + for(var/datum/mind/M in get_owners()) + if(QDELETED(M.current) || M.current.stat == DEAD) + continue // Maybe someone who's alive has the brain. + if(target.current in M.current.GetAllContents()) + return TRUE + return FALSE /datum/objective/protect //The opposite of killing a dude. @@ -206,20 +229,21 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/protect/check_completion() if(!target) //If it's a free objective. - return 1 + return TRUE if(target.current) if(target.current.stat == DEAD) - return 0 + return FALSE if(issilicon(target.current)) - return 0 + return FALSE if(isbrain(target.current)) - return 0 - return 1 - return 0 + return FALSE + return TRUE + return FALSE /datum/objective/protect/mindslave //subytpe for mindslave implants needs_target = FALSE // To be clear, this objective should have a target, but it will always be manually set to the mindslaver through the mindslave antag datum. +// This objective should only be given to a single owner. We can use `owner` and not `get_owners()`. /datum/objective/protect/mindslave/on_target_cryo() if(owner?.current) SEND_SOUND(owner.current, sound('sound/ambience/alarm4.ogg')) @@ -237,17 +261,11 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) needs_target = FALSE /datum/objective/hijack/check_completion() - if(!owner.current || owner.current.stat) - return 0 if(SSshuttle.emergency.mode < SHUTTLE_ENDGAME) - return 0 - if(issilicon(owner.current)) - return 0 - - var/area/A = get_area(owner.current) - if(SSshuttle.emergency.areaInstance != A) - return 0 - + return FALSE + for(var/datum/mind/M in get_owners()) + if(QDELETED(M.current) || M.current.stat != CONSCIOUS || issilicon(M.current) || get_area(M.current) != SSshuttle.emergency.areaInstance) + return FALSE return SSshuttle.emergency.is_hijacked() /datum/objective/hijackclone @@ -255,11 +273,11 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) martyr_compatible = 0 needs_target = FALSE +// This objective should only be given to a single owner, because the "copies" can only copy one person. +// We're fine to use `owner` instead of `get_owners()`. /datum/objective/hijackclone/check_completion() - if(!owner.current) - return 0 - if(SSshuttle.emergency.mode < SHUTTLE_ENDGAME) - return 0 + if(SSshuttle.emergency.mode < SHUTTLE_ENDGAME || !owner.current) + return FALSE var/area/A = SSshuttle.emergency.areaInstance @@ -270,7 +288,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) continue if(get_area(player) == A) if(player.real_name != owner.current.real_name && !istype(get_turf(player.mind.current), /turf/simulated/floor/mineral/plastitanium/red/brig)) - return 0 + return FALSE for(var/mob/living/player in GLOB.player_list) //Make sure at least one of you is onboard if(player.mind && player.mind != owner) @@ -279,8 +297,8 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) continue if(get_area(player) == A) if(player.real_name == owner.current.real_name && !istype(get_turf(player.mind.current), /turf/simulated/floor/mineral/plastitanium/red/brig)) - return 1 - return 0 + return TRUE + return FALSE /datum/objective/block explanation_text = "Hijack the shuttle with no loyalist Nanotrasen crew on board and free. \ @@ -290,17 +308,15 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) needs_target = FALSE /datum/objective/block/check_completion() - if(!issilicon(owner.current)) - return FALSE + for(var/datum/mind/M in get_owners()) + if(!M.current || !issilicon(M.current)) + return FALSE if(SSticker.mode.station_was_nuked) return TRUE if(SSshuttle.emergency.mode < SHUTTLE_ENDGAME) return FALSE - if(!owner.current) - return FALSE if(!SSshuttle.emergency.is_hijacked(TRUE)) return FALSE - return TRUE /datum/objective/escape @@ -308,29 +324,27 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) needs_target = FALSE /datum/objective/escape/check_completion() - if(issilicon(owner.current)) - return 0 - if(isbrain(owner.current)) - return 0 - if(!owner.current || owner.current.stat == DEAD) - return 0 - if(SSticker.force_ending) //This one isn't their fault, so lets just assume good faith - return 1 - if(SSticker.mode.station_was_nuked) //If they escaped the blast somehow, let them win - return 1 + var/list/owners = get_owners() + for(var/datum/mind/M in owners) + // These are mandatory conditions, they should come before the freebie conditions below. + if(QDELETED(M.current) || M.current.stat == DEAD || issilicon(M.current) || isbrain(M.current)) + return FALSE + + if(SSticker.force_ending) // This one isn't their fault, so lets just assume good faith. + return TRUE + if(SSticker.mode.station_was_nuked) // If they escaped the blast somehow, let them win. + return TRUE if(SSshuttle.emergency.mode < SHUTTLE_ENDGAME) - return 0 - var/turf/location = get_turf(owner.current) - if(!location) - return 0 + return FALSE - if(istype(location, /turf/simulated/floor/mineral/plastitanium/red/brig)) // Fails traitors if they are in the shuttle brig -- Polymorph - return 0 + for(var/datum/mind/M in owners) + var/turf/location = get_turf(M.current) + if(istype(location, /turf/simulated/floor/mineral/plastitanium/red/brig)) + return FALSE + if(!location.onCentcom() && !location.onSyndieBase()) + return FALSE - if(location.onCentcom() || location.onSyndieBase()) - return 1 - - return 0 + return TRUE /datum/objective/escape/escape_with_identity @@ -351,28 +365,32 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) else explanation_text = "Free Objective" +// This objective should only be given to a single owner since only 1 person can have the ID card of the target. +// We're fine to use `owner` instead of `get_owners()`. /datum/objective/escape/escape_with_identity/check_completion() if(!target_real_name) - return 1 + return TRUE if(!ishuman(owner.current)) - return 0 + return FALSE var/mob/living/carbon/human/H = owner.current if(..()) if(H.dna.real_name == target_real_name) - if(H.get_id_name()== target_real_name) - return 1 - return 0 + if(H.get_id_name() == target_real_name) + return TRUE + return FALSE /datum/objective/die explanation_text = "Die a glorious death." needs_target = FALSE /datum/objective/die/check_completion() - if(!owner.current || owner.current.stat == DEAD || isbrain(owner.current)) - return 1 - if(issilicon(owner.current) && !owner.is_original_mob(owner.current)) - return 1 - return 0 + for(var/datum/mind/M in get_owners()) + if(QDELETED(M.current) || M.current.stat == DEAD || isbrain(M.current)) + continue + if(issilicon(M.current) && !M.is_original_mob(M.current)) + continue + return FALSE // Some owner didn't meet the above criteria. + return TRUE @@ -381,11 +399,12 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) needs_target = FALSE /datum/objective/survive/check_completion() - if(!owner.current || owner.current.stat == DEAD || isbrain(owner.current)) - return 0 //Brains no longer win survive objectives. --NEO - if(issilicon(owner.current) && !owner.is_original_mob(owner.current)) - return 0 - return 1 + for(var/datum/mind/M in get_owners()) + if(QDELETED(M.current) || M.current.stat == DEAD || isbrain(M.current)) + return FALSE + if(issilicon(M.current) && !M.is_original_mob(M.current)) + return FALSE + return TRUE /datum/objective/nuclear explanation_text = "Destroy the station with a nuclear device." @@ -405,9 +424,12 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) while(!steal_target && length(potential)) var/thefttype = pick_n_take(potential) var/datum/theft_objective/O = new thefttype - if(owner.assigned_role in O.protected_jobs) - continue - if(O in owner.targets) + var/has_invalid_owner = FALSE + for(var/datum/mind/M in get_owners()) + if((M.assigned_role in O.protected_jobs) || (O in M.targets)) + has_invalid_owner = TRUE + break + if(has_invalid_owner) continue if(O.flags & 2) // THEFT_FLAG_UNIQUE continue @@ -445,21 +467,17 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/steal/check_completion() if(!steal_target) - return 1 // Free Objective + return TRUE // Free Objective - if(!owner.current) - return FALSE - - var/list/all_items = owner.current.GetAllContents() - - for(var/obj/I in all_items) - if(istype(I, steal_target.typepath)) - return steal_target.check_special_completion(I) - if(I.type in steal_target.altitems) - return steal_target.check_special_completion(I) + for(var/datum/mind/M in get_owners()) + if(!M.current) + continue + for(var/obj/I in M.current.GetAllContents()) + if((istype(I, steal_target.typepath) || (I.type in steal_target.altitems)) && steal_target.check_special_completion(I)) + return TRUE + return FALSE /datum/objective/steal/proc/give_kit(obj/item/item_path) - var/mob/living/carbon/human/mob = owner.current var/I = new item_path var/list/slots = list( "backpack" = slot_in_backpack, @@ -468,65 +486,15 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) "left hand" = slot_l_hand, "right hand" = slot_r_hand, ) - var/where = mob.equip_in_one_of_slots(I, slots) - if(where) - to_chat(mob, "

In your [where] is a box containing items and instructions to help you with your steal objective.
") - else - to_chat(mob, "Unfortunately, you weren't able to get a stealing kit. This is very bad and you should adminhelp immediately (press F1).") - message_admins("[ADMIN_LOOKUPFLW(mob)] Failed to spawn with their [item_path] theft kit.") - qdel(I) - -/datum/objective/steal/exchange - martyr_compatible = 0 - needs_target = FALSE - -/datum/objective/steal/exchange/proc/set_faction(faction, otheragent) - target = otheragent - var/datum/theft_objective/unique/targetinfo - if(faction == "red") - targetinfo = new /datum/theft_objective/unique/docs_blue - else if(faction == "blue") - targetinfo = new /datum/theft_objective/unique/docs_red - explanation_text = "Acquire [targetinfo.name] held by [target.current.real_name], the [target.assigned_role] and syndicate agent" - steal_target = targetinfo - -/datum/objective/steal/exchange/backstab -/datum/objective/steal/exchange/backstab/set_faction(faction) - var/datum/theft_objective/unique/targetinfo - if(faction == "red") - targetinfo = new /datum/theft_objective/unique/docs_red - else if(faction == "blue") - targetinfo = new /datum/theft_objective/unique/docs_blue - explanation_text = "Do not give up or lose [targetinfo.name]." - steal_target = targetinfo - -/datum/objective/download - needs_target = FALSE - -/datum/objective/download/proc/gen_amount_goal() - target_amount = rand(10,20) - explanation_text = "Download [target_amount] research levels." - return target_amount - - -/datum/objective/download/check_completion() - return 0 - - - -/datum/objective/capture - needs_target = FALSE - -/datum/objective/capture/proc/gen_amount_goal() - target_amount = rand(5,10) - explanation_text = "Accumulate [target_amount] capture points." - return target_amount - - -/datum/objective/capture/check_completion()//Basically runs through all the mobs in the area to determine how much they are worth. - return 0 - - + for(var/datum/mind/M in get_owners()) + var/mob/living/carbon/human/H = M.current + var/where = H.equip_in_one_of_slots(I, slots) + if(where) + to_chat(H, "

In your [where] is a box containing items and instructions to help you with your steal objective.
") + else + to_chat(H, "Unfortunately, you weren't able to get a stealing kit. This is very bad and you should adminhelp immediately (press F1).") + message_admins("[ADMIN_LOOKUPFLW(H)] Failed to spawn with their [item_path] theft kit.") + qdel(I) /datum/objective/absorb @@ -538,7 +506,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) var/n_p = 1 //autowin if(SSticker.current_state == GAME_STATE_SETTING_UP) for(var/mob/new_player/P in GLOB.player_list) - if(P.client && P.ready && P.mind != owner) + if(P.client && P.ready && !(P.mind in get_owners())) if(P.client.prefs && (P.client.prefs.active_character.species == "Machine")) // Special check for species that can't be absorbed. No better solution. continue n_p++ @@ -546,7 +514,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) for(var/mob/living/carbon/human/P in GLOB.player_list) if(HAS_TRAIT(P, TRAIT_GENELESS)) continue - if(P.client && !(P.mind in SSticker.mode.changelings) && P.mind!=owner) + if(P.client && !(P.mind in SSticker.mode.changelings) && !(P.mind in get_owners())) n_p++ target_amount = min(target_amount, n_p) @@ -554,9 +522,10 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) return target_amount /datum/objective/absorb/check_completion() - var/datum/antagonist/changeling/cling = owner?.has_antag_datum(/datum/antagonist/changeling) - if(cling?.absorbed_dna && (cling.absorbed_count >= target_amount)) - return TRUE + for(var/datum/mind/M in get_owners()) + var/datum/antagonist/changeling/cling = M?.has_antag_datum(/datum/antagonist/changeling) + if(cling?.absorbed_dna && (cling.absorbed_count >= target_amount)) + return TRUE return FALSE /datum/objective/destroy @@ -577,9 +546,9 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/destroy/check_completion() if(target && target.current) if(target.current.stat == DEAD || is_away_level(target.current.z) || !target.current.ckey) - return 1 - return 0 - return 1 + return TRUE + return FALSE + return TRUE /datum/objective/steal_five_of_type explanation_text = "Steal at least five items!" @@ -592,9 +561,12 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/steal_five_of_type/check_completion() var/stolen_count = 0 - if(!isliving(owner.current)) - return FALSE - var/list/all_items = owner.current.GetAllContents() //this should get things in cheesewheels, books, etc. + var/list/owners = get_owners() + var/list/all_items = list() + for(var/datum/mind/M in owners) + if(!isliving(M.current)) + continue + all_items += M.current.GetAllContents() //this should get things in cheesewheels, books, etc. for(var/obj/I in all_items) //Check for wanted items if(is_type_in_typecache(I, wanted_items)) stolen_count++ @@ -614,9 +586,12 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/steal_five_of_type/summon_magic/check_completion() var/stolen_count = 0 - if(!isliving(owner.current)) - return FALSE - var/list/all_items = owner.current.GetAllContents() //this should get things in cheesewheels, books, etc. + var/list/owners = get_owners() + var/list/all_items = list() + for(var/datum/mind/M in owners) + if(!isliving(M.current)) + continue + all_items += M.current.GetAllContents() //this should get things in cheesewheels, books, etc. for(var/obj/I in all_items) //Check for wanted items if(istype(I, /obj/item/spellbook) && !istype(I, /obj/item/spellbook/oneuse)) var/obj/item/spellbook/spellbook = I @@ -644,11 +619,12 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) return target_amount /datum/objective/blood/check_completion() - var/datum/antagonist/vampire/V = owner.has_antag_datum(/datum/antagonist/vampire) - if(V.bloodtotal >= target_amount) - return TRUE - else - return FALSE + for(var/datum/mind/M in get_owners()) + var/datum/antagonist/vampire/V = M.has_antag_datum(/datum/antagonist/vampire) + if(V.bloodtotal >= target_amount) + return TRUE + else + return FALSE // Traders