"A Working Datum Antagonist"

This commit is contained in:
Joan Lung
2016-09-19 13:03:22 -04:00
parent a43816bcfa
commit 3ec7e81131
7 changed files with 226 additions and 135 deletions

View File

@@ -83,6 +83,10 @@
if(new_character.mind) //disassociate any mind currently in our new body's mind variable if(new_character.mind) //disassociate any mind currently in our new body's mind variable
new_character.mind.current = null 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/antag_datum/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 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 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 current = new_character //associate ourself with our new body

View File

@@ -0,0 +1,197 @@
/mob/living
var/list/antag_datums
/mob/living/proc/gain_antag_datum(datum_type)
if(!islist(antag_datums))
antag_datums = list()
var/datum/antag_datum/D = new datum_type()
. = D.give_to_body(src)
/mob/living/proc/has_antag_datum(type, check_subtypes)
if(!islist(antag_datums))
return FALSE
for(var/i in antag_datums)
var/datum/antag_datum/D = i
if(check_subtypes
if(istype(D, type))
return D
else
if(D.type == type)
return D
return FALSE
/datum/antag_datum
var/mob/living/owner
var/some_flufftext = "yer an antag larry"
/datum/antag_datum/Destroy()
owner = null
return ..()
/datum/antag_datum/proc/can_be_owned(mob/living/new_body)
return new_body && !new_body.has_antag_datum(type, TRUE)
/datum/antag_datum/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/antag_datum/proc/on_gain() //on initial gain of antag datum, do this. should only be called once per datum
apply_innate_effects()
if(some_flufftext)
owner << some_flufftext
/datum/antag_datum/proc/apply_innate_effects() //applies innate effects to the owner, may be called multiple times due to mind transferral
//antag huds would go here if antag huds were less completely unworkable as-is
/datum/antag_datum/proc/remove_innate_effects() //removes innate effects from the owner, may be called multiple times due to mind transferral
//also antag huds but see above antag huds a shit
/datum/antag_datum/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/antag_datum/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()
//CLOCKCULT PROOF OF CONCEPT
/datum/antag_datum/clockcultist
var/silent_update = FALSE
some_flufftext = null
/datum/antag_datum/clockcultist/silent
silent_update = TRUE
/datum/antag_datum/clockcultist/can_be_owned(mob/living/new_body)
. = ..()
if(.)
. = is_eligible_servant(new_body)
/datum/antag_datum/clockcultist/give_to_body(mob/living/new_body)
if(!silent_update)
if(iscarbon(new_body))
new_body << "<span class='heavy_brass'>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.</span>"
else if(issilicon(new_body))
new_body << "<span class='heavy_brass'>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.</span>"
else
new_body << "<span class='heavy_brass'>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.</span>"
. = ..()
if(!silent_update && new_body)
if(.)
new_body.visible_message("<span class='heavy_brass'>[new_body]'s eyes glow a blazing yellow!</span>", \
"<span class='heavy_brass'>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.</span>")
else
new_body.visible_message("<span class='warning'>[new_body] seems to resist an unseen force!</span>")
new_body << "<span class='warning'><b>And yet, you somehow push it all away.</b></span>"
/datum/antag_datum/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(owner.mind)
owner.mind.special_role = "Servant of Ratvar"
owner.attack_log += "\[[time_stamp()]\] <span class='brass'>Has been converted to the cult of Ratvar!</span>"
if(issilicon(owner))
var/mob/living/silicon/S = owner
if(isrobot(S) && !silent_update)
S << "<span class='boldwarning'>You have been desynced from your master AI. In addition, your onboard camera is no longer active and your safeties have been disabled.</span>"
S << "<span class='heavy_brass'>You can communicate with other servants by using the Hierophant Network action button in the upper left.</span>"
else if(isbrain(owner) || isclockmob(owner))
owner << "<span class='nezbere'>You can communicate with other servants by using the Hierophant Network action button in the upper left.</span>"
..()
/datum/antag_datum/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("<span class='heavy_brass'>[R]'s eyes glow a blazing yellow!</span>", \
"<span class='heavy_brass'>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.</span>")
R << "<span class='boldwarning'>Your onboard camera is no longer active and your safeties have been disabled.</span>"
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"
else if(isbrain(owner))
var/datum/action/innate/hierophant/H = new()
H.Grant(owner)
H.title = "Vessel"
H.span_for_name = "nezbere"
H.span_for_message = "alloy"
else if(isclockmob(owner))
var/datum/action/innate/hierophant/H = new()
H.Grant(owner)
H.title = "Construct"
H.span_for_name = "nezbere"
owner.throw_alert("clockinfo", /obj/screen/alert/clockwork/infodump)
cache_check(owner)
/datum/antag_datum/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)
for(var/datum/action/innate/hierophant/H in owner.actions) //Removes any communication actions
qdel(H)
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/antag_datum/clockcultist/on_remove()
if(!silent_update)
owner.visible_message("<span class='big'>[owner] seems to have remembered their true allegiance!</span>", \
"<span class='userdanger'>A cold, cold darkness flows through your mind, extinguishing the Justiciar's light and all of your memories as his servant.</span>")
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()]\] <span class='brass'>Has renounced the cult of Ratvar!</span>"
if(isrobot(owner))
owner << "<span class='warning'>Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking.</span>"
..()

