diff --git a/code/datums/antagonists/antag_datum.dm b/code/datums/antagonists/antag_datum.dm
new file mode 100644
index 00000000000..07109d242d1
--- /dev/null
+++ b/code/datums/antagonists/antag_datum.dm
@@ -0,0 +1,87 @@
+//The Datum, Antagonist. Handles various antag things via a datum.
+/datum/antagonist
+ var/mob/living/owner //who's our owner and accordingly an antagonist
+ var/some_flufftext = "yer an antag larry"
+ var/prevented_antag_datum_type //the type of antag datum that this datum can't coexist with; should probably be a list
+ var/silent_update = FALSE //if we suppress messages during on_gain, apply_innate_effects, remove_innate_effects, and on_remove
+
+/datum/antagonist/New()
+ if(!prevented_antag_datum_type)
+ prevented_antag_datum_type = type
+
+/datum/antagonist/Destroy()
+ owner = null
+ return ..()
+
+/datum/antagonist/proc/can_be_owned(mob/living/new_body)
+ return new_body && !new_body.has_antag_datum(prevented_antag_datum_type, TRUE)
+
+/datum/antagonist/proc/give_to_body(mob/living/new_body) //tries to give an antag datum to a mob. cancels out if it can't be owned by the new body
+ if(new_body && can_be_owned(new_body))
+ new_body.antag_datums += src
+ owner = new_body
+ on_gain()
+ . = src //return the datum if successful
+ else
+ qdel(src)
+ . = FALSE
+
+/datum/antagonist/proc/on_gain() //on initial gain of antag datum, do this. should only be called once per datum
+ apply_innate_effects()
+ if(!silent_update && some_flufftext)
+ owner << some_flufftext
+
+/datum/antagonist/proc/apply_innate_effects() //applies innate effects to the owner, may be called multiple times due to mind transferral, but should only be called once per mob
+ //antag huds would go here if antag huds were less completely unworkable as-is
+
+/datum/antagonist/proc/remove_innate_effects() //removes innate effects from the owner, may be called multiple times due to mind transferral, but should only be called once per mob
+ //also antag huds but see above antag huds a shit
+
+/datum/antagonist/proc/on_remove() //totally removes the antag datum from the owner; can only be called once per owner
+ remove_innate_effects()
+ owner.antag_datums -= src
+ qdel(src)
+
+/datum/antagonist/proc/transfer_to_new_body(mob/living/new_body)
+ remove_innate_effects()
+ if(!islist(new_body.antag_datums))
+ new_body.antag_datums = list()
+ new_body.antag_datums += src
+ owner.antag_datums -= src
+ owner = new_body
+ apply_innate_effects()
+
+//mob var and helper procs/Destroy override
+/mob/living
+ var/list/antag_datums
+
+/mob/living/Destroy() //TODO: merge this with the living/Destroy() in code\modules\mob\living\living.dm (currently line 29)
+ if(islist(antag_datums))
+ for(var/i in antag_datums)
+ qdel(i)
+ antag_datums = null
+ return ..()
+
+/mob/living/proc/can_have_antag_datum(datum_type) //if we can have this specific antagonist datum; neccessary, but requires creating a new antag datum each time.
+ var/datum/antagonist/D = new datum_type()
+ . = D.can_be_owned(src) //we can't exactly cache the results, either, because conditions might change. avoid use? TODO: better proc
+ qdel(D)
+
+/mob/living/proc/gain_antag_datum(datum_type) //tries to give a mob a specific antagonist datum; returns the datum if successful.
+ if(!islist(antag_datums))
+ antag_datums = list()
+ var/datum/antagonist/D = new datum_type()
+ . = D.give_to_body(src)
+
+/mob/living/proc/has_antag_datum(type, check_subtypes) //checks this mob for if it has the antagonist datum. can either check specific type or subtypes
+ if(!islist(antag_datums))
+ return FALSE
+ for(var/i in antag_datums)
+ var/datum/antagonist/D = i
+ if(check_subtypes)
+ if(istype(D, type))
+ return D //if it finds the datum, will return it so you can mess with it
+ else
+ if(D.type == type)
+ return D
+ return FALSE
diff --git a/code/datums/antagonists/datum_clockcult.dm b/code/datums/antagonists/datum_clockcult.dm
new file mode 100644
index 00000000000..ad369769eb8
--- /dev/null
+++ b/code/datums/antagonists/datum_clockcult.dm
@@ -0,0 +1,133 @@
+//CLOCKCULT PROOF OF CONCEPT
+
+/datum/antagonist/clockcultist
+ prevented_antag_datum_type = /datum/antagonist/clockcultist
+ some_flufftext = null
+ var/datum/action/innate/hierophant/hierophant_network = new()
+
+/datum/antagonist/clockcultist/silent
+ silent_update = TRUE
+
+/datum/antagonist/clockcultist/Destroy()
+ qdel(hierophant_network)
+ ..()
+
+/datum/antagonist/clockcultist/can_be_owned(mob/living/new_body)
+ . = ..()
+ if(.)
+ . = is_eligible_servant(new_body)
+
+/datum/antagonist/clockcultist/give_to_body(mob/living/new_body)
+ if(!silent_update)
+ if(issilicon(new_body))
+ new_body << "You are unable to compute this truth. Your vision glows a brilliant yellow, and all at once it comes to you. Ratvar, the Clockwork Justiciar, \
+ lies in exile, derelict and forgotten in an unseen realm."
+ else
+ new_body << "[iscarbon(new_body) ? "Your mind is racing! Your body feels incredibly light! ":""]Your world glows a brilliant yellow! All at once it comes to you. \
+ Ratvar, the Clockwork Justiciar, lies in exile, derelict and forgotten in an unseen realm."
+ . = ..()
+ if(!silent_update && new_body)
+ if(.)
+ new_body.visible_message("[new_body]'s eyes glow a blazing yellow!", \
+ "Assist your new companions in their righteous efforts. Your goal is theirs, and theirs yours. You serve the Clockwork Justiciar above all else. Perform his every \
+ whim without hesitation.")
+ else
+ new_body.visible_message("[new_body] seems to resist an unseen force!")
+ new_body << "And yet, you somehow push it all away."
+
+/datum/antagonist/clockcultist/on_gain()
+ if(ticker && ticker.mode && owner.mind)
+ ticker.mode.servants_of_ratvar += owner.mind
+ ticker.mode.update_servant_icons_added(owner.mind)
+ if(jobban_isbanned(owner, ROLE_SERVANT_OF_RATVAR))
+ addtimer(ticker.mode, "replace_jobbaned_player", 0, FALSE, owner, ROLE_SERVANT_OF_RATVAR, ROLE_SERVANT_OF_RATVAR)
+ if(owner.mind)
+ owner.mind.special_role = "Servant of Ratvar"
+ owner.attack_log += "\[[time_stamp()]\] Has been converted to the cult of Ratvar!"
+ if(issilicon(owner))
+ var/mob/living/silicon/S = owner
+ if(isrobot(S) && !silent_update)
+ S << "You have been desynced from your master AI. In addition, your onboard camera is no longer active and your safeties have been disabled."
+ S << "You can communicate with other servants by using the Hierophant Network action button in the upper left."
+ else if(isbrain(owner) || isclockmob(owner))
+ owner << "You can communicate with other servants by using the Hierophant Network action button in the upper left."
+ ..()
+
+/datum/antagonist/clockcultist/apply_innate_effects()
+ all_clockwork_mobs += owner
+ owner.faction |= "ratvar"
+ owner.languages_spoken |= RATVAR
+ owner.languages_understood |= RATVAR
+ owner.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them for whatever reason, we need to update buttons
+ if(issilicon(owner))
+ var/mob/living/silicon/S = owner
+ if(isrobot(S))
+ var/mob/living/silicon/robot/R = S
+ R.UnlinkSelf()
+ R.emagged = 1
+ else if(isAI(S))
+ var/mob/living/silicon/ai/A = S
+ for(var/C in A.connected_robots)
+ var/mob/living/silicon/robot/R = C
+ if(R.connected_ai == A)
+ R.visible_message("[R]'s eyes glow a blazing yellow!", \
+ "Assist your new companions in their righteous efforts. Your goal is theirs, and theirs yours. You serve the Clockwork Justiciar above all else. Perform his every \
+ whim without hesitation.")
+ R << "Your onboard camera is no longer active and your safeties have been disabled."
+ add_servant_of_ratvar(R, TRUE)
+ S.laws = new/datum/ai_laws/ratvar
+ S.laws.associate(S)
+ S.update_icons()
+ S.show_laws()
+ hierophant_network.Grant(S)
+ hierophant_network.title = "Silicon"
+ hierophant_network.span_for_name = "nezbere"
+ hierophant_network.span_for_message = "brass"
+ else if(isbrain(owner))
+ hierophant_network.Grant(owner)
+ hierophant_network.title = "Vessel"
+ hierophant_network.span_for_name = "nezbere"
+ hierophant_network.span_for_message = "alloy"
+ else if(isclockmob(owner))
+ hierophant_network.Grant(owner)
+ hierophant_network.title = "Construct"
+ hierophant_network.span_for_name = "nezbere"
+ hierophant_network.span_for_message = "brass"
+ owner.throw_alert("clockinfo", /obj/screen/alert/clockwork/infodump)
+ cache_check(owner)
+ ..()
+
+/datum/antagonist/clockcultist/remove_innate_effects()
+ all_clockwork_mobs -= owner
+ owner.faction -= "ratvar"
+ owner.languages_spoken &= ~RATVAR
+ owner.languages_understood &= ~RATVAR
+ owner.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them, we need to update buttons
+ owner.clear_alert("clockinfo")
+ owner.clear_alert("nocache")
+ for(var/datum/action/innate/function_call/F in owner.actions) //Removes any bound Ratvarian spears
+ qdel(F)
+ if(issilicon(owner))
+ var/mob/living/silicon/S = owner
+ if(isrobot(S))
+ var/mob/living/silicon/robot/R = S
+ R.emagged = initial(R.emagged)
+ S.make_laws()
+ S.update_icons()
+ S.show_laws()
+ ..()
+
+/datum/antagonist/clockcultist/on_remove()
+ if(!silent_update)
+ owner.visible_message("[owner] seems to have remembered their true allegiance!", \
+ "A cold, cold darkness flows through your mind, extinguishing the Justiciar's light and all of your memories as his servant.")
+ if(ticker && ticker.mode && owner.mind)
+ ticker.mode.servants_of_ratvar -= owner.mind
+ ticker.mode.update_servant_icons_removed(owner.mind)
+ if(owner.mind)
+ owner.mind.memory = "" //Not sure if there's a better way to do this
+ owner.mind.special_role = null
+ owner.attack_log += "\[[time_stamp()]\] Has renounced the cult of Ratvar!"
+ if(isrobot(owner))
+ owner << "Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking."
+ ..()
diff --git a/code/datums/antagonists/datum_cult.dm b/code/datums/antagonists/datum_cult.dm
new file mode 100644
index 00000000000..6bc2fe69381
--- /dev/null
+++ b/code/datums/antagonists/datum_cult.dm
@@ -0,0 +1,47 @@
+/datum/antagonist/cultist
+ prevented_antag_datum_type = /datum/antagonist/cultist
+ some_flufftext = null
+ var/datum/action/innate/cultcomm/communion = new()
+
+/datum/antagonist/cultist/Destroy()
+ qdel(communion)
+ return ..()
+
+/datum/antagonist/cultist/can_be_owned(mob/living/new_body)
+ . = ..()
+ if(.)
+ . = is_convertable_to_cult(new_body)
+
+/datum/antagonist/cultist/on_gain()
+ if(ticker && ticker.mode && owner.mind)
+ ticker.mode.cult += owner.mind
+ ticker.mode.servants_of_ratvar += owner.mind
+ ticker.mode.update_cult_icons_added(owner.mind)
+ if(jobban_isbanned(owner, ROLE_CULTIST))
+ addtimer(ticker.mode, "replace_jobbaned_player", 0, FALSE, owner, ROLE_CULTIST, ROLE_CULTIST)
+ if(owner.mind)
+ owner.mind.special_role = "Cultist"
+ owner.attack_log += "\[[time_stamp()]\] Has been converted to the cult of Nar'Sie!"
+ ..()
+
+/datum/antagonist/cultist/apply_innate_effects()
+ owner.faction |= "cult"
+ owner.verbs += /mob/living/proc/cult_help
+ communion.Grant(owner)
+ ..()
+
+/datum/antagonist/cultist/remove_innate_effects()
+ owner.faction -= "cult"
+ owner.verbs -= /mob/living/proc/cult_help
+ ..()
+
+/datum/antagonist/cultist/on_remove()
+ if(ticker && ticker.mode && owner.mind)
+ ticker.mode.cult -= owner.mind
+ ticker.mode.update_cult_icons_removed(owner.mind)
+ owner << "An unfamiliar white light flashes through your mind, cleansing the taint of the Dark One and all your memories as its servant."
+ owner.memory = ""
+ owner.attack_log += "\[[time_stamp()]\] Has renounced the cult of Nar'Sie!"
+ if(!silent_update)
+ owner.visible_message("[owner] looks like they just reverted to their old faith!")
+ ..()
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index b335ccdd762..b7c70b57878 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -83,6 +83,10 @@
if(new_character.mind) //disassociate any mind currently in our new body's mind variable
new_character.mind.current = null
+ if(istype(current) && islist(current.antag_datums)) //wow apparently current isn't always living good fucking job SOMEONE
+ for(var/i in current.antag_datums)
+ var/datum/antagonist/D = i
+ D.transfer_to_new_body(new_character)
var/datum/atom_hud/antag/hud_to_transfer = antag_hud//we need this because leave_hud() will clear this list
leave_all_huds() //leave all the huds in the old body, so it won't get huds if somebody else enters it
current = new_character //associate ourself with our new body
@@ -215,7 +219,7 @@
ticker.mode.add_revolutionary(src)
else if(is_servant_of_ratvar(creator))
- add_servant_of_ratvar(src)
+ add_servant_of_ratvar(current)
else if(is_nuclear_operative(creator))
make_Nuke(null, null, 0, FALSE)
diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm
index 81e00e6b877..69c3db97d8d 100644
--- a/code/game/gamemodes/clock_cult/clock_cult.dm
+++ b/code/game/gamemodes/clock_cult/clock_cult.dm
@@ -43,148 +43,37 @@ Credit where due:
///////////
/proc/is_servant_of_ratvar(mob/living/M)
- return M && istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.servants_of_ratvar)
+ return istype(M) && M.has_antag_datum(/datum/antagonist/clockcultist, TRUE)
/proc/is_eligible_servant(mob/living/M)
if(!istype(M))
return 0
- if(!M.mind)
- return 0
- if(M.mind.enslaved_to && !is_servant_of_ratvar(M.mind.enslaved_to))
- return 0
- if(iscultist(M) || isconstruct(M))
- return 0
- if(isbrain(M))
- return 1
- if(ishuman(M))
- if(isloyal(M) || (M.mind.assigned_role in list("Captain", "Chaplain")))
+ if(M.mind)
+ if(ishuman(M) && (M.mind.assigned_role in list("Captain", "Chaplain")))
return 0
- return 1
- if(isguardian(M))
- var/mob/living/simple_animal/hostile/guardian/G = M
- if(is_servant_of_ratvar(G.summoner))
- return 1 //can't convert it unless the owner is converted
- if(issilicon(M) || isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
+ if(M.mind.enslaved_to && !is_servant_of_ratvar(M.mind.enslaved_to))
+ return 0
+ else
+ return 0
+ if(iscultist(M) || isconstruct(M) || isloyal(M))
+ return 0
+ if(ishuman(M) || isbrain(M) || isguardian(M) || issilicon(M) || isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
return 1
return 0
-/proc/add_servant_of_ratvar(mob/M, silent = FALSE)
- if(is_servant_of_ratvar(M) || !ticker || !ticker.mode)
- return 0
- if(iscarbon(M))
- if(!silent)
- M << "Your mind is racing! Your body feels incredibly light! Your world glows a brilliant yellow! All at once it comes to you. Ratvar, the Clockwork \
- Justiciar, lies in exile, derelict and forgotten in an unseen realm."
- else if(issilicon(M))
- if(!silent)
- M << "You are unable to compute this truth. Your vision glows a brilliant yellow, and all at once it comes to you. Ratvar, the Clockwork Justiciar, lies in \
- exile, derelict and forgotten in an unseen realm."
- if(!is_eligible_servant(M))
- if(!M.stat)
- M.visible_message("[M] whirs as it resists an outside influence!")
- M << "Corrupt data purged. Resetting cortex chip to factory defaults... complete." //silicons have a custom fail message
- return 0
- else if(!silent)
- M << "Your world glows a brilliant yellow! All at once it comes to you. Ratvar, the Clockwork Justiciar, lies in exile, derelict and forgotten in an unseen realm."
+/proc/add_servant_of_ratvar(mob/living/L, silent = FALSE)
+ var/update_type = /datum/antagonist/clockcultist
+ if(silent)
+ update_type = /datum/antagonist/clockcultist/silent
+ . = L.gain_antag_datum(update_type)
- if(!is_eligible_servant(M))
- if(!silent && !M.stat)
- M.visible_message("[M] seems to resist an unseen force!")
- M << "And yet, you somehow push it all away."
- return 0
-
- if(!silent)
- M.visible_message("[M]'s eyes glow a blazing yellow!", \
- "Assist your new companions in their righteous efforts. Your goal is theirs, and theirs yours. You serve the Clockwork Justiciar above all else. Perform his every \
- whim without hesitation.")
- ticker.mode.servants_of_ratvar += M.mind
- ticker.mode.update_servant_icons_added(M.mind)
- all_clockwork_mobs += M
- M.faction |= "ratvar"
- M.mind.special_role = "Servant of Ratvar"
- M.languages_spoken |= RATVAR
- M.languages_understood |= RATVAR
- M.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them for whatever reason, we need to update buttons
- M.attack_log += "\[[time_stamp()]\] Has been converted to the cult of Ratvar!"
- if(issilicon(M))
- var/mob/living/silicon/S = M
- if(isrobot(S))
- var/mob/living/silicon/robot/R = S
- R.UnlinkSelf()
- R.emagged = 1
- if(!silent)
- R << "You have been desynced from your master AI. In addition, your onboard camera is no longer active and your safeties have been disabled."
- else if(isAI(S))
- var/mob/living/silicon/ai/A = S
- for(var/C in A.connected_robots)
- var/mob/living/silicon/robot/R = C
- if(R.connected_ai == A)
- R.visible_message("[R]'s eyes glow a blazing yellow!", \
- "Assist your new companions in their righteous efforts. Your goal is theirs, and theirs yours. You serve the Clockwork Justiciar above all else. Perform his every \
- whim without hesitation.")
- R << "Your onboard camera is no longer active and your safeties have been disabled."
- add_servant_of_ratvar(R, TRUE)
- S.laws = new/datum/ai_laws/ratvar
- S.laws.associate(S)
- S.update_icons()
- S.show_laws()
- var/datum/action/innate/hierophant/H = new()
- H.Grant(S)
- H.title = "Silicon"
- H.span_for_name = "nezbere"
- S << "You can communicate with other servants by using the Hierophant Network action button in the upper left."
- else if(isbrain(M))
- var/datum/action/innate/hierophant/H = new()
- H.Grant(M)
- H.title = "Vessel"
- H.span_for_name = "nezbere"
- H.span_for_message = "alloy"
- M << "You can communicate with other servants by using the Hierophant Network action button in the upper left."
- else if(isclockmob(M))
- var/datum/action/innate/hierophant/H = new()
- H.Grant(M)
- H.title = "Construct"
- H.span_for_name = "nezbere"
- M << "You can communicate with other servants by using the Hierophant Network action button in the upper left."
- if(istype(ticker.mode, /datum/game_mode/clockwork_cult))
- var/datum/game_mode/clockwork_cult/C = ticker.mode
- C.present_tasks(M) //Memorize the objectives
- M.throw_alert("clockinfo", /obj/screen/alert/clockwork/infodump)
- cache_check(M)
- return 1
-
-/proc/remove_servant_of_ratvar(mob/living/M, silent = FALSE)
- if(!is_servant_of_ratvar(M)) //In this way, is_servant_of_ratvar() checks the existence of ticker and minds
- return 0
- if(!silent)
- M.visible_message("[M] seems to have remembered their true allegiance!", \
- "A cold, cold darkness flows through your mind, extinguishing the Justiciar's light and all of your memories as his servant.")
- ticker.mode.servants_of_ratvar -= M.mind
- ticker.mode.update_servant_icons_removed(M.mind)
- all_clockwork_mobs -= M
- M.faction -= "ratvar"
- M.mind.memory = "" //Not sure if there's a better way to do this
- M.mind.special_role = null
- M.languages_spoken &= ~RATVAR
- M.languages_understood &= ~RATVAR
- M.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them, we need to update buttons
- M.attack_log += "\[[time_stamp()]\] Has renounced the cult of Ratvar!"
- M.clear_alert("clockinfo")
- M.clear_alert("nocache")
- for(var/datum/action/innate/function_call/F in M.actions) //Removes any bound Ratvarian spears
- qdel(F)
- for(var/datum/action/innate/hierophant/H in M.actions) //Removes any communication actions
- qdel(H)
- if(issilicon(M))
- var/mob/living/silicon/S = M
- if(isrobot(S))
- var/mob/living/silicon/robot/R = S
- R.emagged = initial(R.emagged)
- R << "Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking."
- S.make_laws()
- S.update_icons()
- S.show_laws()
- return 1
+/proc/remove_servant_of_ratvar(mob/living/L, silent = FALSE)
+ var/datum/antagonist/clockcultist/clock_datum = L.has_antag_datum(/datum/antagonist/clockcultist, TRUE)
+ if(!clock_datum)
+ return FALSE
+ clock_datum.silent_update = silent
+ clock_datum.on_remove()
+ return TRUE
///////////////
// GAME MODE //
diff --git a/code/game/gamemodes/clock_cult/clock_structures.dm b/code/game/gamemodes/clock_cult/clock_structures.dm
index fa2733fdee7..400c680ba19 100644
--- a/code/game/gamemodes/clock_cult/clock_structures.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures.dm
@@ -295,9 +295,7 @@
user.visible_message("[user] places [S] in [src], where it fuses to the shell.", "You place [S] in [src], fusing it to the shell.")
var/mob/living/simple_animal/A = new mobtype(get_turf(src))
A.visible_message("[src][spawn_message]")
- remove_servant_of_ratvar(S.brainmob, TRUE)
S.brainmob.mind.transfer_to(A)
- add_servant_of_ratvar(A, TRUE)
user.drop_item()
qdel(S)
qdel(src)
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index b80a7e692ea..7597b4b2bbb 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -5,7 +5,7 @@
var/list/cult_objectives = list()
/proc/iscultist(mob/living/M)
- return istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.cult)
+ return istype(M) && M.has_antag_datum(/datum/antagonist/cultist, TRUE)
/proc/is_sacrifice_target(datum/mind/mind)
if(ticker.mode.name == "cult")
@@ -14,21 +14,20 @@
return 1
return 0
-/proc/is_convertable_to_cult(datum/mind/mind)
- if(!istype(mind))
+/proc/is_convertable_to_cult(mob/living/M)
+ if(!istype(M))
return 0
- if(istype(mind.current, /mob/living/carbon/human) && (mind.assigned_role in list("Captain", "Chaplain")))
- return 0
- if(isloyal(mind.current))
- return 0
- if(issilicon(mind.current) || isbot(mind.current) || isdrone(mind.current))
- return 0 //can't convert machines, that's ratvar's thing
- if(is_sacrifice_target(mind))
- return 0
- if(mind.enslaved_to && !iscultist(mind.enslaved_to))
- return 0
- if(is_servant_of_ratvar(mind.current))
+ if(M.mind)
+ if(ishuman(M) && (M.mind.assigned_role in list("Captain", "Chaplain")))
+ return 0
+ if(is_sacrifice_target(M.mind))
+ return 0
+ if(M.mind.enslaved_to && !iscultist(M.mind.enslaved_to))
+ return 0
+ else
return 0
+ if(isloyal(M) || issilicon(M) || isbot(M) || isdrone(M) || is_servant_of_ratvar(M))
+ return 0 //can't convert machines, shielded, or ratvar's dogs
return 1
/datum/game_mode/cult
@@ -159,19 +158,10 @@
/datum/game_mode/proc/add_cultist(datum/mind/cult_mind, stun) //BASE
if (!istype(cult_mind))
return 0
- if(!(cult_mind in cult) && is_convertable_to_cult(cult_mind))
+ if(cult_mind.current.gain_antag_datum(/datum/antagonist/cultist))
if(stun)
cult_mind.current.Paralyse(5)
- cult += cult_mind
- cult_mind.current.faction |= "cult"
- cult_mind.current.verbs += /mob/living/proc/cult_help
- var/datum/action/innate/cultcomm/C = new()
- C.Grant(cult_mind.current)
- update_cult_icons_added(cult_mind)
- cult_mind.current.attack_log += "\[[time_stamp()]\] Has been converted to the cult of Nar'Sie!"
- if(jobban_isbanned(cult_mind.current, ROLE_CULTIST))
- replace_jobbaned_player(cult_mind.current, ROLE_CULTIST, ROLE_CULTIST)
- return 1
+ return 1
/datum/game_mode/cult/add_cultist(datum/mind/cult_mind, stun) //INHERIT
@@ -181,21 +171,15 @@
/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = 1, stun)
- if(cult_mind in cult)
- cult -= cult_mind
- cult_mind.current.faction -= "cult"
- cult_mind.current.verbs -= /mob/living/proc/cult_help
- for(var/datum/action/innate/cultcomm/C in cult_mind.current.actions)
- qdel(C)
+ if(cult_mind.current)
+ var/datum/antagonist/cultist/cult_datum = cult_mind.current.has_antag_datum(/datum/antagonist/cultist, TRUE)
+ if(!cult_datum)
+ return FALSE
+ cult_datum.silent_update = show_message
+ cult_datum.on_remove()
if(stun)
cult_mind.current.Paralyse(5)
- cult_mind.current << "An unfamiliar white light flashes through your mind, cleansing the taint of the Dark One and all your memories as its servant."
- cult_mind.memory = ""
- update_cult_icons_removed(cult_mind)
- cult_mind.current.attack_log += "\[[time_stamp()]\] Has renounced the cult of Nar'Sie!"
- if(show_message)
- for(var/mob/M in viewers(cult_mind.current))
- M << "[cult_mind.current] looks like they just reverted to their old faith!"
+ return TRUE
/datum/game_mode/proc/update_cult_icons_added(datum/mind/cult_mind)
var/datum/atom_hud/antag/culthud = huds[ANTAG_HUD_CULT]
@@ -206,12 +190,14 @@
var/datum/atom_hud/antag/culthud = huds[ANTAG_HUD_CULT]
culthud.leave_hud(cult_mind.current)
set_antag_hud(cult_mind.current, null)
+
/datum/game_mode/cult/proc/get_unconvertables()
var/list/ucs = list()
for(var/mob/living/carbon/human/player in player_list)
if(player.mind && !is_convertable_to_cult(player.mind))
ucs += player.mind
return ucs
+
/datum/game_mode/cult/proc/check_cult_victory()
var/cult_fail = 0
if(cult_objectives.Find("survive"))
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index e4311624dc5..6dc61afc365 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -539,8 +539,6 @@
ticker.mode.remove_cultist(newborgie, 0, 0)
ticker.mode.remove_revolutionary(newborgie, 0)
ticker.mode.remove_gangster(newborgie, 0, remove_bosses=1)
- remove_servant_of_ratvar(newborgie.current, TRUE)
-
/datum/game_mode/proc/generate_station_goals()
var/list/possible = list()
diff --git a/code/game/gamemodes/gang/gang.dm b/code/game/gamemodes/gang/gang.dm
index eefbf5689f1..b9f5eaebc28 100644
--- a/code/game/gamemodes/gang/gang.dm
+++ b/code/game/gamemodes/gang/gang.dm
@@ -177,7 +177,7 @@ var/list/gang_colors_pool = list("red","orange","yellow","green","blue","purple"
gangster_mind.store_memory("You are a member of the [G.name] Gang!")
G.add_gang_hud(gangster_mind)
if(jobban_isbanned(gangster_mind.current, ROLE_GANG))
- replace_jobbaned_player(gangster_mind.current, ROLE_GANG, ROLE_GANG)
+ addtimer(src, "replace_jobbaned_player", 0, FALSE, gangster_mind.current, ROLE_GANG, ROLE_GANG)
return 2
////////////////////////////////////////////////////////////////////
//Deals with players reverting to neutral (Not a gangster anymore)//
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index b67617ae380..901d6f986eb 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -253,7 +253,7 @@
rev_mind.special_role = "Revolutionary"
update_rev_icons_added(rev_mind)
if(jobban_isbanned(rev_mind.current, ROLE_REV))
- replace_jobbaned_player(rev_mind.current, ROLE_REV, ROLE_REV)
+ addtimer(src, "replace_jobbaned_player", 0, FALSE, rev_mind.current, ROLE_REV, ROLE_REV)
return 1
//////////////////////////////////////////////////////////////////////////////
//Deals with players being converted from the revolution (Not a rev anymore)// // Modified to handle borged MMIs. Accepts another var if the target is being borged at the time -- Polymorph.
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index 21aab1670c9..f89954ad43a 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -213,11 +213,10 @@
O.make_laws()
ticker.mode.remove_antag_for_borging(BM.mind)
+ if(!M.clockwork)
+ remove_servant_of_ratvar(BM, TRUE)
BM.mind.transfer_to(O)
- if(M.clockwork)
- add_servant_of_ratvar(O)
-
if(O.mind && O.mind.special_role)
O.mind.store_memory("As a cyborg, you must obey your silicon laws and master AI above all else. Your objectives will consider you to be dead.")
O << "You have been robotized!"
diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm
index 9ad75378d04..e1bcccebac1 100644
--- a/code/game/objects/structures/ai_core.dm
+++ b/code/game/objects/structures/ai_core.dm
@@ -156,6 +156,7 @@
return
ticker.mode.remove_antag_for_borging(M.brainmob.mind)
+ remove_servant_of_ratvar(M, TRUE)
M.loc = src
brain = M
user << "Added a brain."
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
index d940daf1a5b..4500cb5ae05 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
@@ -144,4 +144,4 @@
return //we don't get hacked or give a shit about it
/mob/living/simple_animal/drone/cogscarab/drone_chat(msg)
- titled_hierophant_message(src, msg, "heavy_alloy") //HIEROPHANT DRONES
+ titled_hierophant_message(src, msg, "nezbere", "brass", "Construct") //HIEROPHANT DRONES
diff --git a/tgstation.dme b/tgstation.dme
index 4c840265124..3498b295a39 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -189,6 +189,9 @@
#include "code\datums\ruins.dm"
#include "code\datums\shuttles.dm"
#include "code\datums\votablemap.dm"
+#include "code\datums\antagonists\antag_datum.dm"
+#include "code\datums\antagonists\datum_clockcult.dm"
+#include "code\datums\antagonists\datum_cult.dm"
#include "code\datums\diseases\_disease.dm"
#include "code\datums\diseases\_MobProcs.dm"
#include "code\datums\diseases\anxiety.dm"