diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 4dbe7141aac..915bf455b66 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -1,1686 +1,1580 @@
-/* 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/active = 0
-
- var/memory
-
- var/assigned_role
- var/special_role
- var/list/restricted_roles = list()
-
- var/datum/job/assigned_job
-
- var/list/datum/objective/objectives = list()
- var/list/datum/objective/special_verbs = list()
-
- var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button.
-
- var/datum/faction/faction //associated faction
- var/datum/changeling/changeling //changeling holder
-
- var/miming = 0 // Mime's vow of silence
- var/antag_hud_icon_state = null //this mind's ANTAG_HUD should have this icon_state
- var/datum/atom_hud/antag/antag_hud = null //this mind's antag HUD
- var/datum/gang/gang_datum //Which gang this mind belongs to, if any
-
-/datum/mind/New(var/key)
- src.key = key
-
-
-/datum/mind/proc/transfer_to(mob/new_character)
- if(current) // remove ourself from our old body's mind variable
- current.mind = null
- SSnano.on_transfer(current, new_character)
-
- if(key)
- if(new_character.key != key) //if we're transfering into a body with a key associated which is not ours
- new_character.ghostize(1) //we'll need to ghostize so that key isn't mobless.
- else
- key = new_character.key
-
- if(new_character.mind) //disassociate any mind currently in our new body's mind variable
- new_character.mind.current = null
-
- 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
- new_character.mind = src //and associate our new body with ourself
- transfer_antag_huds(hud_to_transfer) //inherit the antag HUD
- transfer_actions(new_character)
-
- 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)
- memory += "[new_text]
"
-
-/datum/mind/proc/wipe_memory()
- memory = null
-
-
-/*
- Removes antag type's references from a mind.
- objectives, uplinks, powers etc are all handled.
-*/
-
-/datum/mind/proc/remove_objectives()
- if(objectives.len)
- for(var/datum/objective/O in objectives)
- objectives -= O
- qdel(O)
-
-/datum/mind/proc/remove_changeling()
- if(src in ticker.mode.changelings)
- ticker.mode.changelings -= src
- current.remove_changeling_powers()
- if(changeling)
- qdel(changeling)
- changeling = null
- special_role = null
- remove_antag_equip()
-
-/datum/mind/proc/remove_traitor()
- if(src in ticker.mode.traitors)
- ticker.mode.traitors -= src
- if(isAI(current))
- var/mob/living/silicon/ai/A = current
- A.set_zeroth_law("")
- A.show_laws()
- A.verbs -= /mob/living/silicon/ai/proc/choose_modules
- A.malf_picker.remove_verbs(A)
- qdel(A.malf_picker)
- special_role = null
- remove_antag_equip()
-
-/datum/mind/proc/remove_nukeop()
- if(src in ticker.mode.syndicates)
- ticker.mode.syndicates -= src
- ticker.mode.update_synd_icons_removed(src)
- special_role = null
- remove_objectives()
- remove_antag_equip()
-
-/datum/mind/proc/remove_wizard()
- if(src in ticker.mode.wizards)
- ticker.mode.wizards -= src
- current.spellremove(current)
- special_role = null
- remove_antag_equip()
-
-/datum/mind/proc/remove_cultist()
- if(src in ticker.mode.cult)
- ticker.mode.cult -= src
- ticker.mode.update_cult_icons_removed(src)
- special_role = null
-
-/datum/mind/proc/remove_rev()
- if(src in ticker.mode.revolutionaries)
- ticker.mode.revolutionaries -= src
- ticker.mode.update_rev_icons_removed(src)
- if(src in ticker.mode.head_revolutionaries)
- ticker.mode.head_revolutionaries -= src
- ticker.mode.update_rev_icons_removed(src)
- special_role = null
- remove_objectives()
- remove_antag_equip()
-
-
-/datum/mind/proc/remove_gang()
- ticker.mode.remove_gangster(src,0,1,1)
- remove_objectives()
-
-/datum/mind/proc/remove_hog_follower_prophet()
- ticker.mode.red_deity_followers -= src
- ticker.mode.red_deity_prophets -= src
- ticker.mode.blue_deity_prophets -= src
- ticker.mode.blue_deity_followers -= src
- ticker.mode.update_hog_icons_removed(src, "red")
- ticker.mode.update_hog_icons_removed(src, "blue")
-
-
-
-/datum/mind/proc/remove_antag_equip()
- var/list/Mob_Contents = current.get_contents()
- for(var/obj/item/I in Mob_Contents)
- if(istype(I, /obj/item/device/pda))
- var/obj/item/device/pda/P = I
- P.lock_code = ""
-
- else if(istype(I, /obj/item/device/radio))
- var/obj/item/device/radio/R = I
- R.traitor_frequency = 0
-
-/datum/mind/proc/remove_all_antag() //For the Lazy amongst us.
- remove_changeling()
- remove_traitor()
- remove_nukeop()
- remove_wizard()
- remove_cultist()
- remove_rev()
- remove_gang()
-
-/datum/mind/proc/show_memory(mob/recipient, window=1)
- if(!recipient)
- recipient = current
- var/output = "[current.real_name]'s Memories:
"
- output += memory
-
- if(objectives.len)
- output += "Objectives:"
- var/obj_count = 1
- for(var/datum/objective/objective in objectives)
- output += "
Objective #[obj_count++]: [objective.explanation_text]"
-
- if(window) recipient << browse(output,"window=memory")
- else recipient << "[output]"
-
-/datum/mind/proc/edit_memory()
- if(!ticker || !ticker.mode)
- alert("Not before round-start!", "Alert")
- return
-
- var/out = "[name][(current&&(current.real_name!=name))?" (as [current.real_name])":""]
"
- out += "Mind currently owned by key: [key] [active?"(synced)":"(not synced)"]
"
- out += "Assigned role: [assigned_role]. Edit
"
- out += "Faction and special role: [special_role]
"
-
- var/list/sections = list(
- "revolution",
- "gang",
- "cult",
- "wizard",
- "changeling",
- "nuclear",
- "traitor", // "traitorchan",
- "monkey",
- )
- var/text = ""
-
- if (istype(current, /mob/living/carbon/human) || istype(current, /mob/living/carbon/monkey))
- /** REVOLUTION ***/
- text = "revolution"
- if (ticker.mode.config_tag=="revolution")
- text = uppertext(text)
- text = "[text]: "
- if (assigned_role in command_positions)
- text += "HEAD|loyal|employee|headrev|rev"
- else if (src in ticker.mode.head_revolutionaries)
- text += "head|loyal|employee|HEADREV|rev"
- text += "
Flash: give"
-
- var/list/L = current.get_contents()
- var/obj/item/device/assembly/flash/flash = locate() in L
- if (flash)
- if(!flash.crit_fail)
- text += "|take."
- else
- text += "|take|repair."
- else
- text += "."
-
- text += " Reequip (gives traitor uplink)."
- if (objectives.len==0)
- text += "
Objectives are empty! Set to kill all heads."
- else if(isloyal(current))
- text += "head|LOYAL|employee|headrev|rev"
- else if (src in ticker.mode.revolutionaries)
- text += "head|loyal|employee|headrev|REV"
- else
- text += "head|loyal|EMPLOYEE|headrev|rev"
-
- if(current && current.client && (ROLE_REV in current.client.prefs.be_special))
- text += "|Enabled in Prefs"
- else
- text += "|Disabled in Prefs"
-
- sections["revolution"] = text
-
- /** GANG ***/
- text = "gang"
- if (ticker.mode.config_tag=="gang")
- text = uppertext(text)
- text = "[text]: "
- text += "[isloyal(current) ? "LOYAL" : "loyal"]|"
- if(src in ticker.mode.get_all_gangsters())
- text += "none"
- else
- text += "NONE"
-
- if(current && current.client && (ROLE_GANG in current.client.prefs.be_special))
- text += "|Enabled in Prefs
"
- else
- text += "|Disabled in Prefs
"
-
- for(var/datum/gang/G in ticker.mode.gangs)
- text += "[G.name]: "
- if(src in (G.gangsters))
- text += "GANGSTER"
- else
- text += "gangster"
- text += "|"
- if(src in (G.bosses))
- text += "GANG LEADER"
- text += "|Equipment: give"
- var/list/L = current.get_contents()
- var/obj/item/device/gangtool/gangtool = locate() in L
- if (gangtool)
- text += "|take"
-
- else
- text += "gang leader"
- text += "
"
-
- if(gang_colors_pool.len)
- text += "Create New Gang"
-
- sections["gang"] = text
-
-
- /** CULT ***/
- text = "cult"
- if (ticker.mode.config_tag=="cult")
- text = uppertext(text)
- text = "[text]: "
- if (src in ticker.mode.cult)
- text += "loyal|employee|CULTIST"
- text += "
Equip"
-
- else if(isloyal(current))
- text += "LOYAL|employee|cultist"
- else
- text += "loyal|EMPLOYEE|cultist"
-
- if(current && current.client && (ROLE_CULTIST in current.client.prefs.be_special))
- text += "|Enabled in Prefs"
- else
- text += "|Disabled in Prefs"
-
- sections["cult"] = text
-
- /** WIZARD ***/
- text = "wizard"
- if (ticker.mode.config_tag=="wizard")
- text = uppertext(text)
- text = "[text]: "
- if ((src in ticker.mode.wizards) || (src in ticker.mode.apprentices))
- text += "YES|no"
- text += "
To lair, undress, dress up, let choose name."
- if (objectives.len==0)
- text += "
Objectives are empty! Randomize!"
- else
- text += "yes|NO"
-
- if(current && current.client && (ROLE_WIZARD in current.client.prefs.be_special))
- text += "|Enabled in Prefs"
- else
- text += "|Disabled in Prefs"
-
- sections["wizard"] = text
-
- /** CHANGELING ***/
- text = "changeling"
- if (ticker.mode.config_tag=="changeling" || ticker.mode.config_tag=="traitorchan")
- text = uppertext(text)
- text = "[text]: "
- if ((src in ticker.mode.changelings) && special_role)
- text += "YES|no"
- if (objectives.len==0)
- text += "
Objectives are empty! Randomize!"
- if(changeling && changeling.stored_profiles.len && (current.real_name != changeling.first_prof.name) )
- text += "
Transform to initial appearance."
- else if(src in ticker.mode.changelings) //Station Aligned Changeling
- text += "YES (but not an antag)|no"
- if (objectives.len==0)
- text += "
Objectives are empty! Randomize!"
- if(changeling && changeling.stored_profiles.len && (current.real_name != changeling.first_prof.name) )
- text += "
Transform to initial appearance."
- else
- text += "yes|NO"
-// var/datum/game_mode/changeling/changeling = ticker.mode
-// if (istype(changeling) && changeling.changelingdeath)
-// text += "
All the changelings are dead! Restart in [round((changeling.TIME_TO_GET_REVIVED-(world.time-changeling.changelingdeathtime))/10)] seconds."
-
- if(current && current.client && (ROLE_CHANGELING in current.client.prefs.be_special))
- text += "|Enabled in Prefs"
- else
- text += "|Disabled in Prefs"
-
- sections["changeling"] = text
-
- /** NUCLEAR ***/
- text = "nuclear"
- if (ticker.mode.config_tag=="nuclear")
- text = uppertext(text)
- text = "[text]: "
- if (src in ticker.mode.syndicates)
- text += "OPERATIVE|nanotrasen"
- text += "
To shuttle, undress, dress up."
- var/code
- for (var/obj/machinery/nuclearbomb/bombue in machines)
- if (length(bombue.r_code) <= 5 && bombue.r_code != "LOLNO" && bombue.r_code != "ADMIN")
- code = bombue.r_code
- break
- if (code)
- text += " Code is [code]. tell the code."
- else
- text += "operative|NANOTRASEN"
-
- if(current && current.client && (ROLE_OPERATIVE in current.client.prefs.be_special))
- text += "|Enabled in Prefs"
- else
- text += "|Disabled in Prefs"
-
- sections["nuclear"] = text
-
- /** TRAITOR ***/
- text = "traitor"
- if (ticker.mode.config_tag=="traitor" || ticker.mode.config_tag=="traitorchan")
- text = uppertext(text)
- text = "[text]: "
- if (src in ticker.mode.traitors)
- text += "TRAITOR|loyal"
- if (objectives.len==0)
- text += "
Objectives are empty! Randomize!"
- else
- text += "traitor|LOYAL"
-
- if(current && current.client && (ROLE_TRAITOR in current.client.prefs.be_special))
- text += "|Enabled in Prefs"
- else
- text += "|Disabled in Prefs"
-
- sections["traitor"] = text
-
- /** SHADOWLING **/
- text = "shadowling"
- if(ticker.mode.config_tag == "shadowling")
- text = uppertext(text)
- text = "[text]: "
- if(src in ticker.mode.shadows)
- text += "SHADOWLING|thrall|human"
- else if(src in ticker.mode.thralls)
- text += "shadowling|THRALL|human"
- else
- text += "shadowling|thrall|HUMAN"
-
- if(current && current.client && (ROLE_SHADOWLING in current.client.prefs.be_special))
- text += "|Enabled in Prefs"
- else
- text += "|Disabled in Prefs"
-
- sections["shadowling"] = text
-
- /** Abductors **/
-
- text = "Abductor"
- if(ticker.mode.config_tag == "abductor")
- text = uppertext(text)
- text = "[text]: "
- if(src in ticker.mode.abductors)
- text += "Abductor|human"
- text += "|undress|equip"
- else
- text += "Abductor|human"
-
- if(current && current.client && (ROLE_ABDUCTOR in current.client.prefs.be_special))
- text += "|Enabled in Prefs"
- else
- text += "|Disabled in Prefs"
-
- sections["abductor"] = text
-
- /** HAND OF GOD **/
- text = "hand of god"
- if(ticker.mode.config_tag == "handofgod")
- text = uppertext(text)
- text = "[text]: "
- if(src in ticker.mode.red_deity_prophets)
- text += "RED PROPHET|red follower|employee|blue follower|blue prophet|red god|blue god"
- else if (src in ticker.mode.red_deity_followers)
- text += "red prophet|RED FOLLOWER|employee|blue follower|blue prophet|red god|blue god"
- else if (src in ticker.mode.blue_deity_followers)
- text += "red prophet|red follower|employee|BLUE FOLLOWER|blue prophet|red god|blue god"
- else if (src in ticker.mode.blue_deity_prophets)
- text += "red prophet|red follower|employee|blue follower|BLUE PROPHET|red god|blue god"
- else if (src in ticker.mode.red_deities)
- text += "red prophet|red follower|employee|blue follower|blue prophet|RED GOD|blue god"
- else if (src in ticker.mode.blue_deities)
- text += "red prophet|red follower|employee|blue follower|blue prophet|red god|BLUE GOD"
- else
- text += "red prophet|red follower|EMPLOYEE|blue follower|blue prophet|red god|blue god"
-
- if(current && current.client && (ROLE_HOG_GOD in current.client.prefs.be_special))
- text += "|HOG God Enabled in Prefs"
- else
- text += "|HOG God Disabled in Prefs"
-
- if(current && current.client && (ROLE_HOG_CULTIST in current.client.prefs.be_special))
- text += "|HOG Cultist Enabled in Prefs"
- else
- text += "|HOG Disabled in Prefs"
-
- sections["follower"] = text
-
- /** MONKEY ***/
- if (istype(current, /mob/living/carbon))
- text = "monkey"
- if (ticker.mode.config_tag=="monkey")
- text = uppertext(text)
- text = "[text]: "
- if (istype(current, /mob/living/carbon/human))
- text += "healthy|infected|HUMAN|other"
- else if (istype(current, /mob/living/carbon/monkey))
- var/found = 0
- for(var/datum/disease/D in current.viruses)
- if(istype(D, /datum/disease/transformation/jungle_fever)) found = 1
-
- if(found)
- text += "healthy|INFECTED|human|other"
- else
- text += "HEALTHY|infected|human|other"
-
- else
- text += "healthy|infected|human|OTHER"
-
- if(current && current.client && (ROLE_MONKEY in current.client.prefs.be_special))
- text += "|Enabled in Prefs"
- else
- text += "|Disabled in Prefs"
-
- sections["monkey"] = text
-
-
- /** SILICON ***/
-
- if (istype(current, /mob/living/silicon))
- text = "silicon"
- var/mob/living/silicon/robot/robot = current
- if (istype(robot) && robot.emagged)
- text += "
Cyborg: Is emagged! Unemag!
0th law: [robot.laws.zeroth]"
- var/mob/living/silicon/ai/ai = current
- if (istype(ai) && ai.connected_robots.len)
- var/n_e_robots = 0
- for (var/mob/living/silicon/robot/R in ai.connected_robots)
- if (R.emagged)
- n_e_robots++
- text += "
[n_e_robots] of [ai.connected_robots.len] slaved cyborgs are emagged. Unemag"
- if (ticker.mode.config_tag == "traitorchan")
- if (sections["traitor"])
- out += sections["traitor"]+"
"
- if (sections["changeling"])
- out += sections["changeling"]+"
"
- sections -= "traitor"
- sections -= "changeling"
- else
- if (sections[ticker.mode.config_tag])
- out += sections[ticker.mode.config_tag]+"
"
- sections -= ticker.mode.config_tag
- for (var/i in sections)
- if (sections[i])
- out += sections[i]+"
"
-
-
- if (((src in ticker.mode.head_revolutionaries) || \
- (src in ticker.mode.traitors) || \
- (src in ticker.mode.syndicates)) && \
- istype(current,/mob/living/carbon/human) )
-
- text = "Uplink: give"
- var/obj/item/device/uplink/hidden/suplink = find_syndicate_uplink()
- var/crystals
- if (suplink)
- crystals = suplink.uses
- if (suplink)
- text += "|take"
- if (check_rights(R_FUN, 0))
- text += ", [crystals] crystals"
- else
- text += ", [crystals] crystals"
- text += "." //hiel grammar
- out += text
-
- out += "
"
-
- out += "Memory:
"
- out += memory
- out += "
Edit memory
"
- out += "Objectives:
"
- if (objectives.len == 0)
- out += "EMPTY
"
- else
- var/obj_count = 1
- for(var/datum/objective/objective in objectives)
- out += "[obj_count]: [objective.explanation_text] Edit Delete Toggle Completion
"
- obj_count++
- out += "Add objective
"
-
- out += "Announce objectives
"
-
- usr << browse(out, "window=edit_memory[src];size=500x600")
-
-
-/datum/mind/Topic(href, href_list)
- if(!check_rights(R_ADMIN)) return
-
- if (href_list["role_edit"])
- var/new_role = input("Select new role", "Assigned role", assigned_role) as null|anything in get_all_jobs()
- if (!new_role) return
- assigned_role = new_role
-
- else if (href_list["memory_edit"])
- var/new_memo = copytext(sanitize(input("Write new memory", "Memory", memory) as null|message),1,MAX_MESSAGE_LEN)
- if (isnull(new_memo)) return
- memory = new_memo
-
- 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", "maroon", "debrain", "protect", "destroy", "prevent", "hijack", "escape", "survive", "martyr", "steal", "download", "nuclear", "capture", "absorb", "custom","follower block (HOG)","build (HOG)","deicide (HOG)", "follower escape (HOG)", "sacrifice prophet (HOG)")
- if (!new_obj_type) return
-
- var/datum/objective/new_objective = null
-
- switch (new_obj_type)
- if ("assassinate","protect","debrain","maroon")
- var/list/possible_targets = list("Free objective")
- for(var/datum/mind/possible_target in ticker.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, /datum/objective/maroon)
- 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]")
- if (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 = new_target:mind
- //Will display as special role if the target is set as MODE. Ninjas/commandos/nuke ops.
- new_objective.update_explanation_text()
-
- if ("destroy")
- var/list/possible_targets = active_ais(1)
- if(possible_targets.len)
- var/mob/new_target = input("Select target:", "Objective target") as null|anything in possible_targets
- new_objective = new /datum/objective/destroy
- new_objective.target = new_target.mind
- new_objective.owner = src
- new_objective.update_explanation_text()
- else
- usr << "No active AIs with minds"
-
- 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("martyr")
- new_objective = new /datum/objective/martyr
- new_objective.owner = src
-
- if ("nuclear")
- 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 = "Capture [target_number] lifeforms with an energy net. Live, rare specimens are worth more."
- 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("follower block (HOG)")
- new_objective = new /datum/objective/follower_block
- new_objective.owner = src
- if("build (HOG)")
- new_objective = new /datum/objective/build
- new_objective.owner = src
- if("deicide (HOG)")
- new_objective = new /datum/objective/deicide
- new_objective.owner = src
- if("follower escape (HOG)")
- new_objective = new /datum/objective/escape_followers
- new_objective.owner = src
- if("sacrifice prophet (HOG)")
- new_objective = new /datum/objective/sacrifice_prophet
- new_objective.owner = src
-
- if ("custom")
- var/expl = stripped_input(usr, "Custom objective:", "Objective", objective ? objective.explanation_text : "")
- 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)
- message_admins("[key_name_admin(usr)] edited [current]'s objective to [new_objective.explanation_text]")
- log_admin("[key_name(usr)] edited [current]'s objective to [new_objective.explanation_text]")
- else
- objectives += new_objective
- message_admins("[key_name_admin(usr)] added a new objective for [current]: [new_objective.explanation_text]")
- log_admin("[key_name(usr)] added a new objective for [current]: [new_objective.explanation_text]")
-
- else if (href_list["obj_delete"])
- var/datum/objective/objective = locate(href_list["obj_delete"])
- if(!istype(objective)) return
- objectives -= objective
- message_admins("[key_name_admin(usr)] removed an objective for [current]: [objective.explanation_text]")
- log_admin("[key_name(usr)] removed an objective for [current]: [objective.explanation_text]")
-
- else if(href_list["obj_completed"])
- var/datum/objective/objective = locate(href_list["obj_completed"])
- if(!istype(objective)) return
- objective.completed = !objective.completed
- log_admin("[key_name(usr)] toggled the win state for [current]'s objective: [objective.explanation_text]")
-
- else if (href_list["handofgod"])
- switch(href_list["handofgod"])
- if("clear") //wipe handofgod status
- if((src in ticker.mode.red_deity_followers) || (src in ticker.mode.blue_deity_followers) || (src in ticker.mode.red_deity_prophets) || (src in ticker.mode.blue_deity_prophets))
- remove_hog_follower_prophet()
- current << "You have been brainwashed... again! Your faith is no more!"
- message_admins("[key_name_admin(usr)] has de-hand of god'ed [current].")
- log_admin("[key_name(usr)] has de-hand of god'ed [current].")
-
- if("red follower")
- make_Handofgod_follower("red")
- message_admins("[key_name_admin(usr)] has red follower'ed [current].")
- log_admin("[key_name(usr)] has red follower'ed [current].")
-
- if("red prophet")
- make_Handofgod_prophet("red")
- message_admins("[key_name_admin(usr)] has red prophet'ed [current].")
- log_admin("[key_name(usr)] has red prophet'ed [current].")
-
- if("blue follower")
- make_Handofgod_follower("blue")
- message_admins("[key_name_admin(usr)] has blue follower'ed [current].")
- log_admin("[key_name(usr)] has blue follower'ed [current].")
-
- if("blue prophet")
- make_Handofgod_prophet("blue")
- message_admins("[key_name_admin(usr)] has blue prophet'ed [current].")
- log_admin("[key_name(usr)] has blue prophet'ed [current].")
-
- if("red god")
- make_Handofgod_god("red")
- message_admins("[key_name_admin(usr)] has red god'ed [current].")
- log_admin("[key_name(usr)] has red god'ed [current].")
-
- if("blue god")
- make_Handofgod_god("blue")
- message_admins("[key_name_admin(usr)] has blue god'ed [current].")
- log_admin("[key_name(usr)] has blue god'ed [current].")
-
-
- else if (href_list["revolution"])
- switch(href_list["revolution"])
- if("clear")
- remove_rev()
- current << "You have been brainwashed! You are no longer a revolutionary!"
- message_admins("[key_name_admin(usr)] has de-rev'ed [current].")
- log_admin("[key_name(usr)] has de-rev'ed [current].")
- if("rev")
- if(src in ticker.mode.head_revolutionaries)
- ticker.mode.head_revolutionaries -= src
- ticker.mode.update_rev_icons_removed(src)
- current << "Revolution has been disappointed of your leader traits! You are a regular revolutionary now!"
- else if(!(src in ticker.mode.revolutionaries))
- current << " You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!"
- else
- return
- ticker.mode.revolutionaries += src
- ticker.mode.update_rev_icons_added(src)
- special_role = "Revolutionary"
- message_admins("[key_name_admin(usr)] has rev'ed [current].")
- log_admin("[key_name(usr)] has rev'ed [current].")
-
- if("headrev")
- if(src in ticker.mode.revolutionaries)
- ticker.mode.revolutionaries -= src
- ticker.mode.update_rev_icons_removed(src)
- current << "You have proved your devotion to revoltion! Yea are a head revolutionary now!"
- else if(!(src in ticker.mode.head_revolutionaries))
- current << "You are a member of the revolutionaries' leadership now!"
- else
- return
- if (ticker.mode.head_revolutionaries.len>0)
- // copy targets
- var/datum/mind/valid_head = locate() in ticker.mode.head_revolutionaries
- if (valid_head)
- for (var/datum/objective/mutiny/O in valid_head.objectives)
- var/datum/objective/mutiny/rev_obj = new
- rev_obj.owner = src
- rev_obj.target = O.target
- rev_obj.explanation_text = "Assassinate [O.target.name], the [O.target.assigned_role]."
- objectives += rev_obj
- ticker.mode.greet_revolutionary(src,0)
- ticker.mode.head_revolutionaries += src
- ticker.mode.update_rev_icons_added(src)
- special_role = "Head Revolutionary"
- message_admins("[key_name_admin(usr)] has head-rev'ed [current].")
- log_admin("[key_name(usr)] has head-rev'ed [current].")
-
- if("autoobjectives")
- ticker.mode.forge_revolutionary_objectives(src)
- ticker.mode.greet_revolutionary(src,0)
- usr << "The objectives for revolution have been generated and shown to [key]"
-
- if("flash")
- if (!ticker.mode.equip_revolutionary(current))
- usr << "Spawning flash failed!"
-
- if("takeflash")
- var/list/L = current.get_contents()
- var/obj/item/device/assembly/flash/flash = locate() in L
- if (!flash)
- usr << "Deleting flash failed!"
- qdel(flash)
-
- if("repairflash")
- var/list/L = current.get_contents()
- var/obj/item/device/assembly/flash/flash = locate() in L
- if (!flash)
- usr << "Repairing flash failed!"
- else
- flash.crit_fail = 0
- flash.update_icon()
-
-
-
-//////////////////// GANG MODE
-
- else if (href_list["gang"])
- switch(href_list["gang"])
- if("clear")
- remove_gang()
- message_admins("[key_name_admin(usr)] has de-gang'ed [current].")
- log_admin("[key_name(usr)] has de-gang'ed [current].")
-
- if("equip")
- switch(ticker.mode.equip_gang(current,gang_datum))
- if(1)
- usr << "Unable to equip territory spraycan!"
- if(2)
- usr << "Unable to equip recruitment pen and spraycan!"
- if(3)
- usr << "Unable to equip gangtool, pen, and spraycan!"
-
- if("takeequip")
- var/list/L = current.get_contents()
- for(var/obj/item/weapon/pen/gang/pen in L)
- qdel(pen)
- for(var/obj/item/device/gangtool/gangtool in L)
- qdel(gangtool)
- for(var/obj/item/toy/crayon/spraycan/gang/SC in L)
- qdel(SC)
-
- if("new")
- if(gang_colors_pool.len)
- var/list/names = list("Random") + gang_name_pool
- var/gangname = input("Pick a gang name.","Select Name") as null|anything in names
- if(gangname && gang_colors_pool.len) //Check again just in case another admin made max gangs at the same time
- if(!(gangname in gang_name_pool))
- gangname = null
- var/datum/gang/newgang = new(null,gangname)
- ticker.mode.gangs += newgang
- message_admins("[key_name_admin(usr)] has created the [newgang.name] Gang.")
- log_admin("[key_name(usr)] has created the [newgang.name] Gang.")
-
- else if (href_list["gangboss"])
- var/datum/gang/G = locate(href_list["gangboss"]) in ticker.mode.gangs
- if(!G || (src in G.bosses))
- return
- ticker.mode.remove_gangster(src,0,2,1)
- G.bosses += src
- gang_datum = G
- special_role = "[G.name] Gang Boss"
- G.add_gang_hud(src)
- current << "You are a [G.name] Gang Boss!"
- message_admins("[key_name_admin(usr)] has added [current] to the [G.name] Gang leadership.")
- log_admin("[key_name(usr)] has added [current] to the [G.name] Gang leadership.")
- ticker.mode.forge_gang_objectives(src)
- ticker.mode.greet_gang(src,0)
-
- else if (href_list["gangster"])
- var/datum/gang/G = locate(href_list["gangster"]) in ticker.mode.gangs
- if(!G || (src in G.gangsters))
- return
- ticker.mode.remove_gangster(src,0,2,1)
- ticker.mode.add_gangster(src,G,0)
- message_admins("[key_name_admin(usr)] has added [current] to the [G.name] Gang (A).")
- log_admin("[key_name(usr)] has added [current] to the [G.name] Gang (A).")
-
-/////////////////////////////////
-
-
-
- else if (href_list["cult"])
- switch(href_list["cult"])
- if("clear")
- remove_cultist()
- current << "You have been brainwashed! You are no longer a cultist!"
- message_admins("[key_name_admin(usr)] has de-cult'ed [current].")
- log_admin("[key_name(usr)] has de-cult'ed [current].")
- if("cultist")
- if(!(src in ticker.mode.cult))
- ticker.mode.add_cultist(src)
- message_admins("[key_name_admin(usr)] has cult'ed [current].")
- log_admin("[key_name(usr)] has cult'ed [current].")
- if("equip")
- if (!ticker.mode.equip_cultist(current))
- usr << "equip_cultist() failed! [current]'s starting equipment will be incomplete."
-
- else if (href_list["wizard"])
- switch(href_list["wizard"])
- if("clear")
- remove_wizard()
- current << "You have been brainwashed! You are no longer a wizard!"
- log_admin("[key_name(usr)] has de-wizard'ed [current].")
- if("wizard")
- if(!(src in ticker.mode.wizards))
- ticker.mode.wizards += src
- special_role = "Wizard"
- //ticker.mode.learn_basic_spells(current)
- current << "You are the Space Wizard!"
- message_admins("[key_name_admin(usr)] has wizard'ed [current].")
- log_admin("[key_name(usr)] has wizard'ed [current].")
- if("lair")
- current.loc = pick(wizardstart)
- if("dressup")
- ticker.mode.equip_wizard(current)
- if("name")
- ticker.mode.name_wizard(current)
- if("autoobjectives")
- ticker.mode.forge_wizard_objectives(src)
- usr << "The objectives for wizard [key] have been generated. You can edit them and anounce manually."
-
- else if (href_list["changeling"])
- switch(href_list["changeling"])
- if("clear")
- remove_changeling()
- current << "You grow weak and lose your powers! You are no longer a changeling and are stuck in your current form!"
- message_admins("[key_name_admin(usr)] has de-changeling'ed [current].")
- log_admin("[key_name(usr)] has de-changeling'ed [current].")
- if("changeling")
- if(!(src in ticker.mode.changelings))
- ticker.mode.changelings += src
- current.make_changeling()
- special_role = "Changeling"
- current << "Your powers are awoken. A flash of memory returns to us...we are [changeling.changelingID], a changeling!"
- message_admins("[key_name_admin(usr)] has changeling'ed [current].")
- log_admin("[key_name(usr)] has changeling'ed [current].")
- if("autoobjectives")
- ticker.mode.forge_changeling_objectives(src)
- usr << "The objectives for changeling [key] have been generated. You can edit them and anounce manually."
-
- if("initialdna")
- if( !changeling || !changeling.stored_profiles.len || !istype(current, /mob/living/carbon))
- usr << "Resetting DNA failed!"
- else
- var/mob/living/carbon/C = current
- changeling.first_prof.dna.transfer_identity(C, transfer_SE=1)
- C.real_name = changeling.first_prof.name
- C.updateappearance(mutcolor_update=1)
- C.domutcheck()
-
- else if (href_list["nuclear"])
- switch(href_list["nuclear"])
- if("clear")
- remove_nukeop()
- current << "You have been brainwashed! You are no longer a syndicate operative!"
- message_admins("[key_name_admin(usr)] has de-nuke op'ed [current].")
- log_admin("[key_name(usr)] has de-nuke op'ed [current].")
- if("nuclear")
- if(!(src in ticker.mode.syndicates))
- ticker.mode.syndicates += src
- ticker.mode.update_synd_icons_added(src)
- if (ticker.mode.syndicates.len==1)
- ticker.mode.prepare_syndicate_leader(src)
- else
- current.real_name = "[syndicate_name()] Operative #[ticker.mode.syndicates.len-1]"
- special_role = "Syndicate"
- assigned_role = "Syndicate"
- current << "You are a [syndicate_name()] agent!"
- ticker.mode.forge_syndicate_objectives(src)
- ticker.mode.greet_syndicate(src)
- message_admins("[key_name_admin(usr)] has nuke op'ed [current].")
- log_admin("[key_name(usr)] has nuke op'ed [current].")
- if("lair")
- current.loc = get_turf(locate("landmark*Syndicate-Spawn"))
- if("dressup")
- var/mob/living/carbon/human/H = current
- qdel(H.belt)
- qdel(H.back)
- qdel(H.ears)
- qdel(H.gloves)
- qdel(H.head)
- qdel(H.shoes)
- qdel(H.wear_id)
- qdel(H.wear_suit)
- qdel(H.w_uniform)
-
- if (!ticker.mode.equip_syndicate(current))
- usr << "Equipping a syndicate failed!"
- if("tellcode")
- var/code
- for (var/obj/machinery/nuclearbomb/bombue in machines)
- if (length(bombue.r_code) <= 5 && bombue.r_code != "LOLNO" && bombue.r_code != "ADMIN")
- code = bombue.r_code
- break
- if (code)
- store_memory("Syndicate Nuclear Bomb Code: [code]", 0, 0)
- current << "The nuclear authorization code is: [code]"
- else
- usr << "No valid nuke found!"
-
- else if (href_list["traitor"])
- switch(href_list["traitor"])
- if("clear")
- remove_traitor()
- current << "You have been brainwashed! You are no longer a traitor!"
- message_admins("[key_name_admin(usr)] has de-traitor'ed [current].")
- log_admin("[key_name(usr)] has de-traitor'ed [current].")
-
- if("traitor")
- if(!(src in ticker.mode.traitors))
- ticker.mode.traitors += src
- special_role = "traitor"
- current << "You are a traitor!"
- message_admins("[key_name_admin(usr)] has traitor'ed [current].")
- log_admin("[key_name(usr)] has traitor'ed [current].")
- if(isAI(current))
- var/mob/living/silicon/ai/A = current
- ticker.mode.add_law_zero(A)
- A.show_laws()
-
- if("autoobjectives")
- ticker.mode.forge_traitor_objectives(src)
- usr << "The objectives for traitor [key] have been generated. You can edit them and anounce manually."
-
- else if(href_list["shadowling"])
- switch(href_list["shadowling"])
- if("clear")
- ticker.mode.update_shadow_icons_removed(src)
- if(src in ticker.mode.shadows)
- ticker.mode.shadows -= src
- special_role = null
- current << "Your powers have been quenched! You are no longer a shadowling!"
- remove_spell(/obj/effect/proc_holder/spell/self/shadowling_hatch)
- remove_spell(/obj/effect/proc_holder/spell/self/shadowling_ascend)
- remove_spell(/obj/effect/proc_holder/spell/targeted/enthrall)
- remove_spell(/obj/effect/proc_holder/spell/self/shadowling_hivemind)
- message_admins("[key_name_admin(usr)] has de-shadowling'ed [current].")
- log_admin("[key_name(usr)] has de-shadowling'ed [current].")
- else if(src in ticker.mode.thralls)
- ticker.mode.remove_thrall(src,0)
- message_admins("[key_name_admin(usr)] has de-thrall'ed [current].")
- log_admin("[key_name(usr)] has de-thrall'ed [current].")
- if("shadowling")
- if(!ishuman(current))
- usr << "This only works on humans!"
- return
- ticker.mode.shadows += src
- special_role = "shadowling"
- current << "Something stirs deep in your mind. A red light floods your vision, and slowly you remember. Though your human disguise has served you well, the \
- time is nigh to cast it off and enter your true form. You have disguised yourself amongst the humans, but you are not one of them. You are a shadowling, and you are to ascend at all costs.\
- "
- ticker.mode.finalize_shadowling(src)
- ticker.mode.update_shadow_icons_added(src)
- if("thrall")
- if(!ishuman(current))
- usr << "This only works on humans!"
- return
- ticker.mode.add_thrall(src)
- message_admins("[key_name_admin(usr)] has thrall'ed [current].")
- log_admin("[key_name(usr)] has thrall'ed [current].")
-
- else if(href_list["abductor"])
- switch(href_list["abductor"])
- if("clear")
- usr << "Not implemented yet. Sorry!"
- if("abductor")
- if(!ishuman(current))
- usr << "This only works on humans!"
- return
- make_Abductor()
- log_admin("[key_name(usr)] turned [current] into abductor.")
- if("equip")
- var/gear = alert("Agent or Scientist Gear","Gear","Agent","Scientist")
- if(gear)
- var/datum/game_mode/abduction/temp = new
- temp.equip_common(current)
- if(gear=="Agent")
- temp.equip_agent(current)
- else
- temp.equip_scientist(current)
-
- else if (href_list["monkey"])
- var/mob/living/L = current
- if (L.notransform)
- return
- switch(href_list["monkey"])
- if("healthy")
- if (check_rights(R_ADMIN))
- var/mob/living/carbon/human/H = current
- var/mob/living/carbon/monkey/M = current
- if (istype(H))
- log_admin("[key_name(usr)] attempting to monkeyize [key_name(current)]")
- message_admins("[key_name_admin(usr)] attempting to monkeyize [key_name_admin(current)]")
- src = null
- M = H.monkeyize()
- src = M.mind
- //world << "DEBUG: \"healthy\": M=[M], M.mind=[M.mind], src=[src]!"
- else if (istype(M) && length(M.viruses))
- for(var/datum/disease/D in M.viruses)
- D.cure(0)
- sleep(0) //because deleting of virus is done through spawn(0)
- if("infected")
- if (check_rights(R_ADMIN, 0))
- var/mob/living/carbon/human/H = current
- var/mob/living/carbon/monkey/M = current
- if (istype(H))
- log_admin("[key_name(usr)] attempting to monkeyize and infect [key_name(current)]")
- message_admins("[key_name_admin(usr)] attempting to monkeyize and infect [key_name_admin(current)]")
- src = null
- M = H.monkeyize()
- src = M.mind
- current.ForceContractDisease(new /datum/disease/transformation/jungle_fever)
- else if (istype(M))
- current.ForceContractDisease(new /datum/disease/transformation/jungle_fever)
- if("human")
- if (check_rights(R_ADMIN, 0))
- var/mob/living/carbon/human/H = current
- var/mob/living/carbon/monkey/M = current
- if (istype(M))
- for(var/datum/disease/D in M.viruses)
- if (istype(D,/datum/disease/transformation/jungle_fever))
- D.cure(0)
- sleep(0) //because deleting of virus is doing throught spawn(0)
- log_admin("[key_name(usr)] attempting to humanize [key_name(current)]")
- message_admins("[key_name_admin(usr)] attempting to humanize [key_name_admin(current)]")
- H = M.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG)
- if(H)
- src = H.mind
-
- else if (href_list["silicon"])
- switch(href_list["silicon"])
- if("unemag")
- var/mob/living/silicon/robot/R = current
- if (istype(R))
- R.SetEmagged(0)
- message_admins("[key_name_admin(usr)] has unemag'ed [R].")
- log_admin("[key_name(usr)] has unemag'ed [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.SetEmagged(0)
- message_admins("[key_name_admin(usr)] has unemag'ed [ai]'s Cyborgs.")
- log_admin("[key_name(usr)] has unemag'ed [ai]'s Cyborgs.")
-
- else if (href_list["common"])
- switch(href_list["common"])
- if("undress")
- for(var/obj/item/W in current)
- current.unEquip(W, 1) //The 1 forces all items to drop, since this is an admin undress.
- if("takeuplink")
- take_uplink()
- memory = null//Remove any memory they may have had.
- log_admin("[key_name(usr)] removed [current]'s uplink.")
- if("crystals")
- if (check_rights(R_FUN, 0))
- var/obj/item/device/uplink/hidden/suplink = find_syndicate_uplink()
- var/crystals
- if (suplink)
- crystals = suplink.uses
- crystals = input("Amount of telecrystals for [key]","Syndicate uplink", crystals) as null|num
- if (!isnull(crystals))
- if (suplink)
- suplink.uses = crystals
- message_admins("[key_name_admin(usr)] changed [current]'s telecrystal count to [crystals].")
- log_admin("[key_name(usr)] changed [current]'s telecrystal count to [crystals].")
- if("uplink")
- if (!ticker.mode.equip_traitor(current, !(src in ticker.mode.traitors)))
- usr << "Equipping a syndicate failed!"
- log_admin("[key_name(usr)] attempted to give [current] an uplink.")
-
- else if (href_list["obj_announce"])
- var/obj_count = 1
- current << "Your current objectives:"
- for(var/datum/objective/objective in objectives)
- current << "Objective #[obj_count]: [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)
-
-/datum/mind/proc/make_Traitor()
- if(!(src in ticker.mode.traitors))
- ticker.mode.traitors += src
- special_role = "traitor"
- ticker.mode.forge_traitor_objectives(src)
- ticker.mode.finalize_traitor(src)
- ticker.mode.greet_traitor(src)
-
-/datum/mind/proc/make_Nuke(turf/spawnloc,nuke_code,leader=0, telecrystals = TRUE)
- if(!(src in ticker.mode.syndicates))
- ticker.mode.syndicates += src
- ticker.mode.update_synd_icons_added(src)
- special_role = "Syndicate"
- ticker.mode.forge_syndicate_objectives(src)
- ticker.mode.greet_syndicate(src)
-
- current.loc = spawnloc
-
- var/mob/living/carbon/human/H = current
- qdel(H.belt)
- qdel(H.back)
- qdel(H.ears)
- qdel(H.gloves)
- qdel(H.head)
- qdel(H.shoes)
- qdel(H.wear_id)
- qdel(H.wear_suit)
- qdel(H.w_uniform)
-
- ticker.mode.equip_syndicate(current, telecrystals)
-
- if (nuke_code)
- store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0)
- current << "The nuclear authorization code is: [nuke_code]"
-
- if (leader)
- ticker.mode.prepare_syndicate_leader(src,nuke_code)
- else
- current.real_name = "[syndicate_name()] Operative #[ticker.mode.syndicates.len-1]"
-
-/datum/mind/proc/make_Changling()
- if(!(src in ticker.mode.changelings))
- ticker.mode.changelings += src
- current.make_changeling()
- special_role = "Changeling"
- ticker.mode.forge_changeling_objectives(src)
- ticker.mode.greet_changeling(src)
-
-/datum/mind/proc/make_Wizard()
- if(!(src in ticker.mode.wizards))
- ticker.mode.wizards += src
- special_role = "Wizard"
- assigned_role = "Wizard"
- //ticker.mode.learn_basic_spells(current)
- if(!wizardstart.len)
- current.loc = pick(latejoin)
- current << "HOT INSERTION, GO GO GO"
- else
- current.loc = pick(wizardstart)
-
- ticker.mode.equip_wizard(current)
- for(var/obj/item/weapon/spellbook/S in current.contents)
- S.op = 0
- ticker.mode.name_wizard(current)
- ticker.mode.forge_wizard_objectives(src)
- ticker.mode.greet_wizard(src)
-
-
-/datum/mind/proc/make_Cultist()
- if(!(src in ticker.mode.cult))
- ticker.mode.cult += src
- ticker.mode.update_cult_icons_added(src)
- special_role = "Cultist"
- current << "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie."
- current << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back."
- current << "Your objective is to summon Nar-Sie by building and defending a suitable shell for the Geometer. Adequate supplies can be procured through human sacrifices."
- ticker.mode.equip_cultist(current)
-
-/datum/mind/proc/make_Rev()
- if (ticker.mode.head_revolutionaries.len>0)
- // copy targets
- var/datum/mind/valid_head = locate() in ticker.mode.head_revolutionaries
- if (valid_head)
- for (var/datum/objective/mutiny/O in valid_head.objectives)
- var/datum/objective/mutiny/rev_obj = new
- rev_obj.owner = src
- rev_obj.target = O.target
- rev_obj.explanation_text = "Assassinate [O.target.current.real_name], the [O.target.assigned_role]."
- objectives += rev_obj
- ticker.mode.greet_revolutionary(src,0)
- ticker.mode.head_revolutionaries += src
- ticker.mode.update_rev_icons_added(src)
- special_role = "Head Revolutionary"
-
- ticker.mode.forge_revolutionary_objectives(src)
- ticker.mode.greet_revolutionary(src,0)
-
- var/list/L = current.get_contents()
- var/obj/item/device/assembly/flash/flash = locate() in L
- qdel(flash)
- take_uplink()
- var/fail = 0
-// fail |= !ticker.mode.equip_traitor(current, 1)
- fail |= !ticker.mode.equip_revolutionary(current)
-
-
-/datum/mind/proc/make_Gang(datum/gang/G)
- special_role = "[G.name] Gang Boss"
- G.bosses += src
- gang_datum = G
- G.add_gang_hud(src)
- ticker.mode.forge_gang_objectives(src)
- ticker.mode.greet_gang(src)
- ticker.mode.equip_gang(current,G)
-
-/datum/mind/proc/make_Abductor()
- var/role = alert("Abductor Role ?","Role","Agent","Scientist")
- var/team = input("Abductor Team ?","Team ?") in list(1,2,3,4)
- var/teleport = alert("Teleport to ship ?","Teleport","Yes","No")
-
- if(!role || !team || !teleport)
- return
-
- if(!ishuman(current))
- return
-
- ticker.mode.abductors |= src
-
- var/datum/objective/experiment/O = new
- O.owner = src
- objectives += O
-
- var/mob/living/carbon/human/H = current
-
- H.set_species(/datum/species/abductor)
- var/datum/species/abductor/S = H.dna.species
-
- switch(role)
- if("Agent")
- S.agent = 1
- if("Scientist")
- S.scientist = 1
- S.team = team
-
- var/list/obj/effect/landmark/abductor/agent_landmarks = new
- var/list/obj/effect/landmark/abductor/scientist_landmarks = new
- agent_landmarks.len = 4
- scientist_landmarks.len = 4
- for(var/obj/effect/landmark/abductor/A in landmarks_list)
- if(istype(A,/obj/effect/landmark/abductor/agent))
- agent_landmarks[text2num(A.team)] = A
- else if(istype(A,/obj/effect/landmark/abductor/scientist))
- scientist_landmarks[text2num(A.team)] = A
-
- var/obj/effect/landmark/L
- if(teleport=="Yes")
- switch(role)
- if("Agent")
- S.agent = 1
- L = agent_landmarks[team]
- H.loc = L.loc
- if("Scientist")
- S.scientist = 1
- L = agent_landmarks[team]
- H.loc = L.loc
-
-
-/datum/mind/proc/make_Handofgod_follower(colour)
- . = 0
- switch(colour)
- if("red")
- //Remove old allegiances
- if(src in ticker.mode.blue_deity_followers || src in ticker.mode.blue_deity_prophets)
- current << "You are no longer a member of the Blue cult!"
-
- ticker.mode.blue_deity_followers -= src
- ticker.mode.blue_deity_prophets -= src
- current.faction |= "red god"
- current.faction -= "blue god"
-
- if(src in ticker.mode.red_deity_prophets)
- current << "You have lost the connection with your deity, but you still believe in their grand design, You are no longer a prophet!"
- ticker.mode.red_deity_prophets -= src
-
- ticker.mode.red_deity_followers |= src
- current << "You are now a follower of the red cult's god!"
-
- special_role = "Hand of God: Red Follower"
- . = 1
- if("blue")
- //Remove old allegiances
- if(src in ticker.mode.red_deity_followers || src in ticker.mode.red_deity_prophets)
- current << "You are no longer a member of the Red cult!"
-
- ticker.mode.red_deity_followers -= src
- ticker.mode.red_deity_prophets -= src
- current.faction -= "red god"
- current.faction |= "blue god"
-
- if(src in ticker.mode.blue_deity_prophets)
- current << "You have lost the connection with your deity, but you still believe in their grand design, You are no longer a prophet!"
- ticker.mode.blue_deity_prophets -= src
-
- ticker.mode.blue_deity_followers |= src
- current << "You are now a follower of the blue cult's god!"
-
- special_role = "Hand of God: Blue Follower"
- . = 1
- else
- return 0
-
- ticker.mode.update_hog_icons_removed(src,"red")
- ticker.mode.update_hog_icons_removed(src,"blue")
- //ticker.mode.greet_hog_follower(src,colour)
- ticker.mode.update_hog_icons_added(src, colour)
-
-/datum/mind/proc/make_Handofgod_prophet(colour)
- . = 0
- switch(colour)
- if("red")
- //Remove old allegiances
-
- if(src in ticker.mode.blue_deity_followers || src in ticker.mode.blue_deity_prophets)
- current << "You are no longer a member of the Blue cult!"
- current.faction -= "blue god"
- current.faction |= "red god"
-
- ticker.mode.blue_deity_followers -= src
- ticker.mode.blue_deity_prophets -= src
- ticker.mode.red_deity_followers -= src
-
- ticker.mode.red_deity_prophets |= src
- current << "You are now a prophet of the red cult's god!"
-
- special_role = "Hand of God: Red Prophet"
- . = 1
- if("blue")
- //Remove old allegiances
-
- if(src in ticker.mode.red_deity_followers || src in ticker.mode.red_deity_prophets)
- current << "You are no longer a member of the Red cult!"
- current.faction -= "red god"
- current.faction |= "blue god"
-
- ticker.mode.red_deity_followers -= src
- ticker.mode.red_deity_prophets -= src
- ticker.mode.blue_deity_followers -= src
-
- ticker.mode.blue_deity_prophets |= src
- current << "You are now a prophet of the blue cult's god!"
-
- special_role = "Hand of God: Blue Prophet"
- . = 1
-
- else
- return 0
-
- ticker.mode.update_hog_icons_removed(src,"red")
- ticker.mode.update_hog_icons_removed(src,"blue")
- ticker.mode.greet_hog_follower(src,colour)
- ticker.mode.update_hog_icons_added(src, colour)
-
-
-/datum/mind/proc/make_Handofgod_god(colour)
- switch(colour)
- if("red")
- current.become_god("red")
- ticker.mode.add_god(src,"red")
- if("blue")
- current.become_god("blue")
- ticker.mode.add_god(src,"blue")
- else
- return 0
- ticker.mode.forge_deity_objectives(src)
- ticker.mode.remove_hog_follower(src,0)
- ticker.mode.update_hog_icons_added(src, colour)
-// ticker.mode.greet_hog_follower(src,colour)
- return 1
-
-
-/datum/mind/proc/AddSpell(obj/effect/proc_holder/spell/spell)
- spell_list += spell
- if(!spell.action)
- spell.action = new/datum/action/spell_action
- spell.action.target = spell
- spell.action.name = spell.name
- spell.action.button_icon = spell.action_icon
- spell.action.button_icon_state = spell.action_icon_state
- spell.action.background_icon_state = spell.action_background_icon_state
- spell.action.Grant(current)
- return
-/datum/mind/proc/transfer_actions(mob/living/new_character)
- if(current && current.actions)
- for(var/datum/action/A in current.actions)
- A.Grant(new_character)
- transfer_mindbound_actions(new_character)
-
-/datum/mind/proc/transfer_mindbound_actions(var/mob/living/new_character)
- for(var/obj/effect/proc_holder/spell/spell in spell_list)
- if(!spell.action) // Unlikely but whatever
- spell.action = new/datum/action/spell_action
- spell.action.target = spell
- spell.action.name = spell.name
- spell.action.button_icon = spell.action_icon
- spell.action.button_icon_state = spell.action_icon_state
- spell.action.background_icon_state = spell.action_background_icon_state
- spell.action.Grant(new_character)
- return
-
-/mob/proc/sync_mind()
- mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist)
- mind.active = 1 //indicates that the mind is currently synced with a client
-
-/mob/new_player/sync_mind()
- return
-
-/mob/dead/observer/sync_mind()
- return
-
-//Initialisation procs
-/mob/proc/mind_initialize()
- if(mind)
- mind.key = key
-
- else
- mind = new /datum/mind(key)
- if(ticker)
- ticker.minds += mind
- else
- spawn(0)
- throw EXCEPTION("mind_initialize(): No ticker ready")
- if(!mind.name) mind.name = real_name
- mind.current = src
-
-//HUMAN
-/mob/living/carbon/human/mind_initialize()
- ..()
- if(!mind.assigned_role) mind.assigned_role = "Assistant" //defualt
-
-//MONKEY
-/mob/living/carbon/monkey/mind_initialize()
- ..()
-
-//slime
-/mob/living/simple_animal/slime/mind_initialize()
- ..()
- mind.special_role = "slime"
- mind.assigned_role = "slime"
-
-//XENO
-/mob/living/carbon/alien/mind_initialize()
- ..()
- mind.special_role = "Alien"
- mind.assigned_role = "Alien"
- //XENO HUMANOID
-/mob/living/carbon/alien/humanoid/royal/queen/mind_initialize()
- ..()
- mind.special_role = "Queen"
-
-/mob/living/carbon/alien/humanoid/royal/praetorian/mind_initialize()
- ..()
- mind.special_role = "Praetorian"
-
-/mob/living/carbon/alien/humanoid/hunter/mind_initialize()
- ..()
- mind.special_role = "Hunter"
-
-/mob/living/carbon/alien/humanoid/drone/mind_initialize()
- ..()
- mind.special_role = "Drone"
-
-/mob/living/carbon/alien/humanoid/sentinel/mind_initialize()
- ..()
- mind.special_role = "Sentinel"
- //XENO LARVA
-/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 = ""
-
-//BLOB
-/mob/camera/blob/mind_initialize()
- ..()
- mind.special_role = "Blob"
-
-//Animals
-/mob/living/simple_animal/mind_initialize()
- ..()
- mind.assigned_role = "Animal"
- mind.special_role = "Animal"
-
-/mob/living/simple_animal/pet/dog/corgi/mind_initialize()
- ..()
- mind.assigned_role = "Corgi"
- mind.special_role = "Corgi"
-
-/mob/living/simple_animal/shade/mind_initialize()
- ..()
- mind.assigned_role = "Shade"
- mind.special_role = "Shade"
-
-/mob/living/simple_animal/hostile/construct/mind_initialize()
- ..()
- mind.assigned_role = "[initial(name)]"
- mind.special_role = "Cultist"
-
+/* 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/active = 0
+
+ var/memory
+
+ var/assigned_role
+ var/special_role
+ var/list/restricted_roles = list()
+
+ var/datum/job/assigned_job
+
+ var/list/datum/objective/objectives = list()
+ var/list/datum/objective/special_verbs = list()
+
+ var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button.
+
+ var/datum/faction/faction //associated faction
+ var/datum/changeling/changeling //changeling holder
+
+ var/miming = 0 // Mime's vow of silence
+ var/antag_hud_icon_state = null //this mind's ANTAG_HUD should have this icon_state
+ var/datum/atom_hud/antag/antag_hud = null //this mind's antag HUD
+ var/datum/gang/gang_datum //Which gang this mind belongs to, if any
+
+/datum/mind/New(var/key)
+ src.key = key
+
+
+/datum/mind/proc/transfer_to(mob/new_character)
+ if(current) // remove ourself from our old body's mind variable
+ current.mind = null
+ SSnano.on_transfer(current, new_character)
+
+ if(key)
+ if(new_character.key != key) //if we're transfering into a body with a key associated which is not ours
+ new_character.ghostize(1) //we'll need to ghostize so that key isn't mobless.
+ else
+ key = new_character.key
+
+ if(new_character.mind) //disassociate any mind currently in our new body's mind variable
+ new_character.mind.current = null
+
+ 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
+ new_character.mind = src //and associate our new body with ourself
+ transfer_antag_huds(hud_to_transfer) //inherit the antag HUD
+ transfer_actions(new_character)
+
+ 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)
+ memory += "[new_text]
"
+
+/datum/mind/proc/wipe_memory()
+ memory = null
+
+
+/*
+ Removes antag type's references from a mind.
+ objectives, uplinks, powers etc are all handled.
+*/
+
+/datum/mind/proc/remove_objectives()
+ if(objectives.len)
+ for(var/datum/objective/O in objectives)
+ objectives -= O
+ qdel(O)
+
+/datum/mind/proc/remove_changeling()
+ if(src in ticker.mode.changelings)
+ ticker.mode.changelings -= src
+ current.remove_changeling_powers()
+ if(changeling)
+ qdel(changeling)
+ changeling = null
+ special_role = null
+ remove_antag_equip()
+
+/datum/mind/proc/remove_traitor()
+ if(src in ticker.mode.traitors)
+ ticker.mode.traitors -= src
+ if(isAI(current))
+ var/mob/living/silicon/ai/A = current
+ A.set_zeroth_law("")
+ A.show_laws()
+ A.verbs -= /mob/living/silicon/ai/proc/choose_modules
+ A.malf_picker.remove_verbs(A)
+ qdel(A.malf_picker)
+ special_role = null
+ remove_antag_equip()
+
+/datum/mind/proc/remove_nukeop()
+ if(src in ticker.mode.syndicates)
+ ticker.mode.syndicates -= src
+ ticker.mode.update_synd_icons_removed(src)
+ special_role = null
+ remove_objectives()
+ remove_antag_equip()
+
+/datum/mind/proc/remove_wizard()
+ if(src in ticker.mode.wizards)
+ ticker.mode.wizards -= src
+ current.spellremove(current)
+ special_role = null
+ remove_antag_equip()
+
+/datum/mind/proc/remove_cultist()
+ if(src in ticker.mode.cult)
+ ticker.mode.cult -= src
+ ticker.mode.update_cult_icons_removed(src)
+ special_role = null
+
+/datum/mind/proc/remove_rev()
+ if(src in ticker.mode.revolutionaries)
+ ticker.mode.revolutionaries -= src
+ ticker.mode.update_rev_icons_removed(src)
+ if(src in ticker.mode.head_revolutionaries)
+ ticker.mode.head_revolutionaries -= src
+ ticker.mode.update_rev_icons_removed(src)
+ special_role = null
+ remove_objectives()
+ remove_antag_equip()
+
+
+/datum/mind/proc/remove_gang()
+ ticker.mode.remove_gangster(src,0,1,1)
+ remove_objectives()
+
+/datum/mind/proc/remove_hog_follower_prophet()
+ ticker.mode.red_deity_followers -= src
+ ticker.mode.red_deity_prophets -= src
+ ticker.mode.blue_deity_prophets -= src
+ ticker.mode.blue_deity_followers -= src
+ ticker.mode.update_hog_icons_removed(src, "red")
+ ticker.mode.update_hog_icons_removed(src, "blue")
+
+
+
+/datum/mind/proc/remove_antag_equip()
+ var/list/Mob_Contents = current.get_contents()
+ for(var/obj/item/I in Mob_Contents)
+ if(istype(I, /obj/item/device/pda))
+ var/obj/item/device/pda/P = I
+ P.lock_code = ""
+
+ else if(istype(I, /obj/item/device/radio))
+ var/obj/item/device/radio/R = I
+ R.traitor_frequency = 0
+
+/datum/mind/proc/remove_all_antag() //For the Lazy amongst us.
+ remove_changeling()
+ remove_traitor()
+ remove_nukeop()
+ remove_wizard()
+ remove_cultist()
+ remove_rev()
+ remove_gang()
+
+/datum/mind/proc/show_memory(mob/recipient, window=1)
+ if(!recipient)
+ recipient = current
+ var/output = "[current.real_name]'s Memories:
"
+ output += memory
+
+ if(objectives.len)
+ output += "Objectives:"
+ var/obj_count = 1
+ for(var/datum/objective/objective in objectives)
+ output += "
Objective #[obj_count++]: [objective.explanation_text]"
+
+ if(window) recipient << browse(output,"window=memory")
+ else recipient << "[output]"
+
+/datum/mind/proc/edit_memory()
+ if(!ticker || !ticker.mode)
+ alert("Not before round-start!", "Alert")
+ return
+
+ var/out = "[name][(current&&(current.real_name!=name))?" (as [current.real_name])":""]
"
+ out += "Mind currently owned by key: [key] [active?"(synced)":"(not synced)"]
"
+ out += "Assigned role: [assigned_role]. Edit
"
+ out += "Faction and special role: [special_role]
"
+
+ var/list/sections = list(
+ "revolution",
+ "gang",
+ "cult",
+ "wizard",
+ "changeling",
+ "nuclear",
+ "traitor", // "traitorchan",
+ "monkey",
+ )
+ var/text = ""
+
+ if (istype(current, /mob/living/carbon/human) || istype(current, /mob/living/carbon/monkey))
+ /** REVOLUTION ***/
+ text = "revolution"
+ if (ticker.mode.config_tag=="revolution")
+ text = uppertext(text)
+ text = "[text]: "
+ if (assigned_role in command_positions)
+ text += "HEAD|loyal|employee|headrev|rev"
+ else if (src in ticker.mode.head_revolutionaries)
+ text += "head|loyal|employee|HEADREV|rev"
+ text += "
Flash: give"
+
+ var/list/L = current.get_contents()
+ var/obj/item/device/assembly/flash/flash = locate() in L
+ if (flash)
+ if(!flash.crit_fail)
+ text += "|take."
+ else
+ text += "|take|repair."
+ else
+ text += "."
+
+ text += " Reequip (gives traitor uplink)."
+ if (objectives.len==0)
+ text += "
Objectives are empty! Set to kill all heads."
+ else if(isloyal(current))
+ text += "head|LOYAL|employee|headrev|rev"
+ else if (src in ticker.mode.revolutionaries)
+ text += "head|loyal|employee|headrev|REV"
+ else
+ text += "head|loyal|EMPLOYEE|headrev|rev"
+
+ if(current && current.client && (ROLE_REV in current.client.prefs.be_special))
+ text += "|Enabled in Prefs"
+ else
+ text += "|Disabled in Prefs"
+
+ sections["revolution"] = text
+
+ /** GANG ***/
+ text = "gang"
+ if (ticker.mode.config_tag=="gang")
+ text = uppertext(text)
+ text = "[text]: "
+ text += "[isloyal(current) ? "LOYAL" : "loyal"]|"
+ if(src in ticker.mode.get_all_gangsters())
+ text += "none"
+ else
+ text += "NONE"
+
+ if(current && current.client && (ROLE_GANG in current.client.prefs.be_special))
+ text += "|Enabled in Prefs
"
+ else
+ text += "|Disabled in Prefs
"
+
+ for(var/datum/gang/G in ticker.mode.gangs)
+ text += "[G.name]: "
+ if(src in (G.gangsters))
+ text += "GANGSTER"
+ else
+ text += "gangster"
+ text += "|"
+ if(src in (G.bosses))
+ text += "GANG LEADER"
+ text += "|Equipment: give"
+ var/list/L = current.get_contents()
+ var/obj/item/device/gangtool/gangtool = locate() in L
+ if (gangtool)
+ text += "|take"
+
+ else
+ text += "gang leader"
+ text += "
"
+
+ if(gang_colors_pool.len)
+ text += "Create New Gang"
+
+ sections["gang"] = text
+
+
+ /** CULT ***/
+ text = "cult"
+ if (ticker.mode.config_tag=="cult")
+ text = uppertext(text)
+ text = "[text]: "
+ if (src in ticker.mode.cult)
+ text += "loyal|employee|CULTIST"
+ text += "
Equip"
+
+ else if(isloyal(current))
+ text += "LOYAL|employee|cultist"
+ else
+ text += "loyal|EMPLOYEE|cultist"
+
+ if(current && current.client && (ROLE_CULTIST in current.client.prefs.be_special))
+ text += "|Enabled in Prefs"
+ else
+ text += "|Disabled in Prefs"
+
+ sections["cult"] = text
+
+ /** WIZARD ***/
+ text = "wizard"
+ if (ticker.mode.config_tag=="wizard")
+ text = uppertext(text)
+ text = "[text]: "
+ if ((src in ticker.mode.wizards) || (src in ticker.mode.apprentices))
+ text += "YES|no"
+ text += "
To lair, undress, dress up, let choose name."
+ if (objectives.len==0)
+ text += "
Objectives are empty! Randomize!"
+ else
+ text += "yes|NO"
+
+ if(current && current.client && (ROLE_WIZARD in current.client.prefs.be_special))
+ text += "|Enabled in Prefs"
+ else
+ text += "|Disabled in Prefs"
+
+ sections["wizard"] = text
+
+ /** CHANGELING ***/
+ text = "changeling"
+ if (ticker.mode.config_tag=="changeling" || ticker.mode.config_tag=="traitorchan")
+ text = uppertext(text)
+ text = "[text]: "
+ if ((src in ticker.mode.changelings) && special_role)
+ text += "YES|no"
+ if (objectives.len==0)
+ text += "
Objectives are empty! Randomize!"
+ if(changeling && changeling.stored_profiles.len && (current.real_name != changeling.first_prof.name) )
+ text += "
Transform to initial appearance."
+ else if(src in ticker.mode.changelings) //Station Aligned Changeling
+ text += "YES (but not an antag)|no"
+ if (objectives.len==0)
+ text += "
Objectives are empty! Randomize!"
+ if(changeling && changeling.stored_profiles.len && (current.real_name != changeling.first_prof.name) )
+ text += "
Transform to initial appearance."
+ else
+ text += "yes|NO"
+// var/datum/game_mode/changeling/changeling = ticker.mode
+// if (istype(changeling) && changeling.changelingdeath)
+// text += "
All the changelings are dead! Restart in [round((changeling.TIME_TO_GET_REVIVED-(world.time-changeling.changelingdeathtime))/10)] seconds."
+
+ if(current && current.client && (ROLE_CHANGELING in current.client.prefs.be_special))
+ text += "|Enabled in Prefs"
+ else
+ text += "|Disabled in Prefs"
+
+ sections["changeling"] = text
+
+ /** NUCLEAR ***/
+ text = "nuclear"
+ if (ticker.mode.config_tag=="nuclear")
+ text = uppertext(text)
+ text = "[text]: "
+ if (src in ticker.mode.syndicates)
+ text += "OPERATIVE|nanotrasen"
+ text += "
To shuttle, undress, dress up."
+ var/code
+ for (var/obj/machinery/nuclearbomb/bombue in machines)
+ if (length(bombue.r_code) <= 5 && bombue.r_code != "LOLNO" && bombue.r_code != "ADMIN")
+ code = bombue.r_code
+ break
+ if (code)
+ text += " Code is [code]. tell the code."
+ else
+ text += "operative|NANOTRASEN"
+
+ if(current && current.client && (ROLE_OPERATIVE in current.client.prefs.be_special))
+ text += "|Enabled in Prefs"
+ else
+ text += "|Disabled in Prefs"
+
+ sections["nuclear"] = text
+
+ /** TRAITOR ***/
+ text = "traitor"
+ if (ticker.mode.config_tag=="traitor" || ticker.mode.config_tag=="traitorchan")
+ text = uppertext(text)
+ text = "[text]: "
+ if (src in ticker.mode.traitors)
+ text += "TRAITOR|loyal"
+ if (objectives.len==0)
+ text += "
Objectives are empty! Randomize!"
+ else
+ text += "traitor|LOYAL"
+
+ if(current && current.client && (ROLE_TRAITOR in current.client.prefs.be_special))
+ text += "|Enabled in Prefs"
+ else
+ text += "|Disabled in Prefs"
+
+ sections["traitor"] = text
+
+ /** SHADOWLING **/
+ text = "shadowling"
+ if(ticker.mode.config_tag == "shadowling")
+ text = uppertext(text)
+ text = "[text]: "
+ if(src in ticker.mode.shadows)
+ text += "SHADOWLING|thrall|human"
+ else if(src in ticker.mode.thralls)
+ text += "shadowling|THRALL|human"
+ else
+ text += "shadowling|thrall|HUMAN"
+
+ if(current && current.client && (ROLE_SHADOWLING in current.client.prefs.be_special))
+ text += "|Enabled in Prefs"
+ else
+ text += "|Disabled in Prefs"
+
+ sections["shadowling"] = text
+
+ /** Abductors **/
+
+ text = "Abductor"
+ if(ticker.mode.config_tag == "abductor")
+ text = uppertext(text)
+ text = "[text]: "
+ if(src in ticker.mode.abductors)
+ text += "Abductor|human"
+ text += "|undress|equip"
+ else
+ text += "Abductor|human"
+
+ if(current && current.client && (ROLE_ABDUCTOR in current.client.prefs.be_special))
+ text += "|Enabled in Prefs"
+ else
+ text += "|Disabled in Prefs"
+
+ sections["abductor"] = text
+
+ /** HAND OF GOD **/
+ text = "hand of god"
+ if(ticker.mode.config_tag == "handofgod")
+ text = uppertext(text)
+ text = "[text]: "
+ if(src in ticker.mode.red_deity_prophets)
+ text += "RED PROPHET|red follower|employee|blue follower|blue prophet|red god|blue god"
+ else if (src in ticker.mode.red_deity_followers)
+ text += "red prophet|RED FOLLOWER|employee|blue follower|blue prophet|red god|blue god"
+ else if (src in ticker.mode.blue_deity_followers)
+ text += "red prophet|red follower|employee|BLUE FOLLOWER|blue prophet|red god|blue god"
+ else if (src in ticker.mode.blue_deity_prophets)
+ text += "red prophet|red follower|employee|blue follower|BLUE PROPHET|red god|blue god"
+ else if (src in ticker.mode.red_deities)
+ text += "red prophet|red follower|employee|blue follower|blue prophet|RED GOD|blue god"
+ else if (src in ticker.mode.blue_deities)
+ text += "red prophet|red follower|employee|blue follower|blue prophet|red god|BLUE GOD"
+ else
+ text += "red prophet|red follower|EMPLOYEE|blue follower|blue prophet|red god|blue god"
+
+ if(current && current.client && (ROLE_HOG_GOD in current.client.prefs.be_special))
+ text += "|HOG God Enabled in Prefs"
+ else
+ text += "|HOG God Disabled in Prefs"
+
+ if(current && current.client && (ROLE_HOG_CULTIST in current.client.prefs.be_special))
+ text += "|HOG Cultist Enabled in Prefs"
+ else
+ text += "|HOG Disabled in Prefs"
+
+ sections["follower"] = text
+
+ /** MONKEY ***/
+ if (istype(current, /mob/living/carbon))
+ text = "monkey"
+ if (ticker.mode.config_tag=="monkey")
+ text = uppertext(text)
+ text = "[text]: "
+ if (istype(current, /mob/living/carbon/human))
+ text += "healthy|infected|HUMAN|other"
+ else if (istype(current, /mob/living/carbon/monkey))
+ var/found = 0
+ for(var/datum/disease/D in current.viruses)
+ if(istype(D, /datum/disease/transformation/jungle_fever)) found = 1
+
+ if(found)
+ text += "healthy|INFECTED|human|other"
+ else
+ text += "HEALTHY|infected|human|other"
+
+ else
+ text += "healthy|infected|human|OTHER"
+
+ if(current && current.client && (ROLE_MONKEY in current.client.prefs.be_special))
+ text += "|Enabled in Prefs"
+ else
+ text += "|Disabled in Prefs"
+
+ sections["monkey"] = text
+
+
+ /** SILICON ***/
+
+ if (istype(current, /mob/living/silicon))
+ text = "silicon"
+ var/mob/living/silicon/robot/robot = current
+ if (istype(robot) && robot.emagged)
+ text += "
Cyborg: Is emagged! Unemag!
0th law: [robot.laws.zeroth]"
+ var/mob/living/silicon/ai/ai = current
+ if (istype(ai) && ai.connected_robots.len)
+ var/n_e_robots = 0
+ for (var/mob/living/silicon/robot/R in ai.connected_robots)
+ if (R.emagged)
+ n_e_robots++
+ text += "
[n_e_robots] of [ai.connected_robots.len] slaved cyborgs are emagged. Unemag"
+ if (ticker.mode.config_tag == "traitorchan")
+ if (sections["traitor"])
+ out += sections["traitor"]+"
"
+ if (sections["changeling"])
+ out += sections["changeling"]+"
"
+ sections -= "traitor"
+ sections -= "changeling"
+ else
+ if (sections[ticker.mode.config_tag])
+ out += sections[ticker.mode.config_tag]+"
"
+ sections -= ticker.mode.config_tag
+ for (var/i in sections)
+ if (sections[i])
+ out += sections[i]+"
"
+
+
+ if (((src in ticker.mode.head_revolutionaries) || \
+ (src in ticker.mode.traitors) || \
+ (src in ticker.mode.syndicates)) && \
+ istype(current,/mob/living/carbon/human) )
+
+ text = "Uplink: give"
+ var/obj/item/device/uplink/hidden/suplink = find_syndicate_uplink()
+ var/crystals
+ if (suplink)
+ crystals = suplink.uses
+ if (suplink)
+ text += "|take"
+ if (check_rights(R_FUN, 0))
+ text += ", [crystals] crystals"
+ else
+ text += ", [crystals] crystals"
+ text += "." //hiel grammar
+ out += text
+
+ out += "
"
+
+ out += "Memory:
"
+ out += memory
+ out += "
Edit memory
"
+ out += "Objectives:
"
+ if (objectives.len == 0)
+ out += "EMPTY
"
+ else
+ var/obj_count = 1
+ for(var/datum/objective/objective in objectives)
+ out += "[obj_count]: [objective.explanation_text] Edit Delete Toggle Completion
"
+ obj_count++
+ out += "Add objective
"
+
+ out += "Announce objectives
"
+
+ usr << browse(out, "window=edit_memory[src];size=500x600")
+
+
+
+/datum/mind/Topic(href, href_list)
+ if(!check_rights(R_ADMIN))
+ return
+
+ if (href_list["role_edit"])
+ var/new_role = input("Select new role", "Assigned role", assigned_role) as null|anything in get_all_jobs()
+ if (!new_role)
+ return
+ assigned_role = new_role
+
+ else if (href_list["memory_edit"])
+ var/new_memo = copytext(sanitize(input("Write new memory", "Memory", memory) as null|message),1,MAX_MESSAGE_LEN)
+ if (isnull(new_memo))
+ return
+ memory = new_memo
+
+ 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 //sanity
+ def_value = objective.type
+
+ var/datum/objective/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in (typesof(/datum/objective) - list(/datum/objective, /datum/objective/default, /datum/objective/escape_obj, /datum/objective/changeling_team_objective)) //keep out the abstract ones
+ if (!new_obj_type)
+ return
+ if (initial(new_obj_type.required_role) != special_role && initial(new_obj_type.required_role) != null)
+ if(alert("The objective requires a special_role that this mind does not have. The player may not be able to complete the objective. Are you sure you want to continue?","uh oh" ,"Yes", "No") == "No")
+ return
+
+ var/datum/objective/new_objective = add_objective(src, new_obj_type)
+
+ if (istype(new_objective, /datum/objective/custom)) //it's lame I know but this type is snowflaky by its very nature
+ var/expl = stripped_input(usr, "Custom objective:", "Objective", objective ? objective.explanation_text : "")
+ if (!expl)
+ expl = "Free objective"
+ new_objective.explanation_text = expl
+
+ if (!new_objective)
+ usr << initial(new_obj_type.error_text)
+ return
+
+ if (objective)
+ objectives -= objective
+ objectives.Insert(objective_pos, new_objective)
+ message_admins("[key_name_admin(usr)] edited [current]'s objective to [new_objective.explanation_text]")
+ log_admin("[key_name(usr)] edited [current]'s objective to [new_objective.explanation_text]")
+ else
+ message_admins("[key_name_admin(usr)] added a new objective for [current]: [new_objective.explanation_text]")
+ log_admin("[key_name(usr)] added a new objective for [current]: [new_objective.explanation_text]")
+
+ else if (href_list["obj_delete"])
+ var/datum/objective/objective = locate(href_list["obj_delete"])
+ if(!istype(objective))
+ return
+ objectives -= objective
+ message_admins("[key_name_admin(usr)] removed an objective for [current]: [objective.explanation_text]")
+ log_admin("[key_name(usr)] removed an objective for [current]: [objective.explanation_text]")
+
+ else if(href_list["obj_completed"])
+ var/datum/objective/objective = locate(href_list["obj_completed"])
+ if(!istype(objective))
+ return
+ objective.completed = !objective.completed
+ log_admin("[key_name(usr)] toggled the win state for [current]'s objective: [objective.explanation_text]")
+ else if (href_list["handofgod"])
+ switch(href_list["handofgod"])
+ if("clear") //wipe handofgod status
+ if((src in ticker.mode.red_deity_followers) || (src in ticker.mode.blue_deity_followers) || (src in ticker.mode.red_deity_prophets) || (src in ticker.mode.blue_deity_prophets))
+ remove_hog_follower_prophet()
+ current << "You have been brainwashed... again! Your faith is no more!"
+ message_admins("[key_name_admin(usr)] has de-hand of god'ed [current].")
+ log_admin("[key_name(usr)] has de-hand of god'ed [current].")
+
+ if("red follower")
+ make_Handofgod_follower("red")
+ message_admins("[key_name_admin(usr)] has red follower'ed [current].")
+ log_admin("[key_name(usr)] has red follower'ed [current].")
+
+ if("red prophet")
+ make_Handofgod_prophet("red")
+ message_admins("[key_name_admin(usr)] has red prophet'ed [current].")
+ log_admin("[key_name(usr)] has red prophet'ed [current].")
+
+ if("blue follower")
+ make_Handofgod_follower("blue")
+ message_admins("[key_name_admin(usr)] has blue follower'ed [current].")
+ log_admin("[key_name(usr)] has blue follower'ed [current].")
+
+ if("blue prophet")
+ make_Handofgod_prophet("blue")
+ message_admins("[key_name_admin(usr)] has blue prophet'ed [current].")
+ log_admin("[key_name(usr)] has blue prophet'ed [current].")
+
+ if("red god")
+ make_Handofgod_god("red")
+ message_admins("[key_name_admin(usr)] has red god'ed [current].")
+ log_admin("[key_name(usr)] has red god'ed [current].")
+
+ if("blue god")
+ make_Handofgod_god("blue")
+ message_admins("[key_name_admin(usr)] has blue god'ed [current].")
+ log_admin("[key_name(usr)] has blue god'ed [current].")
+
+ else if (href_list["revolution"])
+ switch(href_list["revolution"])
+ if("clear")
+ remove_rev()
+ current << "You have been brainwashed! You are no longer a revolutionary!"
+ message_admins("[key_name_admin(usr)] has de-rev'ed [current].")
+ log_admin("[key_name(usr)] has de-rev'ed [current].")
+ if("rev")
+ if(src in ticker.mode.head_revolutionaries)
+ ticker.mode.head_revolutionaries -= src
+ ticker.mode.update_rev_icons_removed(src)
+ current << "Revolution has been disappointed of your leader traits! You are a regular revolutionary now!"
+ else if(!(src in ticker.mode.revolutionaries))
+ current << " You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!"
+ else
+ return
+ ticker.mode.revolutionaries += src
+ ticker.mode.update_rev_icons_added(src)
+ special_role = "Revolutionary"
+ message_admins("[key_name_admin(usr)] has rev'ed [current].")
+ log_admin("[key_name(usr)] has rev'ed [current].")
+
+ if("headrev")
+ if(src in ticker.mode.revolutionaries)
+ ticker.mode.revolutionaries -= src
+ ticker.mode.update_rev_icons_removed(src)
+ current << "You have proved your devotion to revoltion! Yea are a head revolutionary now!"
+ else if(!(src in ticker.mode.head_revolutionaries))
+ current << "You are a member of the revolutionaries' leadership now!"
+ else
+ return
+ if (ticker.mode.head_revolutionaries.len>0)
+ // copy targets
+ var/datum/mind/valid_head = locate() in ticker.mode.head_revolutionaries
+ if (valid_head)
+ for (var/datum/objective/mutiny/O in valid_head.objectives)
+ var/datum/objective/mutiny/rev_obj = new
+ rev_obj.owner = src
+ rev_obj.target = O.target
+ rev_obj.explanation_text = "Assassinate [O.target.name], the [O.target.assigned_role]."
+ objectives += rev_obj
+ ticker.mode.greet_revolutionary(src,0)
+ ticker.mode.head_revolutionaries += src
+ ticker.mode.update_rev_icons_added(src)
+ special_role = "Head Revolutionary"
+ message_admins("[key_name_admin(usr)] has head-rev'ed [current].")
+ log_admin("[key_name(usr)] has head-rev'ed [current].")
+
+ if("autoobjectives")
+ ticker.mode.forge_revolutionary_objectives(src)
+ ticker.mode.greet_revolutionary(src,0)
+ usr << "The objectives for revolution have been generated and shown to [key]"
+
+ if("flash")
+ if (!ticker.mode.equip_revolutionary(current))
+ usr << "Spawning flash failed!"
+
+ if("takeflash")
+ var/list/L = current.get_contents()
+ var/obj/item/device/assembly/flash/flash = locate() in L
+ if (!flash)
+ usr << "Deleting flash failed!"
+ qdel(flash)
+
+ if("repairflash")
+ var/list/L = current.get_contents()
+ var/obj/item/device/assembly/flash/flash = locate() in L
+ if (!flash)
+ usr << "Repairing flash failed!"
+ else
+ flash.crit_fail = 0
+ flash.update_icon()
+
+
+
+//////////////////// GANG MODE
+
+ else if (href_list["gang"])
+ switch(href_list["gang"])
+ if("clear")
+ remove_gang()
+ message_admins("[key_name_admin(usr)] has de-gang'ed [current].")
+ log_admin("[key_name(usr)] has de-gang'ed [current].")
+
+ if("equip")
+ switch(ticker.mode.equip_gang(current,gang_datum))
+ if(1)
+ usr << "Unable to equip territory spraycan!"
+ if(2)
+ usr << "Unable to equip recruitment pen and spraycan!"
+ if(3)
+ usr << "Unable to equip gangtool, pen, and spraycan!"
+
+ if("takeequip")
+ var/list/L = current.get_contents()
+ for(var/obj/item/weapon/pen/gang/pen in L)
+ qdel(pen)
+ for(var/obj/item/device/gangtool/gangtool in L)
+ qdel(gangtool)
+ for(var/obj/item/toy/crayon/spraycan/gang/SC in L)
+ qdel(SC)
+
+ if("new")
+ if(gang_colors_pool.len)
+ var/list/names = list("Random") + gang_name_pool
+ var/gangname = input("Pick a gang name.","Select Name") as null|anything in names
+ if(gangname && gang_colors_pool.len) //Check again just in case another admin made max gangs at the same time
+ if(!(gangname in gang_name_pool))
+ gangname = null
+ var/datum/gang/newgang = new(null,gangname)
+ ticker.mode.gangs += newgang
+ message_admins("[key_name_admin(usr)] has created the [newgang.name] Gang.")
+ log_admin("[key_name(usr)] has created the [newgang.name] Gang.")
+
+ else if (href_list["gangboss"])
+ var/datum/gang/G = locate(href_list["gangboss"]) in ticker.mode.gangs
+ if(!G || (src in G.bosses))
+ return
+ ticker.mode.remove_gangster(src,0,2,1)
+ G.bosses += src
+ gang_datum = G
+ special_role = "[G.name] Gang Boss"
+ G.add_gang_hud(src)
+ current << "You are a [G.name] Gang Boss!"
+ message_admins("[key_name_admin(usr)] has added [current] to the [G.name] Gang leadership.")
+ log_admin("[key_name(usr)] has added [current] to the [G.name] Gang leadership.")
+ ticker.mode.forge_gang_objectives(src)
+ ticker.mode.greet_gang(src,0)
+
+ else if (href_list["gangster"])
+ var/datum/gang/G = locate(href_list["gangster"]) in ticker.mode.gangs
+ if(!G || (src in G.gangsters))
+ return
+ ticker.mode.remove_gangster(src,0,2,1)
+ ticker.mode.add_gangster(src,G,0)
+ message_admins("[key_name_admin(usr)] has added [current] to the [G.name] Gang (A).")
+ log_admin("[key_name(usr)] has added [current] to the [G.name] Gang (A).")
+
+/////////////////////////////////
+
+
+
+ else if (href_list["cult"])
+ switch(href_list["cult"])
+ if("clear")
+ remove_cultist()
+ current << "You have been brainwashed! You are no longer a cultist!"
+ message_admins("[key_name_admin(usr)] has de-cult'ed [current].")
+ log_admin("[key_name(usr)] has de-cult'ed [current].")
+ if("cultist")
+ if(!(src in ticker.mode.cult))
+ ticker.mode.add_cultist(src)
+ message_admins("[key_name_admin(usr)] has cult'ed [current].")
+ log_admin("[key_name(usr)] has cult'ed [current].")
+
+ if("equip")
+ if (!ticker.mode.equip_cultist(current))
+ usr << "equip_cultist() failed! [current]'s starting equipment will be incomplete."
+
+ else if (href_list["wizard"])
+ switch(href_list["wizard"])
+ if("clear")
+ remove_wizard()
+ current << "You have been brainwashed! You are no longer a wizard!"
+ log_admin("[key_name(usr)] has de-wizard'ed [current].")
+ if("wizard")
+ if(!(src in ticker.mode.wizards))
+ ticker.mode.wizards += src
+ special_role = "Wizard"
+ //ticker.mode.learn_basic_spells(current)
+ current << "You are the Space Wizard!"
+ message_admins("[key_name_admin(usr)] has wizard'ed [current].")
+ log_admin("[key_name(usr)] has wizard'ed [current].")
+ if("lair")
+ current.loc = pick(wizardstart)
+ if("dressup")
+ ticker.mode.equip_wizard(current)
+ if("name")
+ ticker.mode.name_wizard(current)
+ if("autoobjectives")
+ ticker.mode.forge_wizard_objectives(src)
+ usr << "The objectives for wizard [key] have been generated. You can edit them and anounce manually."
+
+ else if (href_list["changeling"])
+ switch(href_list["changeling"])
+ if("clear")
+ remove_changeling()
+ current << "You grow weak and lose your powers! You are no longer a changeling and are stuck in your current form!"
+ message_admins("[key_name_admin(usr)] has de-changeling'ed [current].")
+ log_admin("[key_name(usr)] has de-changeling'ed [current].")
+ if("changeling")
+ if(!(src in ticker.mode.changelings))
+ ticker.mode.changelings += src
+ current.make_changeling()
+ special_role = "Changeling"
+ current << "Your powers are awoken. A flash of memory returns to us...we are [changeling.changelingID], a changeling!"
+ message_admins("[key_name_admin(usr)] has changeling'ed [current].")
+ log_admin("[key_name(usr)] has changeling'ed [current].")
+ if("autoobjectives")
+ ticker.mode.forge_changeling_objectives(src)
+ usr << "The objectives for changeling [key] have been generated. You can edit them and anounce manually."
+
+ if("initialdna")
+ if( !changeling || !changeling.stored_profiles.len || !istype(current, /mob/living/carbon))
+ usr << "Resetting DNA failed!"
+ else
+ var/mob/living/carbon/C = current
+ changeling.first_prof.dna.transfer_identity(C, transfer_SE=1)
+ C.real_name = changeling.first_prof.name
+ C.updateappearance(mutcolor_update=1)
+ C.domutcheck()
+
+ else if (href_list["nuclear"])
+ switch(href_list["nuclear"])
+ if("clear")
+ remove_nukeop()
+ current << "You have been brainwashed! You are no longer a syndicate operative!"
+ message_admins("[key_name_admin(usr)] has de-nuke op'ed [current].")
+ log_admin("[key_name(usr)] has de-nuke op'ed [current].")
+ if("nuclear")
+ if(!(src in ticker.mode.syndicates))
+ ticker.mode.syndicates += src
+ ticker.mode.update_synd_icons_added(src)
+ if (ticker.mode.syndicates.len==1)
+ ticker.mode.prepare_syndicate_leader(src)
+ else
+ current.real_name = "[syndicate_name()] Operative #[ticker.mode.syndicates.len-1]"
+ special_role = "Syndicate"
+ assigned_role = "Syndicate"
+ current << "You are a [syndicate_name()] agent!"
+ ticker.mode.forge_syndicate_objectives(src)
+ ticker.mode.greet_syndicate(src)
+ message_admins("[key_name_admin(usr)] has nuke op'ed [current].")
+ log_admin("[key_name(usr)] has nuke op'ed [current].")
+ if("lair")
+ current.loc = get_turf(locate("landmark*Syndicate-Spawn"))
+ if("dressup")
+ var/mob/living/carbon/human/H = current
+ qdel(H.belt)
+ qdel(H.back)
+ qdel(H.ears)
+ qdel(H.gloves)
+ qdel(H.head)
+ qdel(H.shoes)
+ qdel(H.wear_id)
+ qdel(H.wear_suit)
+ qdel(H.w_uniform)
+
+ if (!ticker.mode.equip_syndicate(current))
+ usr << "Equipping a syndicate failed!"
+ if("tellcode")
+ var/code
+ for (var/obj/machinery/nuclearbomb/bombue in machines)
+ if (length(bombue.r_code) <= 5 && bombue.r_code != "LOLNO" && bombue.r_code != "ADMIN")
+ code = bombue.r_code
+ break
+ if (code)
+ store_memory("Syndicate Nuclear Bomb Code: [code]", 0, 0)
+ current << "The nuclear authorization code is: [code]"
+ else
+ usr << "No valid nuke found!"
+
+ else if (href_list["traitor"])
+ switch(href_list["traitor"])
+ if("clear")
+ remove_traitor()
+ current << "You have been brainwashed! You are no longer a traitor!"
+ message_admins("[key_name_admin(usr)] has de-traitor'ed [current].")
+ log_admin("[key_name(usr)] has de-traitor'ed [current].")
+
+ if("traitor")
+ if(!(src in ticker.mode.traitors))
+ ticker.mode.traitors += src
+ special_role = "traitor"
+ current << "You are a traitor!"
+ message_admins("[key_name_admin(usr)] has traitor'ed [current].")
+ log_admin("[key_name(usr)] has traitor'ed [current].")
+ if(isAI(current))
+ var/mob/living/silicon/ai/A = current
+ ticker.mode.add_law_zero(A)
+ A.show_laws()
+
+ if("autoobjectives")
+ ticker.mode.forge_traitor_objectives(src)
+ usr << "The objectives for traitor [key] have been generated. You can edit them and anounce manually."
+
+ else if(href_list["shadowling"])
+ switch(href_list["shadowling"])
+ if("clear")
+ ticker.mode.update_shadow_icons_removed(src)
+ if(src in ticker.mode.shadows)
+ ticker.mode.shadows -= src
+ special_role = null
+ current << "Your powers have been quenched! You are no longer a shadowling!"
+ remove_spell(/obj/effect/proc_holder/spell/self/shadowling_hatch)
+ remove_spell(/obj/effect/proc_holder/spell/self/shadowling_ascend)
+ remove_spell(/obj/effect/proc_holder/spell/targeted/enthrall)
+ remove_spell(/obj/effect/proc_holder/spell/self/shadowling_hivemind)
+ message_admins("[key_name_admin(usr)] has de-shadowling'ed [current].")
+ log_admin("[key_name(usr)] has de-shadowling'ed [current].")
+ else if(src in ticker.mode.thralls)
+ ticker.mode.remove_thrall(src,0)
+ message_admins("[key_name_admin(usr)] has de-thrall'ed [current].")
+ log_admin("[key_name(usr)] has de-thrall'ed [current].")
+ if("shadowling")
+ if(!ishuman(current))
+ usr << "This only works on humans!"
+ return
+ ticker.mode.shadows += src
+ special_role = "shadowling"
+ current << "Something stirs deep in your mind. A red light floods your vision, and slowly you remember. Though your human disguise has served you well, the \
+ time is nigh to cast it off and enter your true form. You have disguised yourself amongst the humans, but you are not one of them. You are a shadowling, and you are to ascend at all costs.\
+ "
+ ticker.mode.finalize_shadowling(src)
+ ticker.mode.update_shadow_icons_added(src)
+ if("thrall")
+ if(!ishuman(current))
+ usr << "This only works on humans!"
+ return
+ ticker.mode.add_thrall(src)
+ message_admins("[key_name_admin(usr)] has thrall'ed [current].")
+ log_admin("[key_name(usr)] has thrall'ed [current].")
+
+ else if(href_list["abductor"])
+ switch(href_list["abductor"])
+ if("clear")
+ usr << "Not implemented yet. Sorry!"
+ if("abductor")
+ if(!ishuman(current))
+ usr << "This only works on humans!"
+ return
+ make_Abductor()
+ log_admin("[key_name(usr)] turned [current] into abductor.")
+ if("equip")
+ var/gear = alert("Agent or Scientist Gear","Gear","Agent","Scientist")
+ if(gear)
+ var/datum/game_mode/abduction/temp = new
+ temp.equip_common(current)
+ if(gear=="Agent")
+ temp.equip_agent(current)
+ else
+ temp.equip_scientist(current)
+
+ else if (href_list["monkey"])
+ var/mob/living/L = current
+ if (L.notransform)
+ return
+ switch(href_list["monkey"])
+ if("healthy")
+ if (check_rights(R_ADMIN))
+ var/mob/living/carbon/human/H = current
+ var/mob/living/carbon/monkey/M = current
+ if (istype(H))
+ log_admin("[key_name(usr)] attempting to monkeyize [key_name(current)]")
+ message_admins("[key_name_admin(usr)] attempting to monkeyize [key_name_admin(current)]")
+ src = null
+ M = H.monkeyize()
+ src = M.mind
+ //world << "DEBUG: \"healthy\": M=[M], M.mind=[M.mind], src=[src]!"
+ else if (istype(M) && length(M.viruses))
+ for(var/datum/disease/D in M.viruses)
+ D.cure(0)
+ sleep(0) //because deleting of virus is done through spawn(0)
+ if("infected")
+ if (check_rights(R_ADMIN, 0))
+ var/mob/living/carbon/human/H = current
+ var/mob/living/carbon/monkey/M = current
+ if (istype(H))
+ log_admin("[key_name(usr)] attempting to monkeyize and infect [key_name(current)]")
+ message_admins("[key_name_admin(usr)] attempting to monkeyize and infect [key_name_admin(current)]")
+ src = null
+ M = H.monkeyize()
+ src = M.mind
+ current.ForceContractDisease(new /datum/disease/transformation/jungle_fever)
+ else if (istype(M))
+ current.ForceContractDisease(new /datum/disease/transformation/jungle_fever)
+ if("human")
+ if (check_rights(R_ADMIN, 0))
+ var/mob/living/carbon/human/H = current
+ var/mob/living/carbon/monkey/M = current
+ if (istype(M))
+ for(var/datum/disease/D in M.viruses)
+ if (istype(D,/datum/disease/transformation/jungle_fever))
+ D.cure(0)
+ sleep(0) //because deleting of virus is doing throught spawn(0)
+ log_admin("[key_name(usr)] attempting to humanize [key_name(current)]")
+ message_admins("[key_name_admin(usr)] attempting to humanize [key_name_admin(current)]")
+ H = M.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG)
+ if(H)
+ src = H.mind
+
+ else if (href_list["silicon"])
+ switch(href_list["silicon"])
+
+ if("unemag")
+ var/mob/living/silicon/robot/R = current
+ if (istype(R))
+ R.SetEmagged(0)
+ message_admins("[key_name_admin(usr)] has unemag'ed [R].")
+ log_admin("[key_name(usr)] has unemag'ed [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.SetEmagged(0)
+ message_admins("[key_name_admin(usr)] has unemag'ed [ai]'s Cyborgs.")
+ log_admin("[key_name(usr)] has unemag'ed [ai]'s Cyborgs.")
+
+ else if (href_list["common"])
+ switch(href_list["common"])
+ if("undress")
+ for(var/obj/item/W in current)
+ current.unEquip(W, 1) //The 1 forces all items to drop, since this is an admin undress.
+ if("takeuplink")
+ take_uplink()
+ memory = null//Remove any memory they may have had.
+ log_admin("[key_name(usr)] removed [current]'s uplink.")
+ if("crystals")
+ if (check_rights(R_FUN, 0))
+ var/obj/item/device/uplink/hidden/suplink = find_syndicate_uplink()
+ var/crystals
+ if (suplink)
+ crystals = suplink.uses
+ crystals = input("Amount of telecrystals for [key]","Syndicate uplink", crystals) as null|num
+ if (!isnull(crystals))
+ if (suplink)
+ suplink.uses = crystals
+ message_admins("[key_name_admin(usr)] changed [current]'s telecrystal count to [crystals].")
+ log_admin("[key_name(usr)] changed [current]'s telecrystal count to [crystals].")
+ if("uplink")
+ if (!ticker.mode.equip_traitor(current, !(src in ticker.mode.traitors)))
+ usr << "Equipping a syndicate failed!"
+ log_admin("[key_name(usr)] attempted to give [current] an uplink.")
+
+ else if (href_list["obj_announce"])
+ var/obj_count = 1
+ current << "Your current objectives:"
+ for(var/datum/objective/objective in objectives)
+ current << "Objective #[obj_count]: [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)
+
+/datum/mind/proc/make_Traitor()
+ if(!(src in ticker.mode.traitors))
+ ticker.mode.traitors += src
+ special_role = "traitor"
+ ticker.mode.forge_traitor_objectives(src)
+ ticker.mode.finalize_traitor(src)
+ ticker.mode.greet_traitor(src)
+
+/datum/mind/proc/make_Nuke(turf/spawnloc,nuke_code,leader=0, telecrystals = TRUE)
+ if(!(src in ticker.mode.syndicates))
+ ticker.mode.syndicates += src
+ ticker.mode.update_synd_icons_added(src)
+ special_role = "Syndicate"
+ ticker.mode.forge_syndicate_objectives(src)
+ ticker.mode.greet_syndicate(src)
+
+ current.loc = spawnloc
+
+ var/mob/living/carbon/human/H = current
+ qdel(H.belt)
+ qdel(H.back)
+ qdel(H.ears)
+ qdel(H.gloves)
+ qdel(H.head)
+ qdel(H.shoes)
+ qdel(H.wear_id)
+ qdel(H.wear_suit)
+ qdel(H.w_uniform)
+
+ ticker.mode.equip_syndicate(current, telecrystals)
+
+ if (nuke_code)
+ store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0)
+ current << "The nuclear authorization code is: [nuke_code]"
+
+ if (leader)
+ ticker.mode.prepare_syndicate_leader(src,nuke_code)
+ else
+ current.real_name = "[syndicate_name()] Operative #[ticker.mode.syndicates.len-1]"
+
+/datum/mind/proc/make_Changling()
+ if(!(src in ticker.mode.changelings))
+ ticker.mode.changelings += src
+ current.make_changeling()
+ special_role = "Changeling"
+ ticker.mode.forge_changeling_objectives(src)
+ ticker.mode.greet_changeling(src)
+
+/datum/mind/proc/make_Wizard()
+ if(!(src in ticker.mode.wizards))
+ ticker.mode.wizards += src
+ special_role = "Wizard"
+ assigned_role = "Wizard"
+ //ticker.mode.learn_basic_spells(current)
+ if(!wizardstart.len)
+ current.loc = pick(latejoin)
+ current << "HOT INSERTION, GO GO GO"
+ else
+ current.loc = pick(wizardstart)
+
+ ticker.mode.equip_wizard(current)
+ for(var/obj/item/weapon/spellbook/S in current.contents)
+ S.op = 0
+ ticker.mode.name_wizard(current)
+ ticker.mode.forge_wizard_objectives(src)
+ ticker.mode.greet_wizard(src)
+
+
+/datum/mind/proc/make_Cultist()
+ if(!(src in ticker.mode.cult))
+ ticker.mode.cult += src
+ ticker.mode.update_cult_icons_added(src)
+ special_role = "Cultist"
+ current << "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie."
+ current << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back."
+ current << "Your objective is to summon Nar-Sie by building and defending a suitable shell for the Geometer. Adequate supplies can be procured through human sacrifices."
+ ticker.mode.equip_cultist(current)
+
+/datum/mind/proc/make_Rev()
+ if (ticker.mode.head_revolutionaries.len>0)
+ // copy targets
+ var/datum/mind/valid_head = locate() in ticker.mode.head_revolutionaries
+ if (valid_head)
+ for (var/datum/objective/mutiny/O in valid_head.objectives)
+ var/datum/objective/mutiny/rev_obj = new
+ rev_obj.owner = src
+ rev_obj.target = O.target
+ rev_obj.explanation_text = "Assassinate [O.target.current.real_name], the [O.target.assigned_role]."
+ objectives += rev_obj
+ ticker.mode.greet_revolutionary(src,0)
+ ticker.mode.head_revolutionaries += src
+ ticker.mode.update_rev_icons_added(src)
+ special_role = "Head Revolutionary"
+
+ ticker.mode.forge_revolutionary_objectives(src)
+ ticker.mode.greet_revolutionary(src,0)
+
+ var/list/L = current.get_contents()
+ var/obj/item/device/assembly/flash/flash = locate() in L
+ qdel(flash)
+ take_uplink()
+ var/fail = 0
+// fail |= !ticker.mode.equip_traitor(current, 1)
+ fail |= !ticker.mode.equip_revolutionary(current)
+
+
+/datum/mind/proc/make_Gang(datum/gang/G)
+ special_role = "[G.name] Gang Boss"
+ G.bosses += src
+ gang_datum = G
+ G.add_gang_hud(src)
+ ticker.mode.forge_gang_objectives(src)
+ ticker.mode.greet_gang(src)
+ ticker.mode.equip_gang(current,G)
+
+/datum/mind/proc/make_Abductor()
+ var/role = alert("Abductor Role ?","Role","Agent","Scientist")
+ var/team = input("Abductor Team ?","Team ?") in list(1,2,3,4)
+ var/teleport = alert("Teleport to ship ?","Teleport","Yes","No")
+
+ if(!role || !team || !teleport)
+ return
+
+ if(!ishuman(current))
+ return
+
+ ticker.mode.abductors |= src
+
+ var/datum/objective/experiment/O = new
+ O.owner = src
+ objectives += O
+
+ var/mob/living/carbon/human/H = current
+
+ H.set_species(/datum/species/abductor)
+ var/datum/species/abductor/S = H.dna.species
+
+ switch(role)
+ if("Agent")
+ S.agent = 1
+ if("Scientist")
+ S.scientist = 1
+ S.team = team
+
+ var/list/obj/effect/landmark/abductor/agent_landmarks = new
+ var/list/obj/effect/landmark/abductor/scientist_landmarks = new
+ agent_landmarks.len = 4
+ scientist_landmarks.len = 4
+ for(var/obj/effect/landmark/abductor/A in landmarks_list)
+ if(istype(A,/obj/effect/landmark/abductor/agent))
+ agent_landmarks[text2num(A.team)] = A
+ else if(istype(A,/obj/effect/landmark/abductor/scientist))
+ scientist_landmarks[text2num(A.team)] = A
+
+ var/obj/effect/landmark/L
+ if(teleport=="Yes")
+ switch(role)
+ if("Agent")
+ S.agent = 1
+ L = agent_landmarks[team]
+ H.loc = L.loc
+ if("Scientist")
+ S.scientist = 1
+ L = agent_landmarks[team]
+ H.loc = L.loc
+
+
+/datum/mind/proc/make_Handofgod_follower(colour)
+ . = 0
+ switch(colour)
+ if("red")
+ //Remove old allegiances
+ if(src in ticker.mode.blue_deity_followers || src in ticker.mode.blue_deity_prophets)
+ current << "You are no longer a member of the Blue cult!"
+
+ ticker.mode.blue_deity_followers -= src
+ ticker.mode.blue_deity_prophets -= src
+ current.faction |= "red god"
+ current.faction -= "blue god"
+
+ if(src in ticker.mode.red_deity_prophets)
+ current << "You have lost the connection with your deity, but you still believe in their grand design, You are no longer a prophet!"
+ ticker.mode.red_deity_prophets -= src
+
+ ticker.mode.red_deity_followers |= src
+ current << "You are now a follower of the red cult's god!"
+
+ special_role = "Hand of God: Red Follower"
+ . = 1
+ if("blue")
+ //Remove old allegiances
+ if(src in ticker.mode.red_deity_followers || src in ticker.mode.red_deity_prophets)
+ current << "You are no longer a member of the Red cult!"
+
+ ticker.mode.red_deity_followers -= src
+ ticker.mode.red_deity_prophets -= src
+ current.faction -= "red god"
+ current.faction |= "blue god"
+
+ if(src in ticker.mode.blue_deity_prophets)
+ current << "You have lost the connection with your deity, but you still believe in their grand design, You are no longer a prophet!"
+ ticker.mode.blue_deity_prophets -= src
+
+ ticker.mode.blue_deity_followers |= src
+ current << "You are now a follower of the blue cult's god!"
+
+ special_role = "Hand of God: Blue Follower"
+ . = 1
+ else
+ return 0
+
+ ticker.mode.update_hog_icons_removed(src,"red")
+ ticker.mode.update_hog_icons_removed(src,"blue")
+ //ticker.mode.greet_hog_follower(src,colour)
+ ticker.mode.update_hog_icons_added(src, colour)
+
+/datum/mind/proc/make_Handofgod_prophet(colour)
+ . = 0
+ switch(colour)
+ if("red")
+ //Remove old allegiances
+
+ if(src in ticker.mode.blue_deity_followers || src in ticker.mode.blue_deity_prophets)
+ current << "You are no longer a member of the Blue cult!"
+ current.faction -= "blue god"
+ current.faction |= "red god"
+
+ ticker.mode.blue_deity_followers -= src
+ ticker.mode.blue_deity_prophets -= src
+ ticker.mode.red_deity_followers -= src
+
+ ticker.mode.red_deity_prophets |= src
+ current << "You are now a prophet of the red cult's god!"
+
+ special_role = "Hand of God: Red Prophet"
+ . = 1
+ if("blue")
+ //Remove old allegiances
+
+ if(src in ticker.mode.red_deity_followers || src in ticker.mode.red_deity_prophets)
+ current << "You are no longer a member of the Red cult!"
+ current.faction -= "red god"
+ current.faction |= "blue god"
+
+ ticker.mode.red_deity_followers -= src
+ ticker.mode.red_deity_prophets -= src
+ ticker.mode.blue_deity_followers -= src
+
+ ticker.mode.blue_deity_prophets |= src
+ current << "You are now a prophet of the blue cult's god!"
+
+ special_role = "Hand of God: Blue Prophet"
+ . = 1
+
+ else
+ return 0
+
+ ticker.mode.update_hog_icons_removed(src,"red")
+ ticker.mode.update_hog_icons_removed(src,"blue")
+ ticker.mode.greet_hog_follower(src,colour)
+ ticker.mode.update_hog_icons_added(src, colour)
+
+
+/datum/mind/proc/make_Handofgod_god(colour)
+ switch(colour)
+ if("red")
+ current.become_god("red")
+ ticker.mode.add_god(src,"red")
+ if("blue")
+ current.become_god("blue")
+ ticker.mode.add_god(src,"blue")
+ else
+ return 0
+ ticker.mode.forge_deity_objectives(src)
+ ticker.mode.remove_hog_follower(src,0)
+ ticker.mode.update_hog_icons_added(src, colour)
+// ticker.mode.greet_hog_follower(src,colour)
+ return 1
+
+
+/datum/mind/proc/AddSpell(obj/effect/proc_holder/spell/spell)
+ spell_list += spell
+ if(!spell.action)
+ spell.action = new/datum/action/spell_action
+ spell.action.target = spell
+ spell.action.name = spell.name
+ spell.action.button_icon = spell.action_icon
+ spell.action.button_icon_state = spell.action_icon_state
+ spell.action.background_icon_state = spell.action_background_icon_state
+ spell.action.Grant(current)
+ return
+/datum/mind/proc/transfer_actions(mob/living/new_character)
+ if(current && current.actions)
+ for(var/datum/action/A in current.actions)
+ A.Grant(new_character)
+ transfer_mindbound_actions(new_character)
+
+/datum/mind/proc/transfer_mindbound_actions(var/mob/living/new_character)
+ for(var/obj/effect/proc_holder/spell/spell in spell_list)
+ if(!spell.action) // Unlikely but whatever
+ spell.action = new/datum/action/spell_action
+ spell.action.target = spell
+ spell.action.name = spell.name
+ spell.action.button_icon = spell.action_icon
+ spell.action.button_icon_state = spell.action_icon_state
+ spell.action.background_icon_state = spell.action_background_icon_state
+ spell.action.Grant(new_character)
+ return
+
+/mob/proc/sync_mind()
+ mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist)
+ mind.active = 1 //indicates that the mind is currently synced with a client
+
+/mob/new_player/sync_mind()
+ return
+
+/mob/dead/observer/sync_mind()
+ return
+
+//Initialisation procs
+/mob/proc/mind_initialize()
+ if(mind)
+ mind.key = key
+
+ else
+ mind = new /datum/mind(key)
+ if(ticker)
+ ticker.minds += mind
+ else
+ spawn(0)
+ throw EXCEPTION("mind_initialize(): No ticker ready")
+ if(!mind.name) mind.name = real_name
+ mind.current = src
+
+//HUMAN
+/mob/living/carbon/human/mind_initialize()
+ ..()
+ if(!mind.assigned_role) mind.assigned_role = "Assistant" //defualt
+
+//MONKEY
+/mob/living/carbon/monkey/mind_initialize()
+ ..()
+
+//slime
+/mob/living/simple_animal/slime/mind_initialize()
+ ..()
+ mind.special_role = "slime"
+ mind.assigned_role = "slime"
+
+//XENO
+/mob/living/carbon/alien/mind_initialize()
+ ..()
+ mind.special_role = "Alien"
+ mind.assigned_role = "Alien"
+ //XENO HUMANOID
+/mob/living/carbon/alien/humanoid/royal/queen/mind_initialize()
+ ..()
+ mind.special_role = "Queen"
+
+/mob/living/carbon/alien/humanoid/royal/praetorian/mind_initialize()
+ ..()
+ mind.special_role = "Praetorian"
+
+/mob/living/carbon/alien/humanoid/hunter/mind_initialize()
+ ..()
+ mind.special_role = "Hunter"
+
+/mob/living/carbon/alien/humanoid/drone/mind_initialize()
+ ..()
+ mind.special_role = "Drone"
+
+/mob/living/carbon/alien/humanoid/sentinel/mind_initialize()
+ ..()
+ mind.special_role = "Sentinel"
+ //XENO LARVA
+/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 = ""
+
+//BLOB
+/mob/camera/blob/mind_initialize()
+ ..()
+ mind.special_role = "Blob"
+
+//Animals
+/mob/living/simple_animal/mind_initialize()
+ ..()
+ mind.assigned_role = "Animal"
+ mind.special_role = "Animal"
+
+/mob/living/simple_animal/pet/dog/corgi/mind_initialize()
+ ..()
+ mind.assigned_role = "Corgi"
+ mind.special_role = "Corgi"
+
+/mob/living/simple_animal/shade/mind_initialize()
+ ..()
+ mind.assigned_role = "Shade"
+ mind.special_role = "Shade"
+
+/mob/living/simple_animal/hostile/construct/mind_initialize()
+ ..()
+ mind.assigned_role = "[initial(name)]"
+ mind.special_role = "Cultist"
+
diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm
index 6cce1a297a7..d61bb3607e1 100644
--- a/code/game/gamemodes/antag_spawner.dm
+++ b/code/game/gamemodes/antag_spawner.dm
@@ -92,14 +92,13 @@
M << "Your service has not gone unrewarded, however. Studying under [usr.real_name], you have learned stealthy, robeless spells. You are able to cast knock and mindswap."
equip_antag(M)
+ var/mob/living/carbon/human/H = usr
var/wizard_name_first = pick(wizard_first)
var/wizard_name_second = pick(wizard_second)
var/randomname = "[wizard_name_first] [wizard_name_second]"
- var/datum/objective/protect/new_objective = new /datum/objective/protect
- new_objective.owner = M:mind
- new_objective:target = usr:mind
- new_objective.explanation_text = "Protect [usr.real_name], the wizard."
- M.mind.objectives += new_objective
+ var/datum/objective/default/protect/new_objective = add_objective(M.mind, /datum/objective/default/protect)
+ new_objective.target = H.mind
+ new_objective.explanation_text = "Protect [H.real_name], the wizard."
ticker.mode.apprentices += M.mind
M.mind.special_role = "apprentice"
ticker.mode.update_wiz_icons_added(M.mind)
@@ -252,11 +251,9 @@
S.mind.assigned_role = "Slaughter Demon"
S.mind.special_role = "Slaughter Demon"
ticker.mode.traitors += S.mind
- var/datum/objective/assassinate/new_objective = new /datum/objective/assassinate
- new_objective.owner = S.mind
+ var/datum/objective/default/assassinate/new_objective = add_objective(S.mind, /datum/objective/default/assassinate)
new_objective.target = usr.mind
new_objective.explanation_text = "Kill [usr.real_name], the one who summoned you."
- S.mind.objectives += new_objective
var/datum/objective/new_objective2 = new /datum/objective
new_objective2.owner = S.mind
new_objective2.explanation_text = "Kill everyone else while you're at it."
@@ -264,4 +261,4 @@
S << S.playstyle_string
S << "You are currently not currently in the same plane of existence as the station. Ctrl+Click a blood pool to manifest."
S << "Objective #[1]: [new_objective.explanation_text]"
- S << "Objective #[2]: [new_objective2.explanation_text]"
+ S << "Objective #[2]: [new_objective2.explanation_text]"
\ No newline at end of file
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index bd417180b6d..2506052b8f2 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -113,9 +113,6 @@ var/list/slot2type = list("head" = /obj/item/clothing/head/changeling, "wear_mas
/datum/game_mode/proc/forge_changeling_objectives(datum/mind/changeling, var/team_mode = 0)
//OBJECTIVES - random traitor objectives. Unique objectives "steal brain" and "identity theft".
- //No escape alone because changelings aren't suited for it and it'd probably just lead to rampant robusting
- //If it seems like they'd be able to do it in play, add a 10% chance to have to escape alone
-
var/escape_objective_possible = TRUE
//if there's a team objective, check if it's compatible with escape objectives
@@ -124,63 +121,7 @@ var/list/slot2type = list("head" = /obj/item/clothing/head/changeling, "wear_mas
escape_objective_possible = FALSE
break
- var/datum/objective/absorb/absorb_objective = new
- absorb_objective.owner = changeling
- absorb_objective.gen_amount_goal(6, 8)
- changeling.objectives += absorb_objective
-
- if(prob(60))
- var/datum/objective/steal/steal_objective = new
- steal_objective.owner = changeling
- steal_objective.find_target()
- changeling.objectives += steal_objective
-
- var/list/active_ais = active_ais()
- if(active_ais.len && prob(100/joined_player_list.len))
- var/datum/objective/destroy/destroy_objective = new
- destroy_objective.owner = changeling
- destroy_objective.find_target()
- changeling.objectives += destroy_objective
- else
- if(prob(70))
- var/datum/objective/assassinate/kill_objective = new
- kill_objective.owner = changeling
- if(team_mode) //No backstabbing while in a team
- kill_objective.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
- else
- kill_objective.find_target()
- changeling.objectives += kill_objective
- else
- var/datum/objective/maroon/maroon_objective = new
- maroon_objective.owner = changeling
- if(team_mode)
- maroon_objective.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
- else
- maroon_objective.find_target()
- changeling.objectives += maroon_objective
-
- if (!(locate(/datum/objective/escape) in changeling.objectives) && escape_objective_possible)
- var/datum/objective/escape/escape_with_identity/identity_theft = new
- identity_theft.owner = changeling
- identity_theft.target = maroon_objective.target
- identity_theft.update_explanation_text()
- changeling.objectives += identity_theft
- escape_objective_possible = FALSE
-
- if (!(locate(/datum/objective/escape) in changeling.objectives) && escape_objective_possible)
- if(prob(50))
- var/datum/objective/escape/escape_objective = new
- escape_objective.owner = changeling
- changeling.objectives += escape_objective
- else
- var/datum/objective/escape/escape_with_identity/identity_theft = new
- identity_theft.owner = changeling
- if(team_mode)
- identity_theft.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
- else
- identity_theft.find_target()
- changeling.objectives += identity_theft
- escape_objective_possible = FALSE
+ generate_objectives(changeling, 4, escape_objective_possible)
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 3490b4c750b..073d828dc81 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -1,838 +1,927 @@
-/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/dangerrating = 0 //How hard the objective is, essentially. Used for dishing out objectives and checking overall victory.
- var/martyr_compatible = 0 //If the objective is compatible with martyr objective, i.e. if you can still do it while dead.
-
-/datum/objective/New(var/text)
- if(text)
- explanation_text = text
-
-/datum/objective/proc/check_completion()
- return completed
-
-/datum/objective/proc/is_unique_objective(possible_target)
- for(var/datum/objective/O in owner.objectives)
- if(istype(O, type) && O.get_target() == possible_target)
- return 0
- return 1
-
-/datum/objective/proc/get_target()
- return target
-
-/datum/objective/proc/find_target()
- var/list/possible_targets = list()
- for(var/datum/mind/possible_target in ticker.minds)
- if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != 2) && is_unique_objective(possible_target))
- possible_targets += possible_target
- if(possible_targets.len > 0)
- target = pick(possible_targets)
- update_explanation_text()
- return target
-
-/datum/objective/proc/find_target_by_role(role, role_type=0, invert=0)//Option sets either to check assigned role or special role. Default to assigned., invert inverts the check, eg: "Don't choose a Ling"
- for(var/datum/mind/possible_target in ticker.minds)
- if((possible_target != owner) && ishuman(possible_target.current))
- var/is_role = 0
- if(role_type)
- if(possible_target.special_role == role)
- is_role++
- else
- if(possible_target.assigned_role == role)
- is_role++
-
- if(invert)
- if(is_role)
- continue
- target = possible_target
- break
- else if(is_role)
- target = possible_target
- break
-
- update_explanation_text()
-
-/datum/objective/proc/update_explanation_text()
- //Default does nothing, override where needed
-
-/datum/objective/proc/give_special_equipment()
-
-/datum/objective/assassinate
- var/target_role_type=0
- dangerrating = 10
- martyr_compatible = 1
-
-/datum/objective/assassinate/find_target_by_role(role, role_type=0, invert=0)
- if(!invert)
- target_role_type = role_type
- ..()
- return target
-
-/datum/objective/assassinate/check_completion()
- if(target && target.current)
- if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current) || target.current.z > 6 || !target.current.ckey) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite
- return 1
- return 0
- return 1
-
-/datum/objective/assassinate/update_explanation_text()
- ..()
- if(target && target.current)
- explanation_text = "Assassinate [target.name], the [!target_role_type ? target.assigned_role : target.special_role]."
- else
- explanation_text = "Free Objective"
-
-
-/datum/objective/mutiny
- var/target_role_type=0
- martyr_compatible = 1
-
-/datum/objective/mutiny/find_target_by_role(role, role_type=0,invert=0)
- if(!invert)
- target_role_type = role_type
- ..()
- return target
-
-/datum/objective/mutiny/check_completion()
- if(target && target.current)
- if(target.current.stat == DEAD || !ishuman(target.current) || !target.current.ckey || !target.current.client)
- return 1
- var/turf/T = get_turf(target.current)
- if(T && (T.z > ZLEVEL_STATION) || target.current.client.is_afk()) //If they leave the station or go afk they count as dead for this
- return 2
- return 0
- return 1
-
-/datum/objective/mutiny/update_explanation_text()
- ..()
- if(target && target.current)
- explanation_text = "Assassinate or exile [target.name], the [!target_role_type ? target.assigned_role : target.special_role]."
- else
- explanation_text = "Free Objective"
-
-
-
-/datum/objective/maroon
- var/target_role_type=0
- dangerrating = 5
- martyr_compatible = 1
-
-/datum/objective/maroon/find_target_by_role(role, role_type=0, invert=0)
- if(!invert)
- target_role_type = role_type
- ..()
- return target
-
-/datum/objective/maroon/check_completion()
- if(target && target.current)
- if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current) || target.current.z > 6 || !target.current.ckey) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite
- return 1
- if(target.current.onCentcom() || target.current.onSyndieBase())
- return 0
- return 1
-
-/datum/objective/maroon/update_explanation_text()
- if(target && target.current)
- explanation_text = "Prevent [target.name], the [!target_role_type ? target.assigned_role : target.special_role], from escaping alive."
- else
- explanation_text = "Free Objective"
-
-
-
-/datum/objective/debrain//I want braaaainssss
- var/target_role_type=0
- dangerrating = 20
-
-/datum/objective/debrain/find_target_by_role(role, role_type=0, invert=0)
- if(!invert)
- target_role_type = role_type
- ..()
- return target
-
-/datum/objective/debrain/check_completion()
- if(!target)//If it's a free objective.
- return 1
- if( !owner.current || owner.current.stat==DEAD )//If you're otherwise dead.
- return 0
- if( !target.current || !isbrain(target.current) )
- return 0
- var/atom/A = target.current
- while(A.loc) //check to see if the brainmob is on our person
- A = A.loc
- if(A == owner.current)
- return 1
- return 0
-
-/datum/objective/debrain/update_explanation_text()
- ..()
- if(target && target.current)
- explanation_text = "Steal the brain of [target.name], the [!target_role_type ? target.assigned_role : target.special_role]."
- else
- explanation_text = "Free Objective"
-
-
-
-/datum/objective/protect//The opposite of killing a dude.
- var/target_role_type=0
- dangerrating = 10
- martyr_compatible = 1
-
-/datum/objective/protect/find_target_by_role(role, role_type=0, invert=0)
- if(!invert)
- target_role_type = role_type
- ..()
- return target
-
-/datum/objective/protect/check_completion()
- if(!target) //If it's a free objective.
- return 1
- if(target.current)
- if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current))
- return 0
- return 1
- return 0
-
-/datum/objective/protect/update_explanation_text()
- ..()
- if(target && target.current)
- explanation_text = "Protect [target.name], the [!target_role_type ? target.assigned_role : target.special_role]."
- else
- explanation_text = "Free Objective"
-
-
-
-/datum/objective/hijack
- explanation_text = "Hijack the shuttle to ensure no loyalist Nanotrasen crew escape alive and out of custody."
- dangerrating = 25
- martyr_compatible = 0 //Technically you won't get both anyway.
-
-/datum/objective/hijack/check_completion()
- if(!owner.current || owner.current.stat)
- return 0
- if(SSshuttle.emergency.mode < SHUTTLE_ENDGAME)
- return 0
- if(issilicon(owner.current))
- return 0
-
- var/area/A = get_area(owner.current)
- if(SSshuttle.emergency.areaInstance != A)
- return 0
-
- for(var/mob/living/player in player_list)
- if(player.mind && player.mind != owner)
- if(player.stat != DEAD)
- if(istype(player, /mob/living/silicon)) //Borgs are technically dead anyways
- continue
- if(get_area(player) == A)
- if(!player.mind.special_role && !istype(get_turf(player.mind.current), /turf/simulated/floor/plasteel/shuttle/red))
- return 0
- return 1
-
-/datum/objective/hijackclone
- explanation_text = "Hijack the emergency shuttle by ensuring only you (or your copies) escape."
- dangerrating = 25
- martyr_compatible = 0
-
-/datum/objective/hijackclone/check_completion()
- if(!owner.current)
- return 0
- if(SSshuttle.emergency.mode < SHUTTLE_ENDGAME)
- return 0
-
- var/area/A = SSshuttle.emergency.areaInstance
-
- for(var/mob/living/player in player_list) //Make sure nobody else is onboard
- if(player.mind && player.mind != owner)
- if(player.stat != DEAD)
- if(istype(player, /mob/living/silicon))
- continue
- if(get_area(player) == A)
- if(player.real_name != owner.current.real_name && !istype(get_turf(player.mind.current), /turf/simulated/floor/plasteel/shuttle/red))
- return 0
-
- for(var/mob/living/player in player_list) //Make sure at least one of you is onboard
- if(player.mind && player.mind != owner)
- if(player.stat != DEAD)
- if(istype(player, /mob/living/silicon))
- continue
- if(get_area(player) == A)
- if(player.real_name == owner.current.real_name && !istype(get_turf(player.mind.current), /turf/simulated/floor/plasteel/shuttle/red))
- return 1
- return 0
-
-/datum/objective/block
- explanation_text = "Do not allow any organic lifeforms to escape on the shuttle alive."
- dangerrating = 25
- martyr_compatible = 1
-
-/datum/objective/block/check_completion()
- if(!istype(owner.current, /mob/living/silicon))
- return 0
- if(SSshuttle.emergency.mode < SHUTTLE_ENDGAME)
- return 1
-
- var/area/A = SSshuttle.emergency.areaInstance
-
- for(var/mob/living/player in player_list)
- if(istype(player, /mob/living/silicon))
- continue
- if(player.mind)
- if(player.stat != DEAD)
- if(get_area(player) == A)
- return 0
-
- return 1
-
-
-/datum/objective/escape
- explanation_text = "Escape on the shuttle or an escape pod alive and without being in custody."
- dangerrating = 5
-
-/datum/objective/escape/check_completion()
- if(issilicon(owner.current))
- return 0
- if(isbrain(owner.current))
- return 0
- if(!owner.current || owner.current.stat == DEAD)
- return 0
- if(ticker.force_ending) //This one isn't their fault, so lets just assume good faith
- return 1
- if(ticker.mode.station_was_nuked) //If they escaped the blast somehow, let them win
- return 1
- if(SSshuttle.emergency.mode < SHUTTLE_ENDGAME)
- return 0
- var/turf/location = get_turf(owner.current)
- if(!location)
- return 0
-
- if(istype(location, /turf/simulated/floor/plasteel/shuttle/red)) // Fails traitors if they are in the shuttle brig -- Polymorph
- return 0
-
- if(location.onCentcom() || location.onSyndieBase())
- return 1
-
- return 0
-
-/datum/objective/escape/escape_with_identity
- dangerrating = 10
- var/target_real_name // Has to be stored because the target's real_name can change over the course of the round
- var/target_missing_id
-
-/datum/objective/escape/escape_with_identity/find_target()
- target = ..()
- update_explanation_text()
-
-/datum/objective/escape/escape_with_identity/update_explanation_text()
- if(target && target.current)
- target_real_name = target.current.real_name
- explanation_text = "Escape on the shuttle or an escape pod with the identity of [target_real_name], the [target.assigned_role]"
- var/mob/living/carbon/human/H
- if(ishuman(target.current))
- H = target.current
- if(H && H.get_id_name() != target_real_name)
- target_missing_id = 1
- else
- explanation_text += " while wearing their identification card"
- explanation_text += "." //Proper punctuation is important!
-
- else
- explanation_text = "Free Objective."
-
-/datum/objective/escape/escape_with_identity/check_completion()
- if(!target_real_name)
- return 1
- if(!ishuman(owner.current))
- return 0
- var/mob/living/carbon/human/H = owner.current
- if(..())
- if(H.dna.real_name == target_real_name)
- if(H.get_id_name()== target_real_name || target_missing_id)
- return 1
- return 0
-
-
-/datum/objective/survive
- explanation_text = "Stay alive until the end."
- dangerrating = 3
-
-/datum/objective/survive/check_completion()
- if(!owner.current || owner.current.stat == DEAD || isbrain(owner.current))
- return 0 //Brains no longer win survive objectives. --NEO
- if(!is_special_character(owner.current)) //This fails borg'd traitors
- return 0
- return 1
-
-
-/datum/objective/martyr
- explanation_text = "Die a glorious death."
- dangerrating = 1
-
-/datum/objective/martyr/check_completion()
- if(!owner.current) //Gibbed, etc.
- return 1
- if(owner.current && owner.current.stat == DEAD) //You're dead! Yay!
- return 1
- return 0
-
-
-/datum/objective/nuclear
- explanation_text = "Destroy the station with a nuclear device."
- martyr_compatible = 1
-
-/datum/objective/nuclear/check_completion()
- if(ticker && ticker.mode && ticker.mode.station_was_nuked)
- return 1
- return 0
-
-
-var/global/list/possible_items = list()
-/datum/objective/steal
- var/datum/objective_item/targetinfo = null //Save the chosen item datum so we can access it later.
- var/obj/item/steal_target = null //Needed for custom objectives (they're just items, not datums).
- dangerrating = 5 //Overridden by the individual item's difficulty, but defaults to 5 for custom objectives.
- martyr_compatible = 0
-
-/datum/objective/steal/get_target()
- return steal_target
-
-/datum/objective/steal/New()
- ..()
- if(!possible_items.len)//Only need to fill the list when it's needed.
- init_subtypes(/datum/objective_item/steal,possible_items)
-
-/datum/objective/steal/find_target()
- var/approved_targets = list()
- for(var/datum/objective_item/possible_item in possible_items)
- if(is_unique_objective(possible_item.targetitem) && !(owner.current.mind.assigned_role in possible_item.excludefromjob))
- approved_targets += possible_item
- return set_target(safepick(approved_targets))
-
-/datum/objective/steal/proc/set_target(datum/objective_item/item)
- if(item)
- targetinfo = item
-
- steal_target = targetinfo.targetitem
- explanation_text = "Steal [targetinfo.name]."
- dangerrating = targetinfo.difficulty
- give_special_equipment()
- return steal_target
- else
- explanation_text = "Free objective"
- return
-
-/datum/objective/steal/proc/select_target() //For admins setting objectives manually.
- var/list/possible_items_all = possible_items+"custom"
- var/new_target = input("Select target:", "Objective target", steal_target) as null|anything in possible_items_all
- if (!new_target) return
-
- if (new_target == "custom") //Can set custom items.
- var/obj/item/custom_target = input("Select type:","Type") as null|anything in typesof(/obj/item)
- if (!custom_target) return
- var/tmp_obj = new custom_target
- var/custom_name = tmp_obj:name
- qdel(tmp_obj)
- custom_name = stripped_input("Enter target name:", "Objective target", custom_name)
- if (!custom_name) return
- steal_target = custom_target
- explanation_text = "Steal [custom_name]."
-
- else
- set_target(new_target)
- return steal_target
-
-/datum/objective/steal/check_completion()
- if(!steal_target) return 1
- if(!isliving(owner.current)) return 0
- var/list/all_items = owner.current.GetAllContents() //this should get things in cheesewheels, books, etc.
-
- for(var/obj/I in all_items) //Check for items
- if(istype(I, steal_target))
- if(!targetinfo) //If there's no targetinfo, then that means it was a custom objective. At this point, we know you have the item, so return 1.
- return 1
- else if(targetinfo.check_special_completion(I))//Returns 1 by default. Items with special checks will return 1 if the conditions are fulfilled.
- return 1
-
- if(targetinfo && I.type in targetinfo.altitems) //Ok, so you don't have the item. Do you have an alternative, at least?
- if(targetinfo.check_special_completion(I))//Yeah, we do! Don't return 0 if we don't though - then you could fail if you had 1 item that didn't pass and got checked first!
- return 1
- return 0
-
-/datum/objective/steal/give_special_equipment()
- if(owner && owner.current && targetinfo)
- if(istype(owner.current, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = owner.current
- var/list/slots = list ("backpack" = slot_in_backpack)
- for(var/eq_path in targetinfo.special_equipment)
- var/obj/O = new eq_path
- H.equip_in_one_of_slots(O, slots)
- H.update_icons()
-
-var/global/list/possible_items_special = list()
-/datum/objective/steal/special //ninjas are so special they get their own subtype good for them
-
-/datum/objective/steal/special/New()
- ..()
- if(!possible_items_special.len)
- init_subtypes(/datum/objective_item/special,possible_items)
- init_subtypes(/datum/objective_item/stack,possible_items)
-
-/datum/objective/steal/special/find_target()
- return set_target(pick(possible_items_special))
-
-
-
-/datum/objective/steal/exchange
- dangerrating = 10
- martyr_compatible = 0
-
-/datum/objective/steal/exchange/proc/set_faction(faction,otheragent)
- target = otheragent
- if(faction == "red")
- targetinfo = new/datum/objective_item/unique/docs_blue
- else if(faction == "blue")
- targetinfo = new/datum/objective_item/unique/docs_red
- explanation_text = "Acquire [targetinfo.name] held by [target.current.real_name], the [target.assigned_role] and syndicate agent"
- steal_target = targetinfo.targetitem
-
-
-/datum/objective/steal/exchange/update_explanation_text()
- ..()
- if(target && target.current)
- explanation_text = "Acquire [targetinfo.name] held by [target.name], the [target.assigned_role] and syndicate agent"
- else
- explanation_text = "Free Objective"
-
-
-/datum/objective/steal/exchange/backstab
- dangerrating = 3
-
-/datum/objective/steal/exchange/backstab/set_faction(faction)
- if(faction == "red")
- targetinfo = new/datum/objective_item/unique/docs_red
- else if(faction == "blue")
- targetinfo = new/datum/objective_item/unique/docs_blue
- explanation_text = "Do not give up or lose [targetinfo.name]."
- steal_target = targetinfo.targetitem
-
-
-/datum/objective/download
- dangerrating = 10
-
-/datum/objective/download/proc/gen_amount_goal()
- target_amount = rand(10,20)
- explanation_text = "Download [target_amount] research level\s."
- return target_amount
-
-/datum/objective/download/check_completion()//NINJACODE
- if(!ishuman(owner.current))
- return 0
-
- var/mob/living/carbon/human/H = owner.current
- if(!H || H.stat == DEAD)
- return 0
-
- if(!istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja))
- return 0
-
- var/obj/item/clothing/suit/space/space_ninja/SN = H.wear_suit
- if(!SN.s_initialized)
- return 0
-
- var/current_amount
- if(!SN.stored_research.len)
- return 0
- else
- for(var/datum/tech/current_data in SN.stored_research)
- if(current_data.level)
- current_amount += (current_data.level-1)
- if(current_amount= target_amount))
- return 1
- else
- return 0
-
-
-
-/datum/objective/destroy
- dangerrating = 10
- martyr_compatible = 1
-
-/datum/objective/destroy/find_target()
- var/list/possible_targets = active_ais(1)
- var/mob/living/silicon/ai/target_ai = pick(possible_targets)
- target = target_ai.mind
- update_explanation_text()
- return target
-
-/datum/objective/destroy/check_completion()
- if(target && target.current)
- if(target.current.stat == DEAD || target.current.z > 6 || !target.current.ckey) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite
- return 1
- return 0
- return 1
-
-/datum/objective/destroy/update_explanation_text()
- ..()
- if(target && target.current)
- explanation_text = "Destroy [target.name], the experimental AI."
- else
- explanation_text = "Free Objective"
-
-/datum/objective/summon_guns
- explanation_text = "Steal at least five guns!"
-
-/datum/objective/summon_guns/check_completion()
- if(!isliving(owner.current)) return 0
- var/guncount = 0
- var/list/all_items = owner.current.GetAllContents() //this should get things in cheesewheels, books, etc.
- for(var/obj/I in all_items) //Check for guns
- if(istype(I, /obj/item/weapon/gun))
- guncount++
- if(guncount >= 5)
- return 1
- else
- return 0
- return 0
-
-
-
-////////////////////////////////
-// Changeling team objectives //
-////////////////////////////////
-
-/datum/objective/changeling_team_objective //Abstract type
- martyr_compatible = 0 //Suicide is not teamwork!
- explanation_text = "Changeling Friendship!"
- var/min_lings = 3 //Minimum amount of lings for this team objective to be possible
- var/escape_objective_compatible = FALSE
-
-
-//Impersonate department
-//Picks as many people as it can from a department (Security,Engineer,Medical,Science)
-//and tasks the lings with killing and replacing them
-/datum/objective/changeling_team_objective/impersonate_department
- explanation_text = "Ensure X derpartment are killed, impersonated, and replaced by Changelings"
- var/command_staff_only = FALSE //if this is true, it picks command staff instead
- var/list/department_minds = list()
- var/list/department_real_names = list()
- var/department_string = ""
-
-
-/datum/objective/changeling_team_objective/impersonate_department/proc/get_department_staff()
- department_minds = list()
- department_real_names = list()
-
- var/list/departments = list("Head of Security","Research Director","Chief Engineer","Chief Medical Officer")
- var/department_head = pick(departments)
- switch(department_head)
- if("Head of Security")
- department_string = "security"
- if("Research Director")
- department_string = "science"
- if("Chief Engineer")
- department_string = "engineering"
- if("Chief Medical Officer")
- department_string = "medical"
-
- var/ling_count = ticker.mode.changelings
-
- for(var/datum/mind/M in ticker.minds)
- if(M in ticker.mode.changelings)
- continue
- if(department_head in get_department_heads(M.assigned_role))
- if(ling_count)
- ling_count--
- department_minds += M
- department_real_names += M.current.real_name
- else
- break
-
- if(!department_minds.len)
- log_game("[type] has failed to find department staff, and has removed itself. the round will continue normally")
- owner.objectives -= src
- qdel(src)
- return
-
-
-/datum/objective/changeling_team_objective/impersonate_department/proc/get_heads()
- department_minds = list()
- department_real_names = list()
-
- //Needed heads is between min_lings and the maximum possible amount of command roles
- //So at the time of writing, rand(3,6), it's also capped by the amount of lings there are
- //Because you can't fill 6 head roles with 3 lings
-
- var/needed_heads = rand(min_lings,command_positions.len)
- needed_heads = min(ticker.mode.changelings.len,needed_heads)
-
- var/list/heads = ticker.mode.get_living_heads()
- for(var/datum/mind/head in heads)
- if(head in ticker.mode.changelings) //Looking at you HoP.
- continue
- if(needed_heads)
- department_minds += head
- department_real_names += head.current.real_name
- needed_heads--
- else
- break
-
- if(!department_minds.len)
- log_game("[type] has failed to find department heads, and has removed itself. the round will continue normally")
- owner.objectives -= src
- qdel(src)
- return
-
-
-/datum/objective/changeling_team_objective/impersonate_department/New(var/text)
- ..()
- if(command_staff_only)
- get_heads()
- else
- get_department_staff()
-
- update_explanation_text()
-
-
-/datum/objective/changeling_team_objective/impersonate_department/update_explanation_text()
- ..()
- if(!department_real_names.len || !department_minds.len)
- explanation_text = "Free Objective"
- return //Something fucked up, give them a win
-
- if(command_staff_only)
- explanation_text = "Ensure changelings impersonate and escape as the following heads of staff: "
- else
- explanation_text = "Ensure changelings impersonate and escape as the following members of \the [department_string] department: "
-
- var/first = 1
- for(var/datum/mind/M in department_minds)
- var/string = "[M.name] the [M.assigned_role]"
- if(!first)
- string = ", [M.name] the [M.assigned_role]"
- else
- first--
- explanation_text += string
-
- if(command_staff_only)
- explanation_text += ", while the real heads are dead. This is a team objective."
- else
- explanation_text += ", while the real members are dead. This is a team objective."
-
-
-/datum/objective/changeling_team_objective/impersonate_department/check_completion()
- if(!department_real_names.len || !department_minds.len)
- return 1 //Something fucked up, give them a win
-
- var/list/check_names = department_real_names.Copy()
-
- //Check each department member's mind to see if any of them made it to centcomm alive, if they did it's an automatic fail
- for(var/datum/mind/M in department_minds)
- if(M in ticker.mode.changelings) //Lings aren't picked for this, but let's be safe
- continue
-
- if(M.current)
- var/turf/mloc = get_turf(M.current)
- if(mloc.onCentcom() && (M.current.stat != DEAD))
- return 0 //A Non-ling living target got to centcomm, fail
-
- //Check each staff member has been replaced, by cross referencing changeling minds, changeling current dna, the staff minds and their original DNA names
- var/success = 0
- changelings:
- for(var/datum/mind/changeling in ticker.mode.changelings)
- if(success >= department_minds.len) //We did it, stop here!
- return 1
- if(ishuman(changeling.current))
- var/mob/living/carbon/human/H = changeling.current
- var/turf/cloc = get_turf(changeling.current)
- if(cloc && cloc.onCentcom() && (changeling.current.stat != DEAD)) //Living changeling on centcomm....
- for(var/name in check_names) //Is he (disguised as) one of the staff?
- if(H.dna.real_name == name)
- check_names -= name //This staff member is accounted for, remove them, so the team don't succeed by escape as 7 of the same engineer
- success++ //A living changeling staff member made it to centcomm
- continue changelings
-
- if(success >= department_minds.len)
- return 1
- return 0
-
-
-
-
-//A subtype of impersonate_derpartment
-//This subtype always picks as many command staff as it can (HoS,HoP,Cap,CE,CMO,RD)
-//and tasks the lings with killing and replacing them
-/datum/objective/changeling_team_objective/impersonate_department/impersonate_heads
- explanation_text = "Have X or more heads of staff escape on the shuttle disguised as heads, while the real heads are dead"
- command_staff_only = TRUE
-
-
-
+/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/dangerrating = 0 //How hard the objective is, essentially. Used for dishing out objectives and checking overall victory.
+ var/martyr_compatible = 0 //If the objective is compatible with martyr objective, i.e. if you can still do it while dead.
+ var/required_role = null //If the objective can only be done by a certain role, such as absorb for changelings.
+ var/randomgen = 1 //Whether the objective can be generated randomly.
+ var/error_text = "" //Displayed to admins if the objective fails to initialize properly when editing or adding
+
+/proc/generate_objectives(var/datum/mind/M, var/objectives_made = 2, var/has_escape = TRUE)
+ var/list/objective_types = (typesof(/datum/objective/default) - /datum/objective/default)
+ var/list/escape_objective_types = (typesof(/datum/objective/escape_obj) - /datum/objective/escape_obj)
+ for(var/O in objective_types) // this is fucking hacky as shit but
+ var/datum/objective/obj = new O
+ if(M.special_role != obj.required_role && obj.required_role != null)
+ objective_types -= O
+ if(!obj.randomgen)
+ objective_types -= O
+ for(var/E in escape_objective_types)
+ var/datum/objective/obj = new E
+ if(M.special_role != obj.required_role && obj.required_role != null)
+ objective_types -= E
+ if(!obj.randomgen)
+ objective_types -= E
+ for(var/i = 1, i <= objectives_made, i++)
+ if(i == objectives_made && has_escape)
+ var/datum/objective/holder_obj = pick(escape_objective_types)
+ add_objective(M, holder_obj)
+ return
+ else
+ var/datum/objective/holder_obj = pick(objective_types)
+ objective_types -= holder_obj
+ var/datum/objective/O = new holder_obj
+ if(!O.martyr_compatible)
+ escape_objective_types -= list(/datum/objective/escape_obj/martyr)
+ add_objective(M, holder_obj)
+
+
+/proc/add_objective(var/datum/mind/M, var/obj_path, var/announce_new_objectives = 0, var/replace_if_impossible = 1, var/admin=0)
+ var/datum/objective/objective = new obj_path()
+ objective.owner = M
+ M.objectives += objective
+ if(admin && check_rights(R_ADMIN))
+ objective.find_target_admin()
+ else
+ objective.find_target()
+
+ if(!objective.extra_prep())
+ if(replace_if_impossible)
+ generate_objectives(objective.owner, 1, FALSE) // Generate another objective to replace this one.
+ objective.owner.objectives -= src
+ qdel(src)
+ return null
+
+ objective.update_explanation_text()
+ if(announce_new_objectives)
+ if(M.special_role)
+ M.current << "You are the [M.special_role]."
+ var/obj_count = 1
+ for(var/datum/objective/OBJ in M.objectives)
+ M.current << "Objective #[obj_count]: [OBJ.explanation_text]"
+ obj_count++
+ return objective
+
+/datum/objective/New(var/text)
+ if(text)
+ explanation_text = text
+
+/datum/objective/proc/check_completion()
+ return completed
+
+/datum/objective/proc/extra_prep()
+ return 1
+
+/datum/objective/proc/is_unique_objective(possible_target)
+ for(var/datum/objective/O in owner.objectives)
+ if(istype(O, type) && O.get_target() == possible_target)
+ return 0
+ return 1
+
+/datum/objective/proc/get_target()
+ return target
+
+/datum/objective/proc/find_possible_targets()
+ var/list/possible_targets = list()
+ for(var/datum/mind/possible_target in ticker.minds)
+ if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != 2) && is_unique_objective(possible_target))
+ possible_targets += possible_target
+ return possible_targets
+
+/datum/objective/proc/find_target()
+ var/list/possible_targets = find_possible_targets()
+ if(possible_targets.len > 0)
+ target = pick(possible_targets)
+ update_explanation_text()
+ return target
+
+/datum/objective/proc/find_target_admin()
+ target = input("Select target:", "Objective target") as null|anything in find_possible_targets()
+ return target
+
+/datum/objective/proc/find_target_by_role(role, role_type=0, invert=0)//Option sets either to check assigned role or special role. Default to assigned., invert inverts the check, eg: "Don't choose a Ling"
+ for(var/datum/mind/possible_target in ticker.minds)
+ if((possible_target != owner) && ishuman(possible_target.current))
+ var/is_role = 0
+ if(role_type)
+ if(possible_target.special_role == role)
+ is_role++
+ else
+ if(possible_target.assigned_role == role)
+ is_role++
+
+ if(invert)
+ if(is_role)
+ continue
+ target = possible_target
+ break
+ else if(is_role)
+ target = possible_target
+ break
+
+ update_explanation_text()
+
+/datum/objective/proc/update_explanation_text()
+ //Default does nothing, override where needed
+
+/datum/objective/proc/give_special_equipment()
+
+// Default objectives are ones you can put on any antag type and they should be able to complete it.
+
+/datum/objective/default/assassinate
+ var/target_role_type=0
+ dangerrating = 10
+ martyr_compatible = 1
+
+/datum/objective/default/assassinate/find_target_by_role(role, role_type=0, invert=0)
+ if(!invert)
+ target_role_type = role_type
+ ..()
+ return target
+
+/datum/objective/default/assassinate/check_completion()
+ if(target && target.current)
+ if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current) || target.current.z > 6 || !target.current.ckey) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite
+ return 1
+ return 0
+ return 1
+
+/datum/objective/default/assassinate/update_explanation_text()
+ ..()
+ if(target && target.current)
+ explanation_text = "Assassinate [target.name], the [!target_role_type ? target.assigned_role : target.special_role]."
+ else
+ explanation_text = "Free Objective"
+
+
+/datum/objective/mutiny
+ var/target_role_type=0
+ martyr_compatible = 1
+
+/datum/objective/mutiny/find_target_by_role(role, role_type=0,invert=0)
+ if(!invert)
+ target_role_type = role_type
+ ..()
+ return target
+
+/datum/objective/mutiny/check_completion()
+ if(target && target.current)
+ if(target.current.stat == DEAD || !ishuman(target.current) || !target.current.ckey || !target.current.client)
+ return 1
+ var/turf/T = get_turf(target.current)
+ if(T && (T.z > ZLEVEL_STATION) || target.current.client.is_afk()) //If they leave the station or go afk they count as dead for this
+ return 2
+ return 0
+ return 1
+
+/datum/objective/mutiny/update_explanation_text()
+ ..()
+ if(target && target.current)
+ explanation_text = "Assassinate or exile [target.name], the [!target_role_type ? target.assigned_role : target.special_role]."
+ else
+ explanation_text = "Free Objective"
+
+
+
+/datum/objective/default/maroon
+ var/target_role_type=0
+ dangerrating = 5
+ martyr_compatible = 1
+
+/datum/objective/default/maroon/find_target_by_role(role, role_type=0, invert=0)
+ if(!invert)
+ target_role_type = role_type
+ ..()
+ return target
+
+/datum/objective/default/maroon/check_completion()
+ if(target && target.current)
+ if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current) || target.current.z > 6 || !target.current.ckey) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite
+ return 1
+ if(target.current.onCentcom() || target.current.onSyndieBase())
+ return 0
+ return 1
+
+/datum/objective/default/maroon/update_explanation_text()
+ if(target && target.current)
+ explanation_text = "Prevent [target.name], the [!target_role_type ? target.assigned_role : target.special_role], from escaping alive."
+ else
+ explanation_text = "Free Objective"
+
+
+
+/datum/objective/default/debrain//I want braaaainssss
+ var/target_role_type=0
+ dangerrating = 20
+ randomgen = 0
+
+/datum/objective/default/debrain/find_target_by_role(role, role_type=0, invert=0)
+ if(!invert)
+ target_role_type = role_type
+ ..()
+ return target
+
+/datum/objective/default/debrain/check_completion()
+ if(!target)//If it's a free objective.
+ return 1
+ if( !owner.current || owner.current.stat==DEAD )//If you're otherwise dead.
+ return 0
+ if( !target.current || !isbrain(target.current) )
+ return 0
+ var/atom/A = target.current
+ while(A.loc) //check to see if the brainmob is on our person
+ A = A.loc
+ if(A == owner.current)
+ return 1
+ return 0
+
+/datum/objective/default/debrain/update_explanation_text()
+ ..()
+ if(target && target.current)
+ explanation_text = "Steal the brain of [target.name], the [!target_role_type ? target.assigned_role : target.special_role]."
+ else
+ explanation_text = "Free Objective"
+
+
+
+/datum/objective/default/protect//The opposite of killing a dude.
+ var/target_role_type=0
+ dangerrating = 10
+ martyr_compatible = 1
+
+/datum/objective/default/protect/find_target_by_role(role, role_type=0, invert=0)
+ if(!invert)
+ target_role_type = role_type
+ ..()
+ return target
+
+/datum/objective/default/protect/check_completion()
+ if(!target) //If it's a free objective.
+ return 1
+ if(target.current)
+ if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current))
+ return 0
+ return 1
+ return 0
+
+/datum/objective/default/protect/update_explanation_text()
+ ..()
+ if(target && target.current)
+ explanation_text = "Protect [target.name], the [!target_role_type ? target.assigned_role : target.special_role]."
+ else
+ explanation_text = "Free Objective"
+
+
+
+/datum/objective/escape_obj/hijack
+ explanation_text = "Hijack the shuttle to ensure no loyalist Nanotrasen crew escape alive and out of custody."
+ dangerrating = 25
+ martyr_compatible = 0 //Technically you won't get both anyway.
+
+/datum/objective/escape_obj/hijack/check_completion()
+ if(!owner.current || owner.current.stat)
+ return 0
+ if(SSshuttle.emergency.mode < SHUTTLE_ENDGAME)
+ return 0
+ if(issilicon(owner.current))
+ return 0
+
+ var/area/A = get_area(owner.current)
+ if(SSshuttle.emergency.areaInstance != A)
+ return 0
+
+ for(var/mob/living/player in player_list)
+ if(player.mind && player.mind != owner)
+ if(player.stat != DEAD)
+ if(istype(player, /mob/living/silicon)) //Borgs are technically dead anyways
+ continue
+ if(get_area(player) == A)
+ if(!player.mind.special_role && !istype(get_turf(player.mind.current), /turf/simulated/floor/plasteel/shuttle/red))
+ return 0
+ return 1
+
+/datum/objective/hijackclone
+ explanation_text = "Hijack the emergency shuttle by ensuring only you (or your copies) escape."
+ dangerrating = 25
+ martyr_compatible = 0
+
+/datum/objective/hijackclone/check_completion()
+ if(!owner.current)
+ return 0
+ if(SSshuttle.emergency.mode < SHUTTLE_ENDGAME)
+ return 0
+
+ var/area/A = SSshuttle.emergency.areaInstance
+
+ for(var/mob/living/player in player_list) //Make sure nobody else is onboard
+ if(player.mind && player.mind != owner)
+ if(player.stat != DEAD)
+ if(istype(player, /mob/living/silicon))
+ continue
+ if(get_area(player) == A)
+ if(player.real_name != owner.current.real_name && !istype(get_turf(player.mind.current), /turf/simulated/floor/plasteel/shuttle/red))
+ return 0
+
+ for(var/mob/living/player in player_list) //Make sure at least one of you is onboard
+ if(player.mind && player.mind != owner)
+ if(player.stat != DEAD)
+ if(istype(player, /mob/living/silicon))
+ continue
+ if(get_area(player) == A)
+ if(player.real_name == owner.current.real_name && !istype(get_turf(player.mind.current), /turf/simulated/floor/plasteel/shuttle/red))
+ return 1
+ return 0
+
+/datum/objective/escape_obj/block
+ explanation_text = "Do not allow any organic lifeforms to escape on the shuttle alive."
+ dangerrating = 25
+ martyr_compatible = 1
+ randomgen = 0
+
+/datum/objective/escape_obj/block/check_completion()
+ if(!istype(owner.current, /mob/living/silicon))
+ return 0
+ if(SSshuttle.emergency.mode < SHUTTLE_ENDGAME)
+ return 1
+
+ var/area/A = SSshuttle.emergency.areaInstance
+
+ for(var/mob/living/player in player_list)
+ if(istype(player, /mob/living/silicon))
+ continue
+ if(player.mind)
+ if(player.stat != DEAD)
+ if(get_area(player) == A)
+ return 0
+
+ return 1
+
+
+/datum/objective/escape_obj/escape
+ explanation_text = "Escape on the shuttle or an escape pod alive and without being in custody."
+ dangerrating = 5
+
+/datum/objective/escape_obj/escape/check_completion()
+ if(issilicon(owner.current))
+ return 0
+ if(isbrain(owner.current))
+ return 0
+ if(!owner.current || owner.current.stat == DEAD)
+ return 0
+ if(ticker.force_ending) //This one isn't their fault, so lets just assume good faith
+ return 1
+ if(ticker.mode.station_was_nuked) //If they escaped the blast somehow, let them win
+ return 1
+ if(SSshuttle.emergency.mode < SHUTTLE_ENDGAME)
+ return 0
+ var/turf/location = get_turf(owner.current)
+ if(!location)
+ return 0
+
+ if(istype(location, /turf/simulated/floor/plasteel/shuttle/red)) // Fails traitors if they are in the shuttle brig -- Polymorph
+ return 0
+
+ if(location.onCentcom() || location.onSyndieBase())
+ return 1
+
+ return 0
+
+/datum/objective/escape_obj/escape/escape_with_identity
+ dangerrating = 10
+ var/target_real_name // Has to be stored because the target's real_name can change over the course of the round
+ var/target_missing_id
+ required_role = "changeling"
+
+/datum/objective/escape_obj/escape/escape_with_identity/find_target()
+ target = ..()
+ update_explanation_text()
+
+/datum/objective/escape_obj/escape/escape_with_identity/update_explanation_text()
+ if(target && target.current)
+ target_real_name = target.current.real_name
+ explanation_text = "Escape on the shuttle or an escape pod with the identity of [target_real_name], the [target.assigned_role]"
+ var/mob/living/carbon/human/H
+ if(ishuman(target.current))
+ H = target.current
+ if(H && H.get_id_name() != target_real_name)
+ target_missing_id = 1
+ else
+ explanation_text += " while wearing their identification card"
+ explanation_text += "." //Proper punctuation is important!
+
+ else
+ explanation_text = "Free Objective."
+
+/datum/objective/escape_obj/escape/escape_with_identity/check_completion()
+ if(!target_real_name)
+ return 1
+ if(!ishuman(owner.current))
+ return 0
+ var/mob/living/carbon/human/H = owner.current
+ if(..())
+ if(H.dna.real_name == target_real_name)
+ if(H.get_id_name()== target_real_name || target_missing_id)
+ return 1
+ return 0
+
+
+/datum/objective/escape_obj/survive
+ explanation_text = "Stay alive until the end."
+ dangerrating = 3
+
+/datum/objective/survive/check_completion()
+ if(!owner.current || owner.current.stat == DEAD || isbrain(owner.current))
+ return 0 //Brains no longer win survive objectives. --NEO
+ if(!is_special_character(owner.current)) //This fails borg'd traitors
+ return 0
+ return 1
+
+
+/datum/objective/escape_obj/martyr
+ explanation_text = "Die a glorious death."
+ dangerrating = 1
+
+/datum/objective/escape_obj/martyr/check_completion()
+ if(!owner.current) //Gibbed, etc.
+ return 1
+ if(owner.current && owner.current.stat == DEAD) //You're dead! Yay!
+ return 1
+ return 0
+
+
+/datum/objective/nuclear
+ explanation_text = "Destroy the station with a nuclear device."
+ martyr_compatible = 1
+
+/datum/objective/nuclear/check_completion()
+ if(ticker && ticker.mode && ticker.mode.station_was_nuked)
+ return 1
+ return 0
+
+var/global/list/possible_items = list()
+/datum/objective/default/steal
+ var/datum/objective_item/targetinfo = null //Save the chosen item datum so we can access it later.
+ var/obj/item/steal_target = null //Needed for custom objectives (they're just items, not datums).
+ dangerrating = 5 //Overridden by the individual item's difficulty, but defaults to 5 for custom objectives.
+ martyr_compatible = 0
+
+/datum/objective/default/steal/get_target()
+ return steal_target
+
+/datum/objective/default/steal/New()
+ ..()
+ if(!possible_items.len)//Only need to fill the list when it's needed.
+ init_subtypes(/datum/objective_item/steal,possible_items)
+
+/datum/objective/default/steal/find_possible_targets()
+ var/list/approved_targets = list()
+ if(check_rights(R_ADMIN))
+ approved_targets += select_target()
+ else
+ for(var/datum/objective_item/possible_item in possible_items)
+ if(is_unique_objective(possible_item.targetitem) && !(owner.current.mind.assigned_role in possible_item.excludefromjob))
+ approved_targets += possible_item
+ return approved_targets
+
+/datum/objective/default/steal/find_target()
+ return set_target(safepick(find_possible_targets()))
+
+/datum/objective/default/steal/proc/set_target(datum/objective_item/item)
+ if(item)
+ targetinfo = item
+
+ steal_target = targetinfo.targetitem
+ explanation_text = "Steal [targetinfo.name]."
+ dangerrating = targetinfo.difficulty
+ give_special_equipment()
+ return steal_target
+ else
+ explanation_text = "Free objective"
+ return
+
+/datum/objective/default/steal/proc/select_target() //For admins setting objectives manually.
+ var/list/possible_items_all = possible_items+"custom"
+ var/new_target = input("Select target:", "Objective target", steal_target) as null|anything in possible_items_all
+ if (!new_target)
+ return
+
+ if (new_target == "custom") //Can set custom items.
+ var/obj/item/custom_target = input("Select type:","Type") as null|anything in typesof(/obj/item)
+ if (!custom_target)
+ return
+ var/custom_name = initial(custom_target.name)
+ custom_name = stripped_input("Enter target name:", "Objective target", custom_name)
+ if (!custom_name)
+ return
+ steal_target = custom_target
+ explanation_text = "Steal [custom_name]."
+
+ return steal_target
+
+/datum/objective/default/steal/check_completion()
+ if(!steal_target)
+ return 1
+ if(!isliving(owner.current))
+ return 0
+ var/list/all_items = owner.current.GetAllContents() //this should get things in cheesewheels, books, etc.
+
+ for(var/obj/I in all_items) //Check for items
+ if(istype(I, steal_target))
+ if(!targetinfo) //If there's no targetinfo, then that means it was a custom objective. At this point, we know you have the item, so return 1.
+ return 1
+ else if(targetinfo.check_special_completion(I))//Returns 1 by default. Items with special checks will return 1 if the conditions are fulfilled.
+ return 1
+
+ if(targetinfo && I.type in targetinfo.altitems) //Ok, so you don't have the item. Do you have an alternative, at least?
+ if(targetinfo.check_special_completion(I))//Yeah, we do! Don't return 0 if we don't though - then you could fail if you had 1 item that didn't pass and got checked first!
+ return 1
+ return 0
+
+/datum/objective/default/steal/give_special_equipment()
+ if(owner && owner.current && targetinfo)
+ if(istype(owner.current, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = owner.current
+ var/list/slots = list ("backpack" = slot_in_backpack)
+ for(var/eq_path in targetinfo.special_equipment)
+ var/obj/O = new eq_path
+ H.equip_in_one_of_slots(O, slots)
+ H.update_icons()
+
+var/global/list/possible_items_special = list()
+/datum/objective/default/steal/special //ninjas are so special they get their own subtype good for them
+ randomgen = 0
+/datum/objective/default/steal/special/New()
+ ..()
+ if(!possible_items_special.len)
+ init_subtypes(/datum/objective_item/special,possible_items)
+ init_subtypes(/datum/objective_item/stack,possible_items)
+
+/datum/objective/default/steal/special/find_target()
+ return set_target(pick(possible_items_special))
+
+
+
+/datum/objective/default/steal/exchange
+ dangerrating = 10
+ martyr_compatible = 0
+ randomgen = 0
+
+/datum/objective/default/steal/exchange/proc/set_faction(faction,otheragent)
+ target = otheragent
+ if(faction == "red")
+ targetinfo = new/datum/objective_item/unique/docs_blue
+ else if(faction == "blue")
+ targetinfo = new/datum/objective_item/unique/docs_red
+ explanation_text = "Acquire [targetinfo.name] held by [target.current.real_name], the [target.assigned_role] and syndicate agent"
+ steal_target = targetinfo.targetitem
+
+
+/datum/objective/default/steal/exchange/update_explanation_text()
+ ..()
+ if(target && target.current)
+ explanation_text = "Acquire [targetinfo.name] held by [target.name], the [target.assigned_role] and syndicate agent"
+ else
+ explanation_text = "Free Objective"
+
+
+/datum/objective/default/steal/exchange/backstab
+ dangerrating = 3
+ randomgen = 0
+
+/datum/objective/default/steal/exchange/backstab/set_faction(faction)
+ if(faction == "red")
+ targetinfo = new/datum/objective_item/unique/docs_red
+ else if(faction == "blue")
+ targetinfo = new/datum/objective_item/unique/docs_blue
+ explanation_text = "Do not give up or lose [targetinfo.name]."
+ steal_target = targetinfo.targetitem
+
+
+/datum/objective/download
+ dangerrating = 10
+
+/datum/objective/download/proc/gen_amount_goal()
+ target_amount = rand(10,20)
+ explanation_text = "Download [target_amount] research level\s."
+ return target_amount
+
+/datum/objective/download/check_completion()//NINJACODE
+ if(!ishuman(owner.current))
+ return 0
+
+ var/mob/living/carbon/human/H = owner.current
+ if(!H || H.stat == DEAD)
+ return 0
+
+ if(!istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja))
+ return 0
+
+ var/obj/item/clothing/suit/space/space_ninja/SN = H.wear_suit
+ if(!SN.s_initialized)
+ return 0
+
+ var/current_amount
+ if(!SN.stored_research.len)
+ return 0
+ else
+ for(var/datum/tech/current_data in SN.stored_research)
+ if(current_data.level)
+ current_amount += (current_data.level-1)
+ if(current_amount= target_amount))
+ return 1
+ else
+ return 0
+
+
+
+/datum/objective/default/destroy
+ dangerrating = 10
+ martyr_compatible = 1
+ error_text = "No active AIs with minds."
+
+/datum/objective/default/destroy/find_target()
+ var/list/possible_targets = active_ais(1)
+ var/mob/living/silicon/ai/target_ai = pick(possible_targets)
+ target = target_ai.mind
+ update_explanation_text()
+ return target
+
+/datum/objective/default/destroy/check_completion()
+ if(target && target.current)
+ if(target.current.stat == DEAD || target.current.z > 6 || !target.current.ckey) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite
+ return 1
+ return 0
+ return 1
+
+/datum/objective/default/destroy/update_explanation_text()
+ ..()
+ if(target && target.current)
+ explanation_text = "Destroy [target.name], the experimental AI."
+ else
+ explanation_text = "Free Objective"
+
+/datum/objective/default/destroy/extra_prep()
+ if(!target)
+ return 0
+ return 1
+
+/datum/objective/summon_guns
+ explanation_text = "Steal at least five guns!"
+
+/datum/objective/summon_guns/check_completion()
+ if(!isliving(owner.current)) return 0
+ var/guncount = 0
+ var/list/all_items = owner.current.GetAllContents() //this should get things in cheesewheels, books, etc.
+ for(var/obj/I in all_items) //Check for guns
+ if(istype(I, /obj/item/weapon/gun))
+ guncount++
+ if(guncount >= 5)
+ return 1
+ else
+ return 0
+ return 0
+
+
+
+////////////////////////////////
+// Changeling team objectives //
+////////////////////////////////
+
+/datum/objective/changeling_team_objective //Abstract type
+ martyr_compatible = 0 //Suicide is not teamwork!
+ explanation_text = "Changeling Friendship!"
+ var/min_lings = 3 //Minimum amount of lings for this team objective to be possible
+ var/escape_objective_compatible = FALSE
+
+
+//Impersonate department
+//Picks as many people as it can from a department (Security,Engineer,Medical,Science)
+//and tasks the lings with killing and replacing them
+/datum/objective/changeling_team_objective/impersonate_department
+ explanation_text = "Ensure X derpartment are killed, impersonated, and replaced by Changelings"
+ var/command_staff_only = FALSE //if this is true, it picks command staff instead
+ var/list/department_minds = list()
+ var/list/department_real_names = list()
+ var/department_string = ""
+
+
+/datum/objective/changeling_team_objective/impersonate_department/proc/get_department_staff()
+ department_minds = list()
+ department_real_names = list()
+
+ var/list/departments = list("Head of Security","Research Director","Chief Engineer","Chief Medical Officer")
+ var/department_head = pick(departments)
+ switch(department_head)
+ if("Head of Security")
+ department_string = "security"
+ if("Research Director")
+ department_string = "science"
+ if("Chief Engineer")
+ department_string = "engineering"
+ if("Chief Medical Officer")
+ department_string = "medical"
+
+ var/ling_count = ticker.mode.changelings
+
+ for(var/datum/mind/M in ticker.minds)
+ if(M in ticker.mode.changelings)
+ continue
+ if(department_head in get_department_heads(M.assigned_role))
+ if(ling_count)
+ ling_count--
+ department_minds += M
+ department_real_names += M.current.real_name
+ else
+ break
+
+ if(!department_minds.len)
+ log_game("[type] has failed to find department staff, and has removed itself. the round will continue normally")
+ owner.objectives -= src
+ qdel(src)
+ return
+
+
+/datum/objective/changeling_team_objective/impersonate_department/proc/get_heads()
+ department_minds = list()
+ department_real_names = list()
+
+ //Needed heads is between min_lings and the maximum possible amount of command roles
+ //So at the time of writing, rand(3,6), it's also capped by the amount of lings there are
+ //Because you can't fill 6 head roles with 3 lings
+
+ var/needed_heads = rand(min_lings,command_positions.len)
+ needed_heads = min(ticker.mode.changelings.len,needed_heads)
+
+ var/list/heads = ticker.mode.get_living_heads()
+ for(var/datum/mind/head in heads)
+ if(head in ticker.mode.changelings) //Looking at you HoP.
+ continue
+ if(needed_heads)
+ department_minds += head
+ department_real_names += head.current.real_name
+ needed_heads--
+ else
+ break
+
+ if(!department_minds.len)
+ log_game("[type] has failed to find department heads, and has removed itself. the round will continue normally")
+ owner.objectives -= src
+ qdel(src)
+ return
+
+
+/datum/objective/changeling_team_objective/impersonate_department/New(var/text)
+ ..()
+ if(command_staff_only)
+ get_heads()
+ else
+ get_department_staff()
+
+ update_explanation_text()
+
+
+/datum/objective/changeling_team_objective/impersonate_department/update_explanation_text()
+ ..()
+ if(!department_real_names.len || !department_minds.len)
+ explanation_text = "Free Objective"
+ return //Something fucked up, give them a win
+
+ if(command_staff_only)
+ explanation_text = "Ensure changelings impersonate and escape as the following heads of staff: "
+ else
+ explanation_text = "Ensure changelings impersonate and escape as the following members of \the [department_string] department: "
+
+ var/first = 1
+ for(var/datum/mind/M in department_minds)
+ var/string = "[M.name] the [M.assigned_role]"
+ if(!first)
+ string = ", [M.name] the [M.assigned_role]"
+ else
+ first--
+ explanation_text += string
+
+ if(command_staff_only)
+ explanation_text += ", while the real heads are dead. This is a team objective."
+ else
+ explanation_text += ", while the real members are dead. This is a team objective."
+
+
+/datum/objective/changeling_team_objective/impersonate_department/check_completion()
+ if(!department_real_names.len || !department_minds.len)
+ return 1 //Something fucked up, give them a win
+
+ var/list/check_names = department_real_names.Copy()
+
+ //Check each department member's mind to see if any of them made it to centcomm alive, if they did it's an automatic fail
+ for(var/datum/mind/M in department_minds)
+ if(M in ticker.mode.changelings) //Lings aren't picked for this, but let's be safe
+ continue
+
+ if(M.current)
+ var/turf/mloc = get_turf(M.current)
+ if(mloc.onCentcom() && (M.current.stat != DEAD))
+ return 0 //A Non-ling living target got to centcomm, fail
+
+ //Check each staff member has been replaced, by cross referencing changeling minds, changeling current dna, the staff minds and their original DNA names
+ var/success = 0
+ changelings:
+ for(var/datum/mind/changeling in ticker.mode.changelings)
+ if(success >= department_minds.len) //We did it, stop here!
+ return 1
+ if(ishuman(changeling.current))
+ var/mob/living/carbon/human/H = changeling.current
+ var/turf/cloc = get_turf(changeling.current)
+ if(cloc && cloc.onCentcom() && (changeling.current.stat != DEAD)) //Living changeling on centcomm....
+ for(var/name in check_names) //Is he (disguised as) one of the staff?
+ if(H.dna.real_name == name)
+ check_names -= name //This staff member is accounted for, remove them, so the team don't succeed by escape as 7 of the same engineer
+ success++ //A living changeling staff member made it to centcomm
+ continue changelings
+
+ if(success >= department_minds.len)
+ return 1
+ return 0
+
+
+
+
+//A subtype of impersonate_derpartment
+//This subtype always picks as many command staff as it can (HoS,HoP,Cap,CE,CMO,RD)
+//and tasks the lings with killing and replacing them
+/datum/objective/changeling_team_objective/impersonate_department/impersonate_heads
+ explanation_text = "Have X or more heads of staff escape on the shuttle disguised as heads, while the real heads are dead"
+ command_staff_only = TRUE
+
+/datum/objective/custom
+ explanation_text = "Free Objective"
\ No newline at end of file
diff --git a/code/game/gamemodes/traitor/double_agents.dm b/code/game/gamemodes/traitor/double_agents.dm
index af284603f6a..76bcc67c856 100644
--- a/code/game/gamemodes/traitor/double_agents.dm
+++ b/code/game/gamemodes/traitor/double_agents.dm
@@ -32,27 +32,19 @@
// Assassinate
var/datum/mind/target_mind = target_list[traitor]
if(issilicon(target_mind.current))
- var/datum/objective/destroy/destroy_objective = new
- destroy_objective.owner = traitor
+ var/datum/objective/default/destroy/destroy_objective = add_objective(traitor, /datum/objective/default/destroy)
destroy_objective.target = target_mind
destroy_objective.update_explanation_text()
- traitor.objectives += destroy_objective
else
- var/datum/objective/assassinate/kill_objective = new
- kill_objective.owner = traitor
+ var/datum/objective/default/assassinate/kill_objective = add_objective(traitor, /datum/objective/default/assassinate)
kill_objective.target = target_mind
kill_objective.update_explanation_text()
- traitor.objectives += kill_objective
// Escape
if(issilicon(traitor.current))
- var/datum/objective/survive/survive_objective = new
- survive_objective.owner = traitor
- traitor.objectives += survive_objective
+ add_objective(traitor, /datum/objective/escape_obj/survive)
else
- var/datum/objective/escape/escape_objective = new
- escape_objective.owner = traitor
- traitor.objectives += escape_objective
+ add_objective(traitor, /datum/objective/escape_obj/escape)
else
..() // Give them standard objectives.
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index 8e1466ef7f8..1efb4626f09 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -89,25 +89,14 @@
var/objective_count = 0
if(prob(10))
- var/datum/objective/block/block_objective = new
- block_objective.owner = traitor
- traitor.objectives += block_objective
- objective_count++
+ add_objective(traitor, /datum/objective/escape_obj/block)
for(var/i = objective_count, i < config.traitor_objectives_amount, i++)
- var/datum/objective/assassinate/kill_objective = new
- kill_objective.owner = traitor
- kill_objective.find_target()
- traitor.objectives += kill_objective
-
- var/datum/objective/survive/survive_objective = new
- survive_objective.owner = traitor
- traitor.objectives += survive_objective
+ add_objective(traitor, /datum/objective/default/assassinate)
+ add_objective(traitor, /datum/objective/escape_obj/survive)
else
- var/is_hijacker = prob(10)
- var/martyr_chance = prob(20)
- var/objective_count = is_hijacker //Hijacking counts towards number of objectives
+ var/objective_count = 0
if(!exchange_blue && traitors.len >= 8) //Set up an exchange if there are enough traitors
if(!exchange_red)
exchange_red = traitor
@@ -116,56 +105,7 @@
assign_exchange_role(exchange_red)
assign_exchange_role(exchange_blue)
objective_count += 1 //Exchange counts towards number of objectives
- var/list/active_ais = active_ais()
- for(var/i = objective_count, i < config.traitor_objectives_amount, i++)
- if(prob(50))
- if(active_ais.len && prob(100/joined_player_list.len))
- var/datum/objective/destroy/destroy_objective = new
- destroy_objective.owner = traitor
- destroy_objective.find_target()
- traitor.objectives += destroy_objective
- else if(prob(30))
- var/datum/objective/maroon/maroon_objective = new
- maroon_objective.owner = traitor
- maroon_objective.find_target()
- traitor.objectives += maroon_objective
- else
- var/datum/objective/assassinate/kill_objective = new
- kill_objective.owner = traitor
- kill_objective.find_target()
- traitor.objectives += kill_objective
- else
- var/datum/objective/steal/steal_objective = new
- steal_objective.owner = traitor
- steal_objective.find_target()
- traitor.objectives += steal_objective
-
- if(is_hijacker && objective_count <= config.traitor_objectives_amount) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount
- if (!(locate(/datum/objective/hijack) in traitor.objectives))
- var/datum/objective/hijack/hijack_objective = new
- hijack_objective.owner = traitor
- traitor.objectives += hijack_objective
- return
-
-
- var/martyr_compatibility = 1 //You can't succeed in stealing if you're dead.
- for(var/datum/objective/O in traitor.objectives)
- if(!O.martyr_compatible)
- martyr_compatibility = 0
- break
-
- if(martyr_compatibility && martyr_chance)
- var/datum/objective/martyr/martyr_objective = new
- martyr_objective.owner = traitor
- traitor.objectives += martyr_objective
- return
-
- else
- if(!(locate(/datum/objective/escape) in traitor.objectives))
- var/datum/objective/escape/escape_objective = new
- escape_objective.owner = traitor
- traitor.objectives += escape_objective
- return
+ generate_objectives(traitor, config.traitor_objectives_amount - objective_count, TRUE)
@@ -333,13 +273,13 @@
faction = "blue"
//Assign objectives
- var/datum/objective/steal/exchange/exchange_objective = new
+ var/datum/objective/default/steal/exchange/exchange_objective = new
exchange_objective.set_faction(faction,((faction == "red") ? exchange_blue : exchange_red))
exchange_objective.owner = owner
owner.objectives += exchange_objective
if(prob(20))
- var/datum/objective/steal/exchange/backstab/backstab_objective = new
+ var/datum/objective/default/steal/exchange/backstab/backstab_objective = new
backstab_objective.set_faction(faction)
backstab_objective.owner = owner
owner.objectives += backstab_objective
diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm
index a13d5652b74..70308435cd9 100644
--- a/code/game/gamemodes/wizard/artefact.dm
+++ b/code/game/gamemodes/wizard/artefact.dm
@@ -254,7 +254,7 @@ var/global/list/multiverse = list()
evil = TRUE
else
user << "With your new found power you could easily defend the station!"
- var/datum/objective/survive/new_objective = new /datum/objective/survive
+ var/datum/objective/escape_obj/survive/new_objective = new /datum/objective/escape_obj/survive
new_objective.owner = usr.mind
new_objective.explanation_text = "Survive, and help defend the innocent from the mobs of multiverse clones."
usr << "Objective #[1]: [new_objective.explanation_text]"
@@ -295,15 +295,15 @@ var/global/list/multiverse = list()
equip_copy(M)
if(evil)
- var/datum/objective/hijackclone/hijack_objective = new /datum/objective/hijackclone
- hijack_objective.owner = M.mind
- M.mind.objectives += hijack_objective
- hijack_objective.explanation_text = "Ensure only [usr.real_name] and their copies are on the shuttle!"
- M << "Objective #[1]: [hijack_objective.explanation_text]"
+ var/datum/objective/hijackclone/new_objective = add_objective(M.mind, /datum/objective/hijackclone)
+ new_objective.owner = M.mind
+ M.mind.objectives += new_objective
+ new_objective.explanation_text = "Ensure only [usr.real_name] and their copies are on the shuttle!"
+ M << "Objective #[1]: [new_objective.explanation_text]"
M.mind.special_role = "multiverse traveller"
log_game("[M.key] was made a multiverse traveller with the objective to help [usr.real_name] hijack.")
else
- var/datum/objective/protect/new_objective = new /datum/objective/protect
+ var/datum/objective/default/protect/new_objective = add_objective(M.mind, /datum/objective/default/protect)
new_objective.owner = M.mind
new_objective.target = usr.mind
new_objective.explanation_text = "Protect [usr.real_name], your copy, and help them defend the innocent from the mobs of multiverse clones."
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index 1dac752b967..e8aa52cf4a4 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -48,51 +48,7 @@
/datum/game_mode/proc/forge_wizard_objectives(datum/mind/wizard)
- switch(rand(1,100))
- if(1 to 30)
-
- var/datum/objective/assassinate/kill_objective = new
- kill_objective.owner = wizard
- kill_objective.find_target()
- wizard.objectives += kill_objective
-
- if (!(locate(/datum/objective/escape) in wizard.objectives))
- var/datum/objective/escape/escape_objective = new
- escape_objective.owner = wizard
- wizard.objectives += escape_objective
- if(31 to 60)
- var/datum/objective/steal/steal_objective = new
- steal_objective.owner = wizard
- steal_objective.find_target()
- wizard.objectives += steal_objective
-
- if (!(locate(/datum/objective/escape) in wizard.objectives))
- var/datum/objective/escape/escape_objective = new
- escape_objective.owner = wizard
- wizard.objectives += escape_objective
-
- if(61 to 85)
- var/datum/objective/assassinate/kill_objective = new
- kill_objective.owner = wizard
- kill_objective.find_target()
- wizard.objectives += kill_objective
-
- var/datum/objective/steal/steal_objective = new
- steal_objective.owner = wizard
- steal_objective.find_target()
- wizard.objectives += steal_objective
-
- if (!(locate(/datum/objective/survive) in wizard.objectives))
- var/datum/objective/survive/survive_objective = new
- survive_objective.owner = wizard
- wizard.objectives += survive_objective
-
- else
- if (!(locate(/datum/objective/hijack) in wizard.objectives))
- var/datum/objective/hijack/hijack_objective = new
- hijack_objective.owner = wizard
- wizard.objectives += hijack_objective
- return
+ generate_objectives(wizard, 2)
/datum/game_mode/proc/name_wizard(mob/living/carbon/human/wizard_mob)
diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm
index d8fce89f1ea..a97f4cc6bc0 100644
--- a/code/game/machinery/syndicatebeacon.dm
+++ b/code/game/machinery/syndicatebeacon.dm
@@ -80,18 +80,11 @@
custom_objective.owner = N.mind
N.mind.objectives += custom_objective
- var/datum/objective/escape/escape_objective = new
- escape_objective.owner = N.mind
- N.mind.objectives += escape_objective
+ add_objective(N.mind, /datum/objective/escape_obj/escape, 1)
M << "You have joined the ranks of the Syndicate and become a traitor to the station!"
- var/obj_count = 1
- for(var/datum/objective/OBJ in M.mind.objectives)
- M << "Objective #[obj_count]: [OBJ.explanation_text]"
- obj_count++
-
src.updateUsrDialog()
return
diff --git a/code/game/machinery/wishgranter.dm b/code/game/machinery/wishgranter.dm
index ef9962cf0b4..4748c08ad48 100644
--- a/code/game/machinery/wishgranter.dm
+++ b/code/game/machinery/wishgranter.dm
@@ -45,14 +45,7 @@
ticker.mode.traitors += user.mind
user.mind.special_role = "Avatar of the Wish Granter"
- var/datum/objective/hijack/hijack = new
- hijack.owner = user.mind
- user.mind.objectives += hijack
-
- var/obj_count = 1
- for(var/datum/objective/OBJ in user.mind.objectives)
- user << "Objective #[obj_count]: [OBJ.explanation_text]"
- obj_count++
+ add_objective(user.mind, /datum/objective/escape_obj/hijack, 1)
user << "You have a very bad feeling about this."
diff --git a/code/modules/admin/verbs/onlyone.dm b/code/modules/admin/verbs/onlyone.dm
index d856e5b8577..88cd7f16394 100644
--- a/code/modules/admin/verbs/onlyone.dm
+++ b/code/modules/admin/verbs/onlyone.dm
@@ -10,20 +10,8 @@
ticker.mode.traitors += H.mind
H.mind.special_role = "traitor"
- var/datum/objective/steal/steal_objective = new
- steal_objective.owner = H.mind
- steal_objective.set_target(new /datum/objective_item/steal/nukedisc)
- H.mind.objectives += steal_objective
-
- var/datum/objective/hijack/hijack_objective = new
- hijack_objective.owner = H.mind
- H.mind.objectives += hijack_objective
-
- H << "You are the traitor."
- var/obj_count = 1
- for(var/datum/objective/OBJ in H.mind.objectives)
- H << "Objective #[obj_count]: [OBJ.explanation_text]"
- obj_count++
+ add_objective(H.mind, /datum/objective/default/steal)
+ add_objective(H.mind, /datum/objective/escape_obj/hijack, 1)
for (var/obj/item/I in H)
if (istype(I, /obj/item/weapon/implant))
diff --git a/code/modules/awaymissions/mission_code/wildwest.dm b/code/modules/awaymissions/mission_code/wildwest.dm
index 6b87a8c3beb..dc2cdd22470 100644
--- a/code/modules/awaymissions/mission_code/wildwest.dm
+++ b/code/modules/awaymissions/mission_code/wildwest.dm
@@ -96,14 +96,8 @@
user << "The Wish Granter punishes you for your wickedness, claiming your soul and warping your body to match the darkness in your heart."
ticker.mode.traitors += user.mind
user.mind.special_role = "traitor"
- var/datum/objective/hijack/hijack = new
- hijack.owner = user.mind
- user.mind.objectives += hijack
+ add_objective(user.mind, /datum/objective/escape_obj/hijack, 1)
user << "Your inhibitions are swept away, the bonds of loyalty broken, you are free to murder as you please!"
- var/obj_count = 1
- for(var/datum/objective/OBJ in user.mind.objectives)
- user << "Objective #[obj_count]: [OBJ.explanation_text]"
- obj_count++
user.set_species(/datum/species/shadow)
if("Peace")
user << "Whatever alien sentience that the Wish Granter possesses is satisfied with your wish. There is a distant wailing as the last of the Faithless begin to die, then silence."
diff --git a/code/modules/events/wizard/imposter.dm b/code/modules/events/wizard/imposter.dm
index ec6f4fa06c5..c260a51251c 100644
--- a/code/modules/events/wizard/imposter.dm
+++ b/code/modules/events/wizard/imposter.dm
@@ -38,11 +38,9 @@
ticker.mode.apprentices += I.mind
I.mind.special_role = "imposter"
- var/datum/objective/protect/protect_objective = new /datum/objective/protect
- protect_objective.owner = I.mind
+ var/datum/objective/protect_objective = add_objective(I.mind, /datum/objective/default/protect)
protect_objective.target = W.mind
protect_objective.explanation_text = "Protect [W.real_name], the wizard."
- I.mind.objectives += protect_objective
ticker.mode.update_wiz_icons_added(I.mind)
I.attack_log += "\[[time_stamp()]\] Is an imposter!"
diff --git a/code/modules/ninja/ninja_event.dm b/code/modules/ninja/ninja_event.dm
index fda579af7ef..e4b60e7d420 100644
--- a/code/modules/ninja/ninja_event.dm
+++ b/code/modules/ninja/ninja_event.dm
@@ -76,64 +76,37 @@ Contents:
else if(M.assigned_role in command_positions)
possible_targets[M] = 1 //good-guy
+/*
+ Alright, so, if I had my way I'd axe all this retarded bullshit entirely, but I know some people would complain because
+ porting ninja specifics to the random gen system would go horribly. I can at the very least axe 99% of the autism
+ and make ninja code slightly more bearable.
+ - Iamgoofball
+*/
var/list/objectives = list(1,2,3,4)
- while(Mind.objectives.len < 6) //still not enough objectives!
- switch(pick_n_take(objectives))
+ while(Mind.objectives.len < 6) //still not enough objectives! // WHY DOES THIS CALL FOR 6 OBJECTIVES
+ switch(pick_n_take(objectives)) // BUT THEN PREVENT YOU FROM GETTING 4 IN THE END
if(1) //research
- var/datum/objective/download/O = new /datum/objective/download()
- O.owner = Mind
- O.gen_amount_goal()
- Mind.objectives += O
+ add_objective(Mind, /datum/objective/download)
if(2) //steal
- var/datum/objective/steal/special/O = new /datum/objective/steal/special()
- O.owner = Mind
- Mind.objectives += O
+ add_objective(Mind, /datum/objective/default/steal/special)
if(3) //protect/kill
- if(!possible_targets.len) continue
- var/selected = rand(1,possible_targets.len)
- var/datum/mind/M = possible_targets[selected]
- var/is_bad_guy = possible_targets[M]
- possible_targets.Cut(selected,selected+1)
-
- if(is_bad_guy ^ helping_station) //kill (good-ninja + bad-guy or bad-ninja + good-guy)
- var/datum/objective/assassinate/O = new /datum/objective/assassinate()
- O.owner = Mind
- O.target = M
- O.explanation_text = "Slay \the [M.current.real_name], the [M.assigned_role]."
- Mind.objectives += O
- else //protect
- var/datum/objective/protect/O = new /datum/objective/protect()
- O.owner = Mind
- O.target = M
- O.explanation_text = "Protect \the [M.current.real_name], the [M.assigned_role], from harm."
- Mind.objectives += O
+ if(prob(50))
+ add_objective(Mind, /datum/objective/default/assassinate)
+ else
+ add_objective(Mind, /datum/objective/default/protect)
if(4) //debrain/capture
- if(!possible_targets.len) continue
- var/selected = rand(1,possible_targets.len)
- var/datum/mind/M = possible_targets[selected]
- var/is_bad_guy = possible_targets[M]
- possible_targets.Cut(selected,selected+1)
-
- if(is_bad_guy ^ helping_station) //debrain (good-ninja + bad-guy or bad-ninja + good-guy)
- var/datum/objective/debrain/O = new /datum/objective/debrain()
- O.owner = Mind
- O.target = M
- O.explanation_text = "Steal the brain of [M.current.real_name]."
- Mind.objectives += O
- else //capture
- var/datum/objective/capture/O = new /datum/objective/capture()
- O.owner = Mind
- O.gen_amount_goal()
- Mind.objectives += O
+ if(prob(50))
+ add_objective(Mind, /datum/objective/default/debrain)
+ else
+ add_objective(Mind, /datum/objective/capture)
else
break
//Add a survival objective since it's usually broad enough for any round type.
- var/datum/objective/O = new /datum/objective/survive()
- O.owner = Mind
- Mind.objectives += O
+ add_objective(Mind, /datum/objective/escape_obj/survive)
+
//add some RP-fluff
Mind.store_memory("I am an elite mercenary assassin of the mighty Spider Clan. A SPACE NINJA!")