View File

@@ -43,148 +43,41 @@ Credit where due:
/////////// ///////////
/proc/is_servant_of_ratvar(mob/living/M) /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 M && istype(M) && M.has_antag_datum(/datum/antag_datum/clockcultist, TRUE)
/proc/is_eligible_servant(mob/living/M) /proc/is_eligible_servant(mob/living/M)
if(!istype(M)) if(!istype(M))
return 0 return 0
if(!M.mind) if(M.mind)
return 0
if(M.mind.enslaved_to && !is_servant_of_ratvar(M.mind.enslaved_to)) if(M.mind.enslaved_to && !is_servant_of_ratvar(M.mind.enslaved_to))
return 0 return 0
if(ishuman(M))
if(M.mind.assigned_role in list("Captain", "Chaplain"))
return 0
if(iscultist(M) || isconstruct(M)) if(iscultist(M) || isconstruct(M))
return 0 return 0
if(isbrain(M))
return 1
if(ishuman(M)) if(ishuman(M))
if(isloyal(M) || (M.mind.assigned_role in list("Captain", "Chaplain"))) if(isloyal(M))
return 0 return 0
return 1 return 1
if(isguardian(M)) if(isbrain(M) || isguardian(M) || issilicon(M) || isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
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))
return 1 return 1
return 0 return 0
/proc/add_servant_of_ratvar(mob/M, silent = FALSE) /proc/add_servant_of_ratvar(mob/living/L, silent = FALSE)
if(is_servant_of_ratvar(M) || !ticker || !ticker.mode) var/update_type = /datum/antag_datum/clockcultist
return 0 if(silent)
if(iscarbon(M)) update_type = /datum/antag_datum/clockcultist/silent
if(!silent) . = L.gain_antag_datum(update_type)
M << "<span class='heavy_brass'>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.</span>"
else if(issilicon(M))
if(!silent)
M << "<span class='heavy_brass'>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.</span>"
if(!is_eligible_servant(M))
if(!M.stat)
M.visible_message("<span class='warning'>[M] whirs as it resists an outside influence!</span>")
M << "<span class='warning'><b>Corrupt data purged. Resetting cortex chip to factory defaults... complete.</b></span>" //silicons have a custom fail message
return 0
else if(!silent)
M << "<span class='heavy_brass'>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.</span>"
if(!is_eligible_servant(M)) /proc/remove_servant_of_ratvar(mob/living/L, silent = FALSE)
if(!silent && !M.stat) var/datum/antag_datum/clockcultist/clock_datum = L.has_antag_datum(/datum/antag_datum/clockcultist, TRUE)
M.visible_message("<span class='warning'>[M] seems to resist an unseen force!</span>") if(!clock_datum)
M << "<span class='warning'><b>And yet, you somehow push it all away.</b></span>" world << "wait shit what"
return 0 return FALSE
clock_datum.silent_update = silent
if(!silent) clock_datum.on_remove()
M.visible_message("<span class='heavy_brass'>[M]'s eyes glow a blazing yellow!</span>", \ return TRUE
"<span class='heavy_brass'>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.</span>")
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()]\] <span class='brass'>Has been converted to the cult of Ratvar!</span>"
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 << "<span class='boldwarning'>You have been desynced from your master AI. In addition, your onboard camera is no longer active and your safeties have been disabled.</span>"
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("<span class='heavy_brass'>[R]'s eyes glow a blazing yellow!</span>", \
"<span class='heavy_brass'>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.</span>")
R << "<span class='boldwarning'>Your onboard camera is no longer active and your safeties have been disabled.</span>"
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 << "<span class='heavy_brass'>You can communicate with other servants by using the Hierophant Network action button in the upper left.</span>"
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 << "<span class='nezbere'>You can communicate with other servants by using the Hierophant Network action button in the upper left.</span>"
else if(isclockmob(M))
var/datum/action/innate/hierophant/H = new()
H.Grant(M)
H.title = "Construct"
H.span_for_name = "nezbere"
M << "<span class='nezbere'>You can communicate with other servants by using the Hierophant Network action button in the upper left.</span>"
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("<span class='big'>[M] seems to have remembered their true allegiance!</span>", \
"<span class='userdanger'>A cold, cold darkness flows through your mind, extinguishing the Justiciar's light and all of your memories as his servant.</span>")
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()]\] <span class='brass'>Has renounced the cult of Ratvar!</span>"
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 << "<span class='warning'>Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking.</span>"
S.make_laws()
S.update_icons()
S.show_laws()
return 1
/////////////// ///////////////
// GAME MODE // // GAME MODE //

