diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 80a1b2c8489..b902f712153 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1116,7 +1116,6 @@ switch(href_list["traitor"]) if("clear") if(has_antag_datum(/datum/antagonist/traitor)) - to_chat(current, "You have been brainwashed! You are no longer a traitor!") remove_antag_datum(/datum/antagonist/traitor) log_admin("[key_name(usr)] has de-traitored [key_name(current)]") message_admins("[key_name_admin(usr)] has de-traitored [key_name_admin(current)]") @@ -1464,9 +1463,14 @@ edit_memory() - -// Datum antag mind procs -/datum/mind/proc/add_antag_datum(datum_type_or_instance, team) +/** + * Create and/or add the `datum_type_or_instance` antag datum to the src mind. + * + * Arguments: + * * datum_type - an antag datum typepath or instance + * * datum/team/team - the antag team that the src mind should join, if any + */ +/datum/mind/proc/add_antag_datum(datum_type_or_instance, datum/team/team = null) if(!datum_type_or_instance) return var/datum/antagonist/A @@ -1476,11 +1480,6 @@ return else A = new datum_type_or_instance() - //Choose snowflake variation if antagonist handles it - var/datum/antagonist/S = A.specialization(src) - if(S && S != A) - qdel(A) - A = S if(!A.can_be_owned(src)) qdel(A) return @@ -1494,25 +1493,33 @@ A.on_gain() return A +/** + * Remove the specified `datum_type` antag datum from the src mind. + * + * Arguments: + * * datum_type - an antag datum typepath + */ /datum/mind/proc/remove_antag_datum(datum_type) if(!datum_type) return var/datum/antagonist/A = has_antag_datum(datum_type) - if(A) - if(!A.owner?.current) - CRASH("attempted to remove an antag datum ([A.type]) that didn't have an owner or owner.current") - A.on_removal() - return TRUE - + qdel(A) +/** + * Removes all antag datums from the src mind. + */ /datum/mind/proc/remove_all_antag_datums() //For the Lazy amongst us. for(var/a in antag_datums) var/datum/antagonist/A = a - if(!A.owner?.current) - stack_trace("attempted to remove an antag datum ([A.type]) that didn't have an owner or owner.current") - continue - A.on_removal() + qdel(A) +/** + * Returns an antag datum instance if the src mind has the specified `datum_type`. Returns `null` otherwise. + * + * Arguments: + * * datum_type - an antag datum typepath + * * check_subtypes - TRUE if this proc will consider subtypes of `datum_type` as valid. FALSE if only the exact same type should be considered. + */ /datum/mind/proc/has_antag_datum(datum_type, check_subtypes = TRUE) if(!datum_type) return diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 18cb6cfd9e2..b82e4c4db95 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -3,12 +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 - var/datum/mind/owner = null //Who owns the objective. - var/explanation_text = "Nothing" //What that person is supposed to do. - var/datum/mind/target = null //If they are focused on a particular person. - var/target_amount = 0 //If they are focused on a particular number. Steal objectives have their own counter. - var/completed = 0 //currently only used for custom objectives. - var/martyr_compatible = 0 //If the objective is compatible with martyr objective, i.e. if you can still do it while dead. + /// Mind who owns the objective. + var/datum/mind/owner = null + /// 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. + var/completed = FALSE + /// 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) GLOB.all_objectives += src @@ -44,6 +52,9 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/proc/find_target() + if(!needs_target) + return + var/list/possible_targets = list() for(var/datum/mind/possible_target in SSticker.minds) if(is_invalid_target(possible_target)) @@ -204,13 +215,13 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) return 0 /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. /datum/objective/protect/mindslave/on_target_cryo() if(owner?.current) - to_chat(owner.current, "
You notice that your master has entered cryogenic storage, and revert to your normal self, until they return again. You are no longer a mindslave!") SEND_SOUND(owner.current, sound('sound/ambience/alarm4.ogg')) owner.remove_antag_datum(/datum/antagonist/mindslave) - SSticker.mode.implanted.Remove(owner) + to_chat(owner.current, "
You notice that your master has entered cryogenic storage, and revert to your normal self.") log_admin("[key_name(owner.current)]'s mindslave master has cryo'd, and is no longer a mindslave.") message_admins("[key_name_admin(owner.current)]'s mindslave master has cryo'd, and is no longer a mindslave.") //Since they were on antag hud earlier, this feels important to log qdel(src) @@ -219,6 +230,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) martyr_compatible = 0 //Technically you won't get both anyway. explanation_text = "Hijack the shuttle by escaping on it with no loyalist Nanotrasen crew on board and free. \ Syndicate agents, other enemies of Nanotrasen, cyborgs, pets, and cuffed/restrained hostages may be allowed on the shuttle alive." + needs_target = FALSE /datum/objective/hijack/check_completion() if(!owner.current || owner.current.stat) @@ -237,6 +249,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/hijackclone explanation_text = "Hijack the shuttle by ensuring only you (or your copies) escape." martyr_compatible = 0 + needs_target = FALSE /datum/objective/hijackclone/check_completion() if(!owner.current) @@ -268,6 +281,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/block explanation_text = "Do not allow any lifeforms, be it organic or synthetic to escape on the shuttle alive. AIs, Cyborgs, Maintenance drones, and pAIs are not considered alive." martyr_compatible = 1 + needs_target = FALSE /datum/objective/block/check_completion() if(!istype(owner.current, /mob/living/silicon)) @@ -293,6 +307,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/escape explanation_text = "Escape on the shuttle or an escape pod alive and free." + needs_target = FALSE /datum/objective/escape/check_completion() if(issilicon(owner.current)) @@ -352,6 +367,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /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)) @@ -364,6 +380,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/survive explanation_text = "Stay alive until the end." + needs_target = FALSE /datum/objective/survive/check_completion() if(!owner.current || owner.current.stat == DEAD || isbrain(owner.current)) @@ -375,6 +392,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/nuclear explanation_text = "Destroy the station with a nuclear device." martyr_compatible = 1 + needs_target = FALSE /datum/objective/steal var/datum/theft_objective/steal_target @@ -462,6 +480,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/steal/exchange martyr_compatible = 0 + needs_target = FALSE /datum/objective/steal/exchange/proc/set_faction(faction, otheragent) target = otheragent @@ -484,6 +503,8 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) 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." @@ -496,6 +517,8 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /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." @@ -509,6 +532,8 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/absorb + needs_target = FALSE + /datum/objective/absorb/proc/gen_amount_goal(lowbound = 4, highbound = 6) target_amount = rand (lowbound,highbound) if(SSticker) @@ -560,6 +585,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/steal_five_of_type explanation_text = "Steal at least five items!" + needs_target = FALSE var/list/wanted_items = list() /datum/objective/steal_five_of_type/New() @@ -607,6 +633,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) return stolen_count >= 5 /datum/objective/blood + needs_target = FALSE /datum/objective/blood/New() gen_amount_goal() @@ -642,4 +669,5 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/wizchaos explanation_text = "Wreak havoc upon the station as much you can. Send those wandless Nanotrasen scum a message!" + needs_target = FALSE completed = 1 diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm index 02e113ba24e..88b42361126 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -11,8 +11,8 @@ GLOBAL_LIST_EMPTY(antagonists) var/datum/mind/owner /// Should the owner mob get a greeting text? Determines whether or not the `greet()` proc is called. var/silent = FALSE - /// List of antagonist datums that this type can't coexist with. - var/list/typecache_datum_blacklist + /// List of other antag datum types that this type can't coexist with. + var/list/antag_datum_blacklist /// Should this datum be deleted when the owner's mind is deleted. var/delete_on_mind_deletion = TRUE /// Used to determine if the player jobbanned from this role. Things like `SPECIAL_ROLE_TRAITOR` should go here to determine the role. @@ -44,13 +44,19 @@ GLOBAL_LIST_EMPTY(antagonists) GLOB.antagonists += src objectives = list() assigned_targets = list() - typecache_datum_blacklist = typecacheof(typecache_datum_blacklist) -/datum/antagonist/Destroy() +/datum/antagonist/Destroy(force, ...) QDEL_LIST(objectives) GLOB.antagonists -= src + if(!silent) + farewell() + remove_innate_effects() + antag_memory = null + var/datum/team/team = get_team() + team?.remove_member(owner) if(owner) LAZYREMOVE(owner.antag_datums, src) + restore_last_hud_and_role() owner = null return ..() @@ -65,18 +71,10 @@ GLOBAL_LIST_EMPTY(antagonists) return FALSE for(var/i in tested.antag_datums) var/datum/antagonist/A = i - if(is_type_in_typecache(src, A.typecache_datum_blacklist)) + if(LAZYIN(A.antag_datum_blacklist, type)) return FALSE return TRUE -/** - * This will be called in `add_antag_datum` before owner assignment. - * - * Should return antagonist datum without owner. - */ -/datum/antagonist/proc/specialization(datum/mind/new_owner) - return src - /** * Removes antagonist datum effects from the old body and applies it to the new one. * @@ -97,14 +95,16 @@ GLOBAL_LIST_EMPTY(antagonists) * If they're a clown, removes their clumsy mutataion. * * Arguments: - * * new_body - the new body that the antag mob is transferring into. + * * mob/living/mob_override - a mob to apply effects to. Can be null. */ -/datum/antagonist/proc/apply_innate_effects(mob/living/new_body) - var/mob/living/L = new_body || owner.current +/datum/antagonist/proc/apply_innate_effects(mob/living/mob_override) + SHOULD_CALL_PARENT(TRUE) + var/mob/living/L = mob_override || owner.current if(antag_hud_type && antag_hud_name) add_antag_hud(L) - // If `new_body` exists it means we're only transferring this datum, we don't need to show the clown any text. - handle_clown_mutation(L, new_body ? null : clown_gain_text, TRUE) + // If `mob_override` exists it means we're only transferring this datum, we don't need to show the clown any text. + handle_clown_mutation(L, mob_override ? null : clown_gain_text, TRUE) + return L /** * This handles the removal of antag huds/special abilities. @@ -113,14 +113,16 @@ GLOBAL_LIST_EMPTY(antagonists) * If they're a clown, gives them back their clumsy mutataion. * * Arguments: - * * old_body - the old body the antag is leaving behind. + * * mob/living/mob_override - a mob to remove effects from. Can be null. */ -/datum/antagonist/proc/remove_innate_effects(mob/living/old_body) - var/mob/living/L = old_body || owner.current +/datum/antagonist/proc/remove_innate_effects(mob/living/mob_override) + SHOULD_CALL_PARENT(TRUE) + var/mob/living/L = mob_override || owner.current if(antag_hud_type && antag_hud_name) remove_antag_hud(L) - // If `old_body` exists it means we're only transferring this datum, we don't need to show the clown any text. - handle_clown_mutation(L, old_body ? null : clown_removal_text) + // If `mob_override` exists it means we're only transferring this datum, we don't need to show the clown any text. + handle_clown_mutation(L, mob_override ? null : clown_removal_text) + return L /** * Adds this datum's antag hud to `antag_mob`. @@ -184,8 +186,6 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/proc/give_objectives() return -#define NO_TARGET_OBJECTIVES list(/datum/objective/escape, /datum/objective/hijack, /datum/objective/survive, /datum/objective/block, /datum/objective/die) - /** * Create and add an objective of the given type. * @@ -194,13 +194,20 @@ GLOBAL_LIST_EMPTY(antagonists) * * Arguments: * * objective_type - A type path of an objective, for example: /datum/objective/steal + * * explanation_text - the explanation text that will be passed into the objective's `New()` proc + * * mob/target_override - a target for the objective */ -/datum/antagonist/proc/add_objective(objective_type) - var/datum/objective/O = new objective_type +/datum/antagonist/proc/add_objective(objective_type, explanation_text = "", mob/target_override = null) + var/datum/objective/O = new objective_type(explanation_text) O.owner = owner - if(is_type_in_list(O, NO_TARGET_OBJECTIVES)) - objectives += O // No need to find a target, just add the objective and return. + if(target_override) + O.target = target_override + objectives += O + return + + if(!O.needs_target) + objectives += O return O.find_target() @@ -230,8 +237,6 @@ GLOBAL_LIST_EMPTY(antagonists) objectives += O -#undef NO_TARGET_OBJECTIVES - /** * Announces all objectives of this datum, and only this datum. */ @@ -263,22 +268,6 @@ GLOBAL_LIST_EMPTY(antagonists) INVOKE_ASYNC(src, .proc/replace_banned_player) return TRUE -/** - * Called when `remove_antag_datum()` is called on the owner's mind. - * - * Removes all effects this datum granted and deletes itself afterwards. - */ -/datum/antagonist/proc/on_removal() - if(!silent) - farewell() - remove_innate_effects() - antag_memory = null - var/datum/team/team = get_team() - team?.remove_member(owner) - LAZYREMOVE(owner.antag_datums, src) - restore_last_hud_and_role() - qdel(src) - /** * Re-sets the antag hud and `special_role` of the owner to that of the previous antag datum they had before this one was added. * diff --git a/code/modules/antagonists/survivalist/survivalist.dm b/code/modules/antagonists/survivalist/survivalist.dm index 1d30a6fe334..0bda6e5606f 100644 --- a/code/modules/antagonists/survivalist/survivalist.dm +++ b/code/modules/antagonists/survivalist/survivalist.dm @@ -1,41 +1,26 @@ /datum/antagonist/survivalist name = "Survivalist" + special_role = "Survivalist" var/greet_message = "" -/datum/antagonist/survivalist/proc/forge_objectives() - var/datum/objective/survive/survive = new - survive.owner = owner - objectives += survive - owner.objectives |= objectives - -/datum/antagonist/survivalist/on_gain() - owner.special_role = "survivalist" - forge_objectives() - . = ..() +/datum/antagonist/survivalist/give_objectives() + add_objective(/datum/objective/survive) /datum/antagonist/survivalist/greet() - to_chat(owner.current, "You are the survivalist! [greet_message]") - owner.announce_objectives() + ..() + to_chat(owner.current, "[greet_message]") /datum/antagonist/survivalist/guns greet_message = "Your own safety matters above all else, and the only way to ensure your safety is to stockpile weapons! Grab as many guns as possible, by any means necessary. Kill anyone who gets in your way." -/datum/antagonist/survivalist/guns/forge_objectives() - var/datum/objective/steal_five_of_type/summon_guns/guns = new - guns.owner = owner - objectives += guns +/datum/antagonist/survivalist/guns/give_objectives() + add_objective(/datum/objective/steal_five_of_type/summon_guns) ..() /datum/antagonist/survivalist/magic name = "Amateur Magician" - greet_message = "Grow your newfound talent! Grab as many magical artefacts as possible, by any means necessary. Kill anyone who gets in your way." + greet_message = "Grow your newfound talent! Grab as many magical artefacts as possible, by any means necessary. Kill anyone who gets in your way. As a wonderful magician, you should remember that spellbooks don't mean anything if they are used up." -/datum/antagonist/survivalist/magic/greet() - ..() - to_chat(owner.current, "As a wonderful magician, you should remember that spellbooks don't mean anything if they are used up.") - -/datum/antagonist/survivalist/magic/forge_objectives() - var/datum/objective/steal_five_of_type/summon_magic/magic = new - magic.owner = owner - objectives += magic +/datum/antagonist/survivalist/magic/give_objectives() + add_objective(/datum/objective/steal_five_of_type/summon_magic) ..() diff --git a/code/modules/antagonists/traitor/datum_mindslave.dm b/code/modules/antagonists/traitor/datum_mindslave.dm index 4efa9ddaa56..5a0f5b49cf0 100644 --- a/code/modules/antagonists/traitor/datum_mindslave.dm +++ b/code/modules/antagonists/traitor/datum_mindslave.dm @@ -21,10 +21,15 @@ return master = _master greet_text = _greet_text - return ..() + ..() -/datum/antagonist/mindslave/Destroy() +/datum/antagonist/mindslave/Destroy(force, ...) + if(owner.som) + owner.som.serv -= owner + owner.som.leave_serv_hud(owner) master = null + SSticker.mode.implanted[owner] = null + SSticker.mode.implanted -= owner return ..() /datum/antagonist/mindslave/on_gain() @@ -42,22 +47,11 @@ hud.join_hud(master.current) set_antag_hud(master.current, "hudmaster") slaved.add_serv_hud(master, "master") - - // Add an obey and protect objective. - var/datum/objective/protect/serve_objective = new - serve_objective.target = master - serve_objective.owner = owner - var/role = master.assigned_role ? master.assigned_role : master.special_role - serve_objective.explanation_text = "Obey every order from and protect [master.current.real_name], the [role]." - objectives += serve_objective return ..() -/datum/antagonist/mindslave/on_removal() - if(owner.som) - var/datum/mindslaves/slaved = owner.som - slaved.serv -= owner - slaved.leave_serv_hud(owner) - return ..() +/datum/antagonist/mindslave/give_objectives() + var/explanation_text = "Obey every order from and protect [master.current.real_name], the [master.assigned_role ? master.assigned_role : master.special_role]." + add_objective(/datum/objective/protect/mindslave, explanation_text, master) /datum/antagonist/mindslave/greet() var/mob/living/carbon/human/mindslave = owner.current diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index 9f71b00aad6..58233c8c3a1 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -23,9 +23,9 @@ owner.som.masters += owner SSticker.mode.traitors |= owner - return ..() + ..() -/datum/antagonist/traitor/on_removal() +/datum/antagonist/traitor/Destroy(force, ...) // Remove all associated malf AI abilities. if(isAI(owner.current)) var/mob/living/silicon/ai/A = owner.current @@ -46,7 +46,6 @@ owner.som = null owner.current.client.chatOutput?.clear_syndicate_codes() - assigned_targets.Cut() SSticker.mode.traitors -= owner return ..() diff --git a/code/modules/antagonists/vampire/vamp_datum.dm b/code/modules/antagonists/vampire/vamp_datum.dm index a9efbf2303d..03398df4d32 100644 --- a/code/modules/antagonists/vampire/vamp_datum.dm +++ b/code/modules/antagonists/vampire/vamp_datum.dm @@ -36,9 +36,9 @@ SSticker.mode.vampire_enthralled += owner ..() -/datum/antagonist/mindslave/thrall/on_removal() +/datum/antagonist/mindslave/thrall/Destroy(force, ...) SSticker.mode.vampire_enthralled -= owner - ..() + return ..() /datum/antagonist/mindslave/thrall/apply_innate_effects(mob/living/new_body) ..() @@ -51,6 +51,8 @@ M.RemoveSpell(/obj/effect/proc_holder/spell/vampire/thrall_commune) /datum/antagonist/vampire/Destroy(force, ...) + SSticker.mode.vampires -= owner + owner.current.create_log(CONVERSION_LOG, "De-vampired") draining = null QDEL_NULL(subclass) QDEL_LIST(powers) @@ -88,18 +90,17 @@ qdel(ability) owner.current.update_sight() // Life updates conditionally, so we need to update sight here in case the vamp loses his vision based powers. Maybe one day refactor to be more OOP and on the vampire's ability datum. -/datum/antagonist/vampire/remove_innate_effects(mob/living/old_body) - var/mob/living/L = old_body || owner.current +/datum/antagonist/vampire/remove_innate_effects(mob/living/mob_override) + mob_override = ..() for(var/P in powers) remove_ability(P) - var/datum/hud/hud = L.hud_used + var/datum/hud/hud = mob_override.hud_used if(hud?.vampire_blood_display) hud.remove_vampire_hud() - L.dna.species.hunger_type = initial(L.dna.species.hunger_type) - L.dna.species.hunger_icon = initial(L.dna.species.hunger_icon) + mob_override.dna.species.hunger_type = initial(mob_override.dna.species.hunger_type) + mob_override.dna.species.hunger_icon = initial(mob_override.dna.species.hunger_icon) owner.current.alpha = 255 REMOVE_TRAITS_IN(owner.current, "vampire") - return ..() #define BLOOD_GAINED_MODIFIER 0.5 @@ -188,10 +189,6 @@ var/datum/vampire_passive/power = p to_chat(owner.current, "[power.gain_desc]") -/datum/antagonist/vampire/on_removal() - SSticker.mode.vampires -= owner - owner.current.create_log(CONVERSION_LOG, "De-vampired") - ..() /datum/antagonist/vampire/on_gain() SSticker.mode.vampires += owner @@ -321,14 +318,14 @@ You are weak to holy things, starlight and fire. Don't go into space and avoid the Chaplain, the chapel and especially Holy Water."} to_chat(owner.current, dat) -/datum/antagonist/vampire/apply_innate_effects(mob/living/new_body) - . = ..() +/datum/antagonist/vampire/apply_innate_effects(mob/living/mob_override) + mob_override = ..() if(!owner.som) //thralls and mindslaves owner.som = new() owner.som.masters += owner - var/mob/living/L = new_body || owner.current - L.dna.species.hunger_type = "vampire" - L.dna.species.hunger_icon = 'icons/mob/screen_hunger_vampire.dmi' + + mob_override.dna.species.hunger_type = "vampire" + mob_override.dna.species.hunger_icon = 'icons/mob/screen_hunger_vampire.dmi' check_vampire_upgrade(FALSE) /datum/hud/proc/remove_vampire_hud() diff --git a/code/modules/antagonists/wishgranter/wishgranter.dm b/code/modules/antagonists/wishgranter/wishgranter.dm index 99efbc811f4..463cb869211 100644 --- a/code/modules/antagonists/wishgranter/wishgranter.dm +++ b/code/modules/antagonists/wishgranter/wishgranter.dm @@ -1,24 +1,16 @@ /datum/antagonist/wishgranter name = "Wishgranter Avatar" + special_role = "Avatar of the Wish Granter" -/datum/antagonist/wishgranter/proc/forge_objectives() - var/datum/objective/hijack/hijack = new - hijack.owner = owner - objectives += hijack - owner.objectives |= objectives - -/datum/antagonist/wishgranter/on_gain() - owner.special_role = "Avatar of the Wish Granter" - forge_objectives() - . = ..() - give_powers() +/datum/antagonist/wishgranter/give_objectives() + add_objective(/datum/objective/hijack) /datum/antagonist/wishgranter/greet() - to_chat(owner.current, "Your inhibitions are swept away, the bonds of loyalty broken, you are free to murder as you please!") - owner.announce_objectives() + ..() + to_chat(owner.current, "Your inhibitions are swept away, the bonds of loyalty broken, you are free to murder as you please!") -/datum/antagonist/wishgranter/proc/give_powers() - var/mob/living/carbon/human/H = owner.current +/datum/antagonist/wishgranter/apply_innate_effects(mob/living/mob_override) + var/mob/living/carbon/human/H = ..() if(!istype(H)) return H.ignore_gene_stability = TRUE