mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-24 00:51:26 +00:00
PDAs are dead, long live PDAs. All trace of old PDAs has been scoured from the codebase, and in its place are modular computer PDAs that are feature-equivalent. Essentially every PDA function except the Syndicate detonation feature and Notepad has been ported over, and battery life for handheld computers has been boosted alongside the addition of charging cables to make things easier.
595 lines
20 KiB
Plaintext
595 lines
20 KiB
Plaintext
/* Note from Carnie:
|
|
The way datum/mind stuff works has been changed a lot.
|
|
Minds now represent IC characters rather than following a client around constantly.
|
|
|
|
Guidelines for using minds properly:
|
|
|
|
- Never mind.transfer_to(ghost). The var/current and var/original of a mind must always be of type mob/living!
|
|
ghost.mind is however used as a reference to the ghost's corpse
|
|
|
|
- When creating a new mob for an existing IC character (e.g. cloning a dead guy or borging a brain of a human)
|
|
the existing mind of the old mob should be transfered to the new mob like so:
|
|
|
|
mind.transfer_to(new_mob)
|
|
|
|
- You must not assign key= or ckey= after transfer_to() since the transfer_to transfers the client for you.
|
|
By setting key or ckey explicitly after transfering the mind with transfer_to you will cause bugs like DCing
|
|
the player.
|
|
|
|
- IMPORTANT NOTE 2, if you want a player to become a ghost, use mob.ghostize() It does all the hard work for you.
|
|
|
|
- When creating a new mob which will be a new IC character (e.g. putting a shade in a construct or randomly selecting
|
|
a ghost to become a xeno during an event). Simply assign the key or ckey like you've always done.
|
|
|
|
new_mob.key = key
|
|
|
|
The Login proc will handle making a new mob for that mobtype (including setting up stuff like mind.name). Simple!
|
|
However if you want that mind to have any special properties like being a traitor etc you will have to do that
|
|
yourself.
|
|
|
|
*/
|
|
|
|
/datum/mind
|
|
var/key
|
|
var/name //replaces mob/var/original_name
|
|
var/mob/living/current
|
|
var/mob/living/original //This is being used now, don't remove it
|
|
var/active = 0
|
|
|
|
var/mob/living/admin_mob_placeholder = null
|
|
|
|
var/memory
|
|
|
|
var/assigned_role
|
|
var/special_role
|
|
|
|
var/role_alt_title
|
|
|
|
var/datum/job/assigned_job
|
|
var/datum/faction/selected_faction
|
|
|
|
var/list/datum/objective/objectives = list()
|
|
var/list/datum/objective/special_verbs = list()
|
|
|
|
var/has_been_rev = 0//Tracks if this mind has been a rev or not
|
|
|
|
var/datum/faction/faction //associated faction
|
|
var/datum/changeling/changeling //changeling holder
|
|
|
|
var/datum/vampire/vampire //vampire holder
|
|
|
|
var/rev_cooldown = 0
|
|
|
|
// the world.time since the mob has been brigged, or -1 if not at all
|
|
var/brigged_since = -1
|
|
|
|
// Custom signature data.
|
|
var/signature
|
|
var/signfont
|
|
|
|
//put this here for easier tracking ingame
|
|
var/datum/money_account/initial_account
|
|
|
|
var/last_words
|
|
var/ambitions
|
|
|
|
/datum/mind/New(var/key)
|
|
src.key = key
|
|
..()
|
|
|
|
/datum/mind/proc/handle_mob_deletion(mob/living/deleted_mob)
|
|
if (current == deleted_mob)
|
|
current.spellremove()
|
|
current = null
|
|
|
|
if (original == deleted_mob)
|
|
original = null
|
|
|
|
/datum/mind/proc/transfer_to(mob/living/new_character)
|
|
if(!istype(new_character))
|
|
world.log << "## DEBUG: transfer_to(): Some idiot has tried to transfer_to( a non mob/living mob. Please inform Carn"
|
|
if(current) //remove ourself from our old body's mind variable
|
|
if(changeling)
|
|
current.remove_changeling_powers()
|
|
current.verbs -= /datum/changeling/proc/EvolutionMenu
|
|
if(vampire)
|
|
current.remove_vampire_powers()
|
|
current.mind = null
|
|
|
|
SSnanoui.user_transferred(current, new_character) // transfer active NanoUI instances to new user
|
|
SSvueui.user_transferred(current, new_character)
|
|
if(current.client && ticket_panels[current.client])
|
|
var/datum/ticket_panel/tp = ticket_panels[current.client]
|
|
tp.ticket_panel_window.user = new_character
|
|
|
|
if(new_character.mind) //remove any mind currently in our new body's mind variable
|
|
new_character.mind.current = null
|
|
|
|
current = new_character //link ourself to our new body
|
|
new_character.mind = src //and link our new body to ourself
|
|
|
|
if(changeling)
|
|
new_character.make_changeling()
|
|
if(vampire)
|
|
new_character.make_vampire()
|
|
if(active)
|
|
new_character.key = key //now transfer the key to link the client to our new body
|
|
|
|
/datum/mind/proc/store_memory(new_text)
|
|
. = length(memory + new_text)
|
|
|
|
if (. > MAX_PAPER_MESSAGE_LEN)
|
|
memory = copytext(memory, . - MAX_PAPER_MESSAGE_LEN, .)
|
|
else
|
|
memory += "[new_text]<BR>"
|
|
|
|
/datum/mind/proc/show_memory(mob/recipient)
|
|
var/output = "<B>[current.real_name]'s Memory</B><HR>"
|
|
output += memory
|
|
|
|
if(ambitions)
|
|
output += "<HR><B>Ambitions:</B> [ambitions]<br>"
|
|
|
|
if(objectives.len>0)
|
|
output += "<HR><B>Objectives:</B>"
|
|
|
|
var/obj_count = 1
|
|
for(var/datum/objective/objective in objectives)
|
|
output += "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
|
|
obj_count++
|
|
|
|
var/datum/browser/memory_win = new(recipient, "memory")
|
|
memory_win.set_content(output)
|
|
memory_win.open()
|
|
|
|
/datum/mind/proc/edit_memory()
|
|
if(!ROUND_IS_STARTED)
|
|
alert("Not before round-start!", "Alert")
|
|
return
|
|
|
|
var/out = "<B>[name]</B>[(current&&(current.real_name!=name))?" (as [current.real_name])":""]<br>"
|
|
out += "Mind currently owned by key: [key] [active?"(synced)":"(not synced)"]<br>"
|
|
out += "Assigned role: [assigned_role]. <a href='?src=\ref[src];role_edit=1'>Edit</a><br>"
|
|
out += "<hr>"
|
|
out += "Factions and special roles:<br><table>"
|
|
for(var/antag_type in all_antag_types)
|
|
var/datum/antagonist/antag = all_antag_types[antag_type]
|
|
out += "[antag.get_panel_entry(src)]"
|
|
out += "</table><hr>"
|
|
out += "<b>Objectives</b></br>"
|
|
|
|
if(objectives && objectives.len)
|
|
var/num = 1
|
|
for(var/datum/objective/O in objectives)
|
|
out += "<b>Objective #[num]:</b> [O.explanation_text] "
|
|
if(O.completed)
|
|
out += "(<span class='good'>complete</span>)"
|
|
else
|
|
out += "(<span class='warning'>incomplete</span>)"
|
|
out += " <a href='?src=\ref[src];obj_completed=\ref[O]'>\[toggle\]</a>"
|
|
out += " <a href='?src=\ref[src];obj_delete=\ref[O]'>\[remove\]</a><br>"
|
|
num++
|
|
out += "<br><a href='?src=\ref[src];obj_announce=1'>\[announce objectives\]</a>"
|
|
|
|
else
|
|
out += "None."
|
|
out += "<br><a href='?src=\ref[src];obj_add=1'>\[add\]</a>"
|
|
out += "<b>Ambitions:</b> [ambitions ? ambitions : "None"] <a href='?src=\ref[src];amb_edit=\ref[src]'>\[edit\]</a></br>"
|
|
usr << browse(out, "window=edit_memory[src]")
|
|
|
|
/datum/mind/Topic(href, href_list)
|
|
if(!check_rights(R_ADMIN)) return
|
|
|
|
if(current && isliving(current))
|
|
if(href_list["set_psi_faculty"] && href_list["set_psi_faculty_rank"])
|
|
current.set_psi_rank(href_list["set_psi_faculty"], text2num(href_list["set_psi_faculty_rank"]))
|
|
return TRUE
|
|
|
|
if(href_list["add_antagonist"])
|
|
var/datum/antagonist/antag = all_antag_types[href_list["add_antagonist"]]
|
|
if(antag)
|
|
if(antag.add_antagonist(src, 1, 1, 0, 1, 1)) // Ignore equipment and role type for this.
|
|
log_admin("[key_name_admin(usr)] made [key_name(src, highlight_special = 1)] into a [antag.role_text].",admin_key=key_name(usr),ckey=key_name(src))
|
|
else
|
|
to_chat(usr, "<span class='warning'>[src] could not be made into a [antag.role_text]!</span>")
|
|
|
|
else if(href_list["remove_antagonist"])
|
|
var/datum/antagonist/antag = all_antag_types[href_list["remove_antagonist"]]
|
|
if(antag) antag.remove_antagonist(src)
|
|
|
|
else if(href_list["equip_antagonist"])
|
|
var/datum/antagonist/antag = all_antag_types[href_list["equip_antagonist"]]
|
|
if(antag) antag.equip(src.current)
|
|
|
|
else if(href_list["unequip_antagonist"])
|
|
var/datum/antagonist/antag = all_antag_types[href_list["unequip_antagonist"]]
|
|
if(antag) antag.unequip(src.current)
|
|
|
|
else if(href_list["move_antag_to_spawn"])
|
|
var/datum/antagonist/antag = all_antag_types[href_list["move_antag_to_spawn"]]
|
|
if(antag) antag.place_mob(src.current)
|
|
|
|
else if (href_list["role_edit"])
|
|
var/new_role = input("Select new role", "Assigned role", assigned_role) as null|anything in joblist
|
|
if (!new_role) return
|
|
assigned_role = new_role
|
|
|
|
else if (href_list["memory_edit"])
|
|
var/new_memo = sanitize(input("Write new memory", "Memory", memory) as null|message)
|
|
if (isnull(new_memo)) return
|
|
memory = new_memo
|
|
|
|
else if (href_list["amb_edit"])
|
|
var/new_ambition = input("Enter a new ambition", "Memory",html_decode(src.ambitions)) as null|message
|
|
if(isnull(new_ambition))
|
|
return
|
|
src.ambitions = sanitize(new_ambition)
|
|
to_chat(src.current, "<span class='warning'>Your ambitions have been changed by higher powers, they are now: [src.ambitions]</span>")
|
|
|
|
else if (href_list["obj_edit"] || href_list["obj_add"])
|
|
var/datum/objective/objective
|
|
var/objective_pos
|
|
var/def_value
|
|
|
|
if (href_list["obj_edit"])
|
|
objective = locate(href_list["obj_edit"])
|
|
if (!objective) return
|
|
objective_pos = objectives.Find(objective)
|
|
|
|
//Text strings are easy to manipulate. Revised for simplicity.
|
|
var/temp_obj_type = "[objective.type]"//Convert path into a text string.
|
|
def_value = copytext(temp_obj_type, 19)//Convert last part of path into an objective keyword.
|
|
if(!def_value)//If it's a custom objective, it will be an empty string.
|
|
def_value = "custom"
|
|
|
|
var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "debrain", "protect", "prevent", "harm", "brig", "hijack", "escape", "survive", "steal", "download", "mercenary", "capture", "absorb", "custom")
|
|
if (!new_obj_type) return
|
|
|
|
var/datum/objective/new_objective = null
|
|
|
|
switch (new_obj_type)
|
|
if ("assassinate","protect","debrain", "harm", "brig")
|
|
//To determine what to name the objective in explanation text.
|
|
var/objective_type_capital = uppertext(copytext(new_obj_type, 1,2))//Capitalize first letter.
|
|
var/objective_type_text = copytext(new_obj_type, 2)//Leave the rest of the text.
|
|
var/objective_type = "[objective_type_capital][objective_type_text]"//Add them together into a text string.
|
|
|
|
var/list/possible_targets = list("Free objective")
|
|
for(var/datum/mind/possible_target in SSticker.minds)
|
|
if ((possible_target != src) && istype(possible_target.current, /mob/living/carbon/human))
|
|
possible_targets += possible_target.current
|
|
|
|
var/mob/def_target = null
|
|
var/objective_list[] = list(/datum/objective/assassinate, /datum/objective/protect, /datum/objective/debrain)
|
|
if (objective&&(objective.type in objective_list) && objective:target)
|
|
def_target = objective.target.current
|
|
|
|
var/new_target = input("Select target:", "Objective target", def_target) as null|anything in possible_targets
|
|
if (!new_target) return
|
|
|
|
var/objective_path = text2path("/datum/objective/[new_obj_type]")
|
|
var/mob/living/M = new_target
|
|
if (!istype(M) || !M.mind || new_target == "Free objective")
|
|
new_objective = new objective_path
|
|
new_objective.owner = src
|
|
new_objective:target = null
|
|
new_objective.explanation_text = "Free objective"
|
|
else
|
|
new_objective = new objective_path
|
|
new_objective.owner = src
|
|
new_objective:target = M.mind
|
|
new_objective.explanation_text = "[objective_type] [M.real_name], the [M.mind.special_role ? M.mind:special_role : M.mind:assigned_role]."
|
|
|
|
if ("prevent")
|
|
new_objective = new /datum/objective/block
|
|
new_objective.owner = src
|
|
|
|
if ("hijack")
|
|
new_objective = new /datum/objective/hijack
|
|
new_objective.owner = src
|
|
|
|
if ("escape")
|
|
new_objective = new /datum/objective/escape
|
|
new_objective.owner = src
|
|
|
|
if ("survive")
|
|
new_objective = new /datum/objective/survive
|
|
new_objective.owner = src
|
|
|
|
if ("mercenary")
|
|
new_objective = new /datum/objective/nuclear
|
|
new_objective.owner = src
|
|
|
|
if ("steal")
|
|
if (!istype(objective, /datum/objective/steal))
|
|
new_objective = new /datum/objective/steal
|
|
new_objective.owner = src
|
|
else
|
|
new_objective = objective
|
|
var/datum/objective/steal/steal = new_objective
|
|
if (!steal.select_target())
|
|
return
|
|
|
|
if("download","capture","absorb")
|
|
var/def_num
|
|
if(objective&&objective.type==text2path("/datum/objective/[new_obj_type]"))
|
|
def_num = objective.target_amount
|
|
|
|
var/target_number = input("Input target number:", "Objective", def_num) as num|null
|
|
if (isnull(target_number))//Ordinarily, you wouldn't need isnull. In this case, the value may already exist.
|
|
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."
|
|
new_objective.owner = src
|
|
new_objective.target_amount = target_number
|
|
|
|
if ("custom")
|
|
var/expl = sanitize(input("Custom objective:", "Objective", objective ? objective.explanation_text : "") as text|null)
|
|
if (!expl) return
|
|
new_objective = new /datum/objective
|
|
new_objective.owner = src
|
|
new_objective.explanation_text = expl
|
|
|
|
if (!new_objective) return
|
|
|
|
if (objective)
|
|
objectives -= objective
|
|
objectives.Insert(objective_pos, new_objective)
|
|
else
|
|
objectives += new_objective
|
|
|
|
else if (href_list["obj_delete"])
|
|
var/datum/objective/objective = locate(href_list["obj_delete"])
|
|
if(!istype(objective)) return
|
|
objectives -= objective
|
|
|
|
else if(href_list["obj_completed"])
|
|
var/datum/objective/objective = locate(href_list["obj_completed"])
|
|
if(!istype(objective)) return
|
|
objective.completed = !objective.completed
|
|
|
|
else if(href_list["implant"])
|
|
var/mob/living/carbon/human/H = current
|
|
|
|
BITSET(H.hud_updateflag, IMPLOYAL_HUD) // updates that players HUD images so secHUD's pick up they are implanted or not.
|
|
|
|
switch(href_list["implant"])
|
|
if("remove")
|
|
for(var/obj/item/implant/mindshield/I in H.contents)
|
|
for(var/obj/item/organ/external/organs in H.organs)
|
|
if(I in organs.implants)
|
|
qdel(I)
|
|
break
|
|
to_chat(H, "<span class='notice'><font size =3><B>Your loyalty implant has been deactivated.</B></font></span>")
|
|
log_admin("[key_name_admin(usr)] has de-loyalty implanted [current].",admin_key=key_name(usr),ckey=key_name(usr))
|
|
if("add")
|
|
to_chat(H, "<span class='danger'><font size =3>You somehow have become the recepient of a loyalty transplant, and it just activated!</font></span>")
|
|
H.implant_loyalty(H, override = TRUE)
|
|
log_admin("[key_name_admin(usr)] has loyalty implanted [current].",admin_key=key_name(usr),ckey=key_name(usr))
|
|
else
|
|
else if (href_list["silicon"])
|
|
BITSET(current.hud_updateflag, SPECIALROLE_HUD)
|
|
switch(href_list["silicon"])
|
|
|
|
if("unemag")
|
|
var/mob/living/silicon/robot/R = current
|
|
if (istype(R))
|
|
R.emagged = 0
|
|
if (R.activated(R.module.emag))
|
|
R.set_module_active(null)
|
|
if(R.module_state_1 == R.module.emag)
|
|
R.module_state_1 = null
|
|
R.contents -= R.module.emag
|
|
else if(R.module_state_2 == R.module.emag)
|
|
R.module_state_2 = null
|
|
R.contents -= R.module.emag
|
|
else if(R.module_state_3 == R.module.emag)
|
|
R.module_state_3 = null
|
|
R.contents -= R.module.emag
|
|
log_admin("[key_name_admin(usr)] has unemag'ed [R].",admin_key=key_name(usr),ckey_target=key_name(R))
|
|
|
|
if("unemagcyborgs")
|
|
if (istype(current, /mob/living/silicon/ai))
|
|
var/mob/living/silicon/ai/ai = current
|
|
for (var/mob/living/silicon/robot/R in ai.connected_robots)
|
|
R.emagged = 0
|
|
if (R.module)
|
|
if (R.activated(R.module.emag))
|
|
R.set_module_active(null)
|
|
if(R.module_state_1 == R.module.emag)
|
|
R.module_state_1 = null
|
|
R.contents -= R.module.emag
|
|
else if(R.module_state_2 == R.module.emag)
|
|
R.module_state_2 = null
|
|
R.contents -= R.module.emag
|
|
else if(R.module_state_3 == R.module.emag)
|
|
R.module_state_3 = null
|
|
R.contents -= R.module.emag
|
|
log_admin("[key_name_admin(usr)] has unemag'ed [ai]'s Cyborgs.",admin_key=key_name(usr),ckey_target=key_name(ai))
|
|
|
|
else if (href_list["common"])
|
|
switch(href_list["common"])
|
|
if("undress")
|
|
for(var/obj/item/W in current)
|
|
current.drop_from_inventory(W)
|
|
if("takeuplink")
|
|
take_uplink()
|
|
memory = null//Remove any memory they may have had.
|
|
if("crystals")
|
|
if (usr.client.holder.rights & R_FUN)
|
|
var/obj/item/device/uplink/hidden/suplink = find_syndicate_uplink()
|
|
var/crystals
|
|
if (suplink)
|
|
crystals = suplink.uses
|
|
crystals = input("Amount of telecrystals for [key]","Operative uplink", crystals) as null|num
|
|
if (!isnull(crystals))
|
|
if (suplink)
|
|
suplink.uses = crystals
|
|
|
|
else if (href_list["obj_announce"])
|
|
var/obj_count = 1
|
|
to_chat(current, "<span class='notice'>Your current objectives:</span>")
|
|
for(var/datum/objective/objective in objectives)
|
|
to_chat(current, "<B>Objective #[obj_count]</B>: [objective.explanation_text]")
|
|
obj_count++
|
|
edit_memory()
|
|
|
|
/datum/mind/proc/find_syndicate_uplink()
|
|
var/list/L = current.get_contents()
|
|
for (var/obj/item/I in L)
|
|
if (I.hidden_uplink)
|
|
return I.hidden_uplink
|
|
return null
|
|
|
|
/datum/mind/proc/take_uplink()
|
|
var/obj/item/device/uplink/hidden/H = find_syndicate_uplink()
|
|
if(H)
|
|
qdel(H)
|
|
|
|
|
|
// check whether this mind's mob has been brigged for the given duration
|
|
// have to call this periodically for the duration to work properly
|
|
/datum/mind/proc/is_brigged(duration)
|
|
var/turf/T = current.loc
|
|
if(isnull(T))
|
|
brigged_since = -1
|
|
return 0
|
|
var/area/A = T.loc
|
|
var/is_currently_brigged = 0
|
|
if(A?.is_prison())
|
|
is_currently_brigged = 1
|
|
if(current.GetIdCard())
|
|
is_currently_brigged = 0
|
|
|
|
if(!is_currently_brigged)
|
|
brigged_since = -1
|
|
return 0
|
|
|
|
if(brigged_since == -1)
|
|
brigged_since = world.time
|
|
|
|
return (duration <= world.time - brigged_since)
|
|
|
|
/datum/mind/proc/reset()
|
|
assigned_role = null
|
|
special_role = null
|
|
role_alt_title = null
|
|
assigned_job = null
|
|
//faction = null //Uncommenting this causes a compile error due to 'undefined type', fucked if I know.
|
|
changeling = null
|
|
vampire = null
|
|
initial_account = null
|
|
objectives = list()
|
|
special_verbs = list()
|
|
has_been_rev = 0
|
|
rev_cooldown = 0
|
|
brigged_since = -1
|
|
|
|
//Antagonist role check
|
|
/mob/living/proc/check_special_role(role)
|
|
if(mind)
|
|
if(!role)
|
|
return mind.special_role
|
|
else
|
|
return (mind.special_role == role) ? 1 : 0
|
|
else
|
|
return 0
|
|
|
|
//Initialisation procs
|
|
/mob/living/proc/mind_initialize()
|
|
if(mind)
|
|
mind.key = key
|
|
else
|
|
mind = new /datum/mind(key)
|
|
mind.original = src
|
|
SSticker.minds += mind
|
|
if(!mind.name)
|
|
mind.name = real_name
|
|
|
|
if (client)
|
|
if (client.prefs.signature)
|
|
mind.signature = client.prefs.signature
|
|
if (client.prefs.signfont)
|
|
mind.signfont = client.prefs.signfont
|
|
mind.current = src
|
|
|
|
//HUMAN
|
|
/mob/living/carbon/human/mind_initialize()
|
|
..()
|
|
if(!mind.assigned_role)
|
|
mind.assigned_role = "Assistant" //defualt
|
|
|
|
//slime
|
|
/mob/living/carbon/slime/mind_initialize()
|
|
..()
|
|
mind.assigned_role = "slime"
|
|
|
|
/mob/living/carbon/alien/larva
|
|
icon_state = "larva0"
|
|
|
|
/mob/living/carbon/alien/larva/mind_initialize()
|
|
..()
|
|
mind.special_role = "Larva"
|
|
|
|
//AI
|
|
/mob/living/silicon/ai/mind_initialize()
|
|
..()
|
|
mind.assigned_role = "AI"
|
|
|
|
//BORG
|
|
/mob/living/silicon/robot/mind_initialize()
|
|
..()
|
|
mind.assigned_role = "Cyborg"
|
|
|
|
//PAI
|
|
/mob/living/silicon/pai/mind_initialize()
|
|
..()
|
|
mind.assigned_role = "pAI"
|
|
mind.special_role = ""
|
|
|
|
//Animals
|
|
/mob/living/simple_animal/shade/mind_initialize()
|
|
..()
|
|
mind.assigned_role = "Shade"
|
|
|
|
/mob/living/simple_animal/construct/builder/mind_initialize()
|
|
..()
|
|
mind.assigned_role = "Artificer"
|
|
mind.special_role = "Cultist"
|
|
|
|
/mob/living/simple_animal/construct/wraith/mind_initialize()
|
|
..()
|
|
mind.assigned_role = "Wraith"
|
|
mind.special_role = "Cultist"
|
|
|
|
/mob/living/simple_animal/construct/armored/mind_initialize()
|
|
..()
|
|
mind.assigned_role = "Juggernaut"
|
|
mind.special_role = "Cultist"
|
|
|
|
/mob/living/silicon/robot/syndicate/mind_initialize()
|
|
..()
|
|
mind.assigned_role = "Syndicate Robot"
|
|
mind.special_role = "Mercenary"
|
|
|
|
/mob/living/simple_animal/hostile/faithless/wizard/mind_initialize()
|
|
..()
|
|
mind.assigned_role = "Space Wizard"
|
|
|
|
/mob/living/simple_animal/familiar/mind_initialize()
|
|
..()
|
|
mind.assigned_role = "Familiar"
|
|
|
|
/mob/living/simple_animal/rat/familiar/familiar/mind_initialize()
|
|
..()
|
|
mind.assigned_role = "Familiar"
|