View File

@@ -293,9 +293,7 @@
user.visible_message("<span class='notice'>[user] places [S] in [src], where it fuses to the shell.</span>", "<span class='brass'>You place [S] in [src], fusing it to the shell.</span>") user.visible_message("<span class='notice'>[user] places [S] in [src], where it fuses to the shell.</span>", "<span class='brass'>You place [S] in [src], fusing it to the shell.</span>")
var/mob/living/simple_animal/A = new mobtype(get_turf(src)) var/mob/living/simple_animal/A = new mobtype(get_turf(src))
A.visible_message("<span class='brass'>[src][spawn_message]</span>") A.visible_message("<span class='brass'>[src][spawn_message]</span>")
remove_servant_of_ratvar(S.brainmob, TRUE)
S.brainmob.mind.transfer_to(A) S.brainmob.mind.transfer_to(A)
add_servant_of_ratvar(A, TRUE)
user.drop_item() user.drop_item()
qdel(S) qdel(S)
qdel(src) qdel(src)

View File

@@ -540,7 +540,6 @@
ticker.mode.remove_revolutionary(newborgie, 0) ticker.mode.remove_revolutionary(newborgie, 0)
ticker.mode.remove_gangster(newborgie, 0, remove_bosses=1) ticker.mode.remove_gangster(newborgie, 0, remove_bosses=1)
ticker.mode.remove_hog_follower(newborgie, 0) ticker.mode.remove_hog_follower(newborgie, 0)
remove_servant_of_ratvar(newborgie.current, TRUE)
/datum/game_mode/proc/generate_station_goals() /datum/game_mode/proc/generate_station_goals()

View File

@@ -213,11 +213,10 @@
O.make_laws() O.make_laws()
ticker.mode.remove_antag_for_borging(BM.mind) ticker.mode.remove_antag_for_borging(BM.mind)
if(!M.clockwork)
remove_servant_of_ratvar(BM, TRUE)
BM.mind.transfer_to(O) BM.mind.transfer_to(O)
if(M.clockwork)
add_servant_of_ratvar(O)
if(O.mind && O.mind.special_role) 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.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 << "<span class='userdanger'>You have been robotized!</span>" O << "<span class='userdanger'>You have been robotized!</span>"

View File

@@ -283,6 +283,7 @@
#include "code\game\area\ai_monitored.dm" #include "code\game\area\ai_monitored.dm"
#include "code\game\area\areas.dm" #include "code\game\area\areas.dm"
#include "code\game\area\Space_Station_13_areas.dm" #include "code\game\area\Space_Station_13_areas.dm"
#include "code\game\gamemodes\antag_datum.dm"
#include "code\game\gamemodes\antag_hud.dm" #include "code\game\gamemodes\antag_hud.dm"
#include "code\game\gamemodes\antag_spawner.dm" #include "code\game\gamemodes\antag_spawner.dm"
#include "code\game\gamemodes\events.dm" #include "code\game\gamemodes\events.dm"