diff --git a/baystation12.dme b/baystation12.dme
index 17063261ab..ab7fdbfa48 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -223,7 +223,6 @@
#include "code\defines\procs\dbcore.dm"
#include "code\defines\procs\hud.dm"
#include "code\defines\procs\radio.dm"
-#include "code\defines\procs\records.dm"
#include "code\defines\procs\sd_Alert.dm"
#include "code\defines\procs\statistics.dm"
#include "code\game\asteroid.dm"
@@ -642,6 +641,7 @@
#include "code\game\objects\items\weapons\autopsy.dm"
#include "code\game\objects\items\weapons\candle.dm"
#include "code\game\objects\items\weapons\cards_ids.dm"
+#include "code\game\objects\items\weapons\cards_ids_syndicate.dm"
#include "code\game\objects\items\weapons\cigs_lighters.dm"
#include "code\game\objects\items\weapons\clown_items.dm"
#include "code\game\objects\items\weapons\cosmetics.dm"
@@ -697,6 +697,7 @@
#include "code\game\objects\items\weapons\circuitboards\machinery\shieldgen.dm"
#include "code\game\objects\items\weapons\circuitboards\machinery\telecomms.dm"
#include "code\game\objects\items\weapons\circuitboards\machinery\unary_atmos.dm"
+#include "code\game\objects\items\weapons\grenades\anti_photon_grenade.dm"
#include "code\game\objects\items\weapons\grenades\chem_grenade.dm"
#include "code\game\objects\items\weapons\grenades\emgrenade.dm"
#include "code\game\objects\items\weapons\grenades\flashbang.dm"
diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm
index 7468db758b..cabf7c04b3 100644
--- a/code/_helpers/icons.dm
+++ b/code/_helpers/icons.dm
@@ -635,7 +635,7 @@ The _flatIcons list is a cache for generated icon files.
*/
proc // Creates a single icon from a given /atom or /image. Only the first argument is required.
- getFlatIcon(image/A, defdir=2, deficon=null, defstate="", defblend=BLEND_DEFAULT)
+ getFlatIcon(image/A, defdir=2, deficon=null, defstate="", defblend=BLEND_DEFAULT, always_use_defdir = 0)
// We start with a blank canvas, otherwise some icon procs crash silently
var/icon/flat = icon('icons/effects/effects.dmi', "icon_state"="nothing") // Final flattened icon
if(!A)
@@ -666,7 +666,7 @@ proc // Creates a single icon from a given /atom or /image. Only the first argu
noIcon = TRUE // Do not render this object.
var/curdir
- if(A.dir != 2)
+ if(A.dir != 2 && !always_use_defdir)
curdir = A.dir
else
curdir = defdir
diff --git a/code/_helpers/lists.dm b/code/_helpers/lists.dm
index fb4cd3874e..c3a99bcf82 100644
--- a/code/_helpers/lists.dm
+++ b/code/_helpers/lists.dm
@@ -604,10 +604,13 @@ datum/proc/dd_SortValue()
/datum/alarm/dd_SortValue()
return "[sanitize_old(last_name)]"
+/proc/subtypes(prototype)
+ return (typesof(prototype) - prototype)
+
//creates every subtype of prototype (excluding prototype) and adds it to list L.
//if no list/L is provided, one is created.
/proc/init_subtypes(prototype, list/L)
if(!istype(L)) L = list()
- for(var/path in (typesof(prototype) - prototype))
+ for(var/path in subtypes(prototype))
L += new path()
return L
diff --git a/code/_helpers/text.dm b/code/_helpers/text.dm
index 60b25c8ee8..5aa80299c7 100644
--- a/code/_helpers/text.dm
+++ b/code/_helpers/text.dm
@@ -116,7 +116,7 @@
if(last_char_group == 1)
output = copytext(output,1,length(output)) //removes the last character (in this case a space)
- for(var/bad_name in list("space","floor","wall","r-wall","monkey","unknown","inactive ai")) //prevents these common metagamey names
+ for(var/bad_name in list("space","floor","wall","r-wall","monkey","unknown","inactive ai","plating")) //prevents these common metagamey names
if(cmptext(output,bad_name)) return //(not case sensitive)
return output
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index 84a64d8ade..ab79808cf3 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -1,16 +1,136 @@
/hook/startup/proc/createDatacore()
- data_core = new /obj/effect/datacore()
+ data_core = new /datum/datacore()
return 1
-/obj/effect/datacore/proc/manifest()
+/datum/datacore
+ var/name = "datacore"
+ var/medical[] = list()
+ var/general[] = list()
+ var/security[] = list()
+ //This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character().
+ var/locked[] = list()
+
+
+/datum/datacore/proc/get_manifest(monochrome, OOC)
+ var/list/heads = new()
+ var/list/sec = new()
+ var/list/eng = new()
+ var/list/med = new()
+ var/list/sci = new()
+ var/list/civ = new()
+ var/list/bot = new()
+ var/list/misc = new()
+ var/list/isactive = new()
+ var/dat = {"
+
+
+ | Name | Rank | Activity |
+ "}
+ var/even = 0
+ // sort mobs
+ for(var/datum/data/record/t in data_core.general)
+ var/name = t.fields["name"]
+ var/rank = t.fields["rank"]
+ var/real_rank = make_list_rank(t.fields["real_rank"])
+
+ if(OOC)
+ var/active = 0
+ for(var/mob/M in player_list)
+ if(M.real_name == name && M.client && M.client.inactivity <= 10 * 60 * 10)
+ active = 1
+ break
+ isactive[name] = active ? "Active" : "Inactive"
+ else
+ isactive[name] = t.fields["p_stat"]
+ //world << "[name]: [rank]"
+ //cael - to prevent multiple appearances of a player/job combination, add a continue after each line
+ var/department = 0
+ if(real_rank in command_positions)
+ heads[name] = rank
+ department = 1
+ if(real_rank in security_positions)
+ sec[name] = rank
+ department = 1
+ if(real_rank in engineering_positions)
+ eng[name] = rank
+ department = 1
+ if(real_rank in medical_positions)
+ med[name] = rank
+ department = 1
+ if(real_rank in science_positions)
+ sci[name] = rank
+ department = 1
+ if(real_rank in civilian_positions)
+ civ[name] = rank
+ department = 1
+ if(real_rank in nonhuman_positions)
+ bot[name] = rank
+ department = 1
+ if(!department && !(name in heads))
+ misc[name] = rank
+ if(heads.len > 0)
+ dat += "| Heads |
"
+ for(name in heads)
+ dat += "| [name] | [heads[name]] | [isactive[name]] |
"
+ even = !even
+ if(sec.len > 0)
+ dat += "| Security |
"
+ for(name in sec)
+ dat += "| [name] | [sec[name]] | [isactive[name]] |
"
+ even = !even
+ if(eng.len > 0)
+ dat += "| Engineering |
"
+ for(name in eng)
+ dat += "| [name] | [eng[name]] | [isactive[name]] |
"
+ even = !even
+ if(med.len > 0)
+ dat += "| Medical |
"
+ for(name in med)
+ dat += "| [name] | [med[name]] | [isactive[name]] |
"
+ even = !even
+ if(sci.len > 0)
+ dat += "| Science |
"
+ for(name in sci)
+ dat += "| [name] | [sci[name]] | [isactive[name]] |
"
+ even = !even
+ if(civ.len > 0)
+ dat += "| Civilian |
"
+ for(name in civ)
+ dat += "| [name] | [civ[name]] | [isactive[name]] |
"
+ even = !even
+ // in case somebody is insane and added them to the manifest, why not
+ if(bot.len > 0)
+ dat += "| Silicon |
"
+ for(name in bot)
+ dat += "| [name] | [bot[name]] | [isactive[name]] |
"
+ even = !even
+ // misc guys
+ if(misc.len > 0)
+ dat += "| Miscellaneous |
"
+ for(name in misc)
+ dat += "| [name] | [misc[name]] | [isactive[name]] |
"
+ even = !even
+
+ dat += "
"
+ dat = replacetext(dat, "\n", "") // so it can be placed on paper correctly
+ dat = replacetext(dat, "\t", "")
+ return dat
+
+/datum/datacore/proc/manifest()
spawn()
for(var/mob/living/carbon/human/H in player_list)
manifest_inject(H)
return
-/obj/effect/datacore/proc/manifest_modify(var/name, var/assignment)
- if(PDA_Manifest.len)
- PDA_Manifest.Cut()
+/datum/datacore/proc/manifest_modify(var/name, var/assignment)
+ ResetPDAManifest()
var/datum/data/record/foundrecord
var/real_title = assignment
@@ -33,27 +153,13 @@
foundrecord.fields["rank"] = assignment
foundrecord.fields["real_rank"] = real_title
-/obj/effect/datacore/proc/manifest_inject(var/mob/living/carbon/human/H)
- if(PDA_Manifest.len)
- PDA_Manifest.Cut()
-
+/datum/datacore/proc/manifest_inject(var/mob/living/carbon/human/H)
if(H.mind && !player_is_antag(H.mind, only_offstation_roles = 1))
- var/assignment
- if(H.mind.role_alt_title)
- assignment = H.mind.role_alt_title
- else if(H.mind.assigned_role)
- assignment = H.mind.assigned_role
- else if(H.job)
- assignment = H.job
- else
- assignment = "Unassigned"
+ var/assignment = GetAssignment(H)
var/id = add_zero(num2hex(rand(1, 1.6777215E7)), 6) //this was the best they could come up with? A large random number? *sigh*
- var/icon/front = new(get_id_photo(H), dir = SOUTH)
- var/icon/side = new(get_id_photo(H), dir = WEST)
//General Record
- var/datum/data/record/G = new()
- G.fields["id"] = id
+ var/datum/data/record/G = CreateGeneralRecord(H, id)
G.fields["name"] = H.real_name
G.fields["real_rank"] = H.mind.assigned_role
G.fields["rank"] = assignment
@@ -67,49 +173,20 @@
G.fields["citizenship"] = H.citizenship
G.fields["faction"] = H.personal_faction
G.fields["religion"] = H.religion
- G.fields["photo_front"] = front
- G.fields["photo_side"] = side
if(H.gen_record && !jobban_isbanned(H, "Records"))
G.fields["notes"] = H.gen_record
- else
- G.fields["notes"] = "No notes found."
- general += G
//Medical Record
- var/datum/data/record/M = new()
- M.fields["id"] = id
- M.fields["name"] = H.real_name
+ var/datum/data/record/M = CreateMedicalRecord(H.real_name, id)
M.fields["b_type"] = H.b_type
M.fields["b_dna"] = H.dna.unique_enzymes
- M.fields["mi_dis"] = "None"
- M.fields["mi_dis_d"] = "No minor disabilities have been declared."
- M.fields["ma_dis"] = "None"
- M.fields["ma_dis_d"] = "No major disabilities have been diagnosed."
- M.fields["alg"] = "None"
- M.fields["alg_d"] = "No allergies have been detected in this patient."
- M.fields["cdi"] = "None"
- M.fields["cdi_d"] = "No diseases have been diagnosed at the moment."
if(H.med_record && !jobban_isbanned(H, "Records"))
M.fields["notes"] = H.med_record
- else
- M.fields["notes"] = "No notes found."
- medical += M
//Security Record
- var/datum/data/record/S = new()
- S.fields["id"] = id
- S.fields["name"] = H.real_name
- S.fields["criminal"] = "None"
- S.fields["mi_crim"] = "None"
- S.fields["mi_crim_d"] = "No minor crime convictions."
- S.fields["ma_crim"] = "None"
- S.fields["ma_crim_d"] = "No major crime convictions."
- S.fields["notes"] = "No notes."
+ var/datum/data/record/S = CreateSecurityRecord(H.real_name, id)
if(H.sec_record && !jobban_isbanned(H, "Records"))
S.fields["notes"] = H.sec_record
- else
- S.fields["notes"] = "No notes."
- security += S
//Locked Record
var/datum/data/record/L = new()
@@ -136,8 +213,7 @@
locked += L
return
-
-proc/get_id_photo(var/mob/living/carbon/human/H)
+proc/get_id_photo(var/mob/living/carbon/human/H, var/assigned_role)
var/icon/preview_icon = null
var/g = "m"
@@ -191,7 +267,8 @@ proc/get_id_photo(var/mob/living/carbon/human/H)
eyes_s.Blend(facial_s, ICON_OVERLAY)
var/icon/clothes_s = null
- switch(H.mind.assigned_role)
+ if(!assigned_role) assigned_role = H.mind.assigned_role
+ switch(assigned_role)
if("Head of Personnel")
clothes_s = new /icon('icons/mob/uniform.dmi', "hop_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY)
@@ -295,3 +372,106 @@ proc/get_id_photo(var/mob/living/carbon/human/H)
qdel(clothes_s)
return preview_icon
+
+/datum/datacore/proc/CreateGeneralRecord(var/mob/living/carbon/human/H, var/id)
+ ResetPDAManifest()
+ var/icon/front
+ var/icon/side
+ if(H)
+ front = getFlatIcon(H, SOUTH, always_use_defdir = 1)
+ side = getFlatIcon(H, WEST, always_use_defdir = 1)
+ else
+ var/mob/living/carbon/human/dummy = new()
+ front = new(get_id_photo(dummy), dir = SOUTH)
+ side = new(get_id_photo(dummy), dir = WEST)
+ qdel(dummy)
+
+ if(!id) id = text("[]", add_zero(num2hex(rand(1, 1.6777215E7)), 6))
+ var/datum/data/record/G = new /datum/data/record()
+ G.name = "Employee Record #[id]"
+ G.fields["name"] = "New Record"
+ G.fields["id"] = id
+ G.fields["rank"] = "Unassigned"
+ G.fields["real_rank"] = "Unassigned"
+ G.fields["sex"] = "Male"
+ G.fields["age"] = "Unknown"
+ G.fields["fingerprint"] = "Unknown"
+ G.fields["p_stat"] = "Active"
+ G.fields["m_stat"] = "Stable"
+ G.fields["species"] = "Human"
+ G.fields["home_system"] = "Unknown"
+ G.fields["citizenship"] = "Unknown"
+ G.fields["faction"] = "Unknown"
+ G.fields["religion"] = "Unknown"
+ G.fields["photo_front"] = front
+ G.fields["photo_side"] = side
+ G.fields["notes"] = "No notes found."
+ general += G
+
+ return G
+
+/datum/datacore/proc/CreateSecurityRecord(var/name, var/id)
+ ResetPDAManifest()
+ var/datum/data/record/R = new /datum/data/record()
+ R.name = "Security Record #[id]"
+ R.fields["name"] = name
+ R.fields["id"] = id
+ R.fields["criminal"] = "None"
+ R.fields["mi_crim"] = "None"
+ R.fields["mi_crim_d"] = "No minor crime convictions."
+ R.fields["ma_crim"] = "None"
+ R.fields["ma_crim_d"] = "No major crime convictions."
+ R.fields["notes"] = "No notes."
+ R.fields["notes"] = "No notes."
+ data_core.security += R
+
+ return R
+
+/datum/datacore/proc/CreateMedicalRecord(var/name, var/id)
+ ResetPDAManifest()
+ var/datum/data/record/M = new()
+ M.name = "Medical Record #[id]"
+ M.fields["id"] = id
+ M.fields["name"] = name
+ M.fields["b_type"] = "AB+"
+ M.fields["b_dna"] = md5(name)
+ M.fields["mi_dis"] = "None"
+ M.fields["mi_dis_d"] = "No minor disabilities have been declared."
+ M.fields["ma_dis"] = "None"
+ M.fields["ma_dis_d"] = "No major disabilities have been diagnosed."
+ M.fields["alg"] = "None"
+ M.fields["alg_d"] = "No allergies have been detected in this patient."
+ M.fields["cdi"] = "None"
+ M.fields["cdi_d"] = "No diseases have been diagnosed at the moment."
+ M.fields["notes"] = "No notes found."
+ data_core.medical += M
+
+ return M
+
+/datum/datacore/proc/ResetPDAManifest()
+ if(PDA_Manifest.len)
+ PDA_Manifest.Cut()
+
+/proc/find_general_record(field, value)
+ return find_record(field, value, data_core.general)
+
+/proc/find_medical_record(field, value)
+ return find_record(field, value, data_core.medical)
+
+/proc/find_security_record(field, value)
+ return find_record(field, value, data_core.security)
+
+/proc/find_record(field, value, list/L)
+ for(var/datum/data/record/R in L)
+ if(R.fields[field] == value)
+ return R
+
+/proc/GetAssignment(var/mob/living/carbon/human/H)
+ if(H.mind.role_alt_title)
+ return H.mind.role_alt_title
+ else if(H.mind.assigned_role)
+ return H.mind.assigned_role
+ else if(H.job)
+ return H.job
+ else
+ return "Unassigned"
diff --git a/code/defines/obj.dm b/code/defines/obj.dm
index 5495ff2761..c3082d188f 100644
--- a/code/defines/obj.dm
+++ b/code/defines/obj.dm
@@ -45,129 +45,6 @@
* This item is completely unused, but removing it will break something in R&D and Radio code causing PDA and Ninja code to fail on compile
*/
-/obj/effect/datacore
- name = "datacore"
- var/medical[] = list()
- var/general[] = list()
- var/security[] = list()
- //This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character().
- var/locked[] = list()
-
-
-
-/obj/effect/datacore/proc/get_manifest(monochrome, OOC)
- var/list/heads = new()
- var/list/sec = new()
- var/list/eng = new()
- var/list/med = new()
- var/list/sci = new()
- var/list/civ = new()
- var/list/bot = new()
- var/list/misc = new()
- var/list/isactive = new()
- var/dat = {"
-
-
- | Name | Rank | Activity |
- "}
- var/even = 0
- // sort mobs
- for(var/datum/data/record/t in data_core.general)
- var/name = t.fields["name"]
- var/rank = t.fields["rank"]
- var/real_rank = make_list_rank(t.fields["real_rank"])
-
- if(OOC)
- var/active = 0
- for(var/mob/M in player_list)
- if(M.real_name == name && M.client && M.client.inactivity <= 10 * 60 * 10)
- active = 1
- break
- isactive[name] = active ? "Active" : "Inactive"
- else
- isactive[name] = t.fields["p_stat"]
- //world << "[name]: [rank]"
- //cael - to prevent multiple appearances of a player/job combination, add a continue after each line
- var/department = 0
- if(real_rank in command_positions)
- heads[name] = rank
- department = 1
- if(real_rank in security_positions)
- sec[name] = rank
- department = 1
- if(real_rank in engineering_positions)
- eng[name] = rank
- department = 1
- if(real_rank in medical_positions)
- med[name] = rank
- department = 1
- if(real_rank in science_positions)
- sci[name] = rank
- department = 1
- if(real_rank in civilian_positions)
- civ[name] = rank
- department = 1
- if(real_rank in nonhuman_positions)
- bot[name] = rank
- department = 1
- if(!department && !(name in heads))
- misc[name] = rank
- if(heads.len > 0)
- dat += "| Heads |
"
- for(name in heads)
- dat += "| [name] | [heads[name]] | [isactive[name]] |
"
- even = !even
- if(sec.len > 0)
- dat += "| Security |
"
- for(name in sec)
- dat += "| [name] | [sec[name]] | [isactive[name]] |
"
- even = !even
- if(eng.len > 0)
- dat += "| Engineering |
"
- for(name in eng)
- dat += "| [name] | [eng[name]] | [isactive[name]] |
"
- even = !even
- if(med.len > 0)
- dat += "| Medical |
"
- for(name in med)
- dat += "| [name] | [med[name]] | [isactive[name]] |
"
- even = !even
- if(sci.len > 0)
- dat += "| Science |
"
- for(name in sci)
- dat += "| [name] | [sci[name]] | [isactive[name]] |
"
- even = !even
- if(civ.len > 0)
- dat += "| Civilian |
"
- for(name in civ)
- dat += "| [name] | [civ[name]] | [isactive[name]] |
"
- even = !even
- // in case somebody is insane and added them to the manifest, why not
- if(bot.len > 0)
- dat += "| Silicon |
"
- for(name in bot)
- dat += "| [name] | [bot[name]] | [isactive[name]] |
"
- even = !even
- // misc guys
- if(misc.len > 0)
- dat += "| Miscellaneous |
"
- for(name in misc)
- dat += "| [name] | [misc[name]] | [isactive[name]] |
"
- even = !even
-
- dat += "
"
- dat = replacetext(dat, "\n", "") // so it can be placed on paper correctly
- dat = replacetext(dat, "\t", "")
- return dat
-
-
/var/list/acting_rank_prefixes = list("acting", "temporary", "interim", "provisional")
/proc/make_list_rank(rank)
@@ -181,13 +58,13 @@
We can't just insert in HTML into the nanoUI so we need the raw data to play with.
Instead of creating this list over and over when someone leaves their PDA open to the page
we'll only update it when it changes. The PDA_Manifest global list is zeroed out upon any change
-using /obj/effect/datacore/proc/manifest_inject( ), or manifest_insert( )
+using /datum/datacore/proc/manifest_inject( ), or manifest_insert( )
*/
var/global/list/PDA_Manifest = list()
var/global/ManifestJSON
-/obj/effect/datacore/proc/get_manifest_json()
+/datum/datacore/proc/get_manifest_json()
if(PDA_Manifest.len)
return
var/heads[0]
diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm
index 0a64e89592..fbc3624b7d 100644
--- a/code/defines/procs/announce.dm
+++ b/code/defines/procs/announce.dm
@@ -117,3 +117,18 @@ datum/announcement/proc/Log(message as text, message_title as text)
/proc/GetNameAndAssignmentFromId(var/obj/item/weapon/card/id/I)
// Format currently matches that of newscaster feeds: Registered Name (Assigned Rank)
return I.assignment ? "[I.registered_name] ([I.assignment])" : I.registered_name
+
+/proc/level_seven_announcement()
+ command_announcement.Announce("Confirmed outbreak of level 7 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg')
+
+/proc/ion_storm_announcement()
+ command_announcement.Announce("It has come to our attention that the station passed through an ion storm. Please monitor all electronic equipment for malfunctions.", "Anomaly Alert")
+
+/proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank, var/join_message)
+ if (ticker.current_state == GAME_STATE_PLAYING)
+ if(character.mind.role_alt_title)
+ rank = character.mind.role_alt_title
+ AnnounceArrivalSimple(character.real_name, rank, join_message)
+
+/proc/AnnounceArrivalSimple(var/name, var/rank = "visitor", var/join_message = "has arrived on the station")
+ global_announcer.autosay("[name], [rank], [join_message].", "Arrivals Announcement Computer")
diff --git a/code/defines/procs/records.dm b/code/defines/procs/records.dm
deleted file mode 100644
index 256ae51dbf..0000000000
--- a/code/defines/procs/records.dm
+++ /dev/null
@@ -1,48 +0,0 @@
-/proc/CreateGeneralRecord()
- var/mob/living/carbon/human/dummy = new()
- dummy.mind = new()
- var/icon/front = new(get_id_photo(dummy), dir = SOUTH)
- var/icon/side = new(get_id_photo(dummy), dir = WEST)
- var/datum/data/record/G = new /datum/data/record()
- G.fields["name"] = "New Record"
- G.fields["id"] = text("[]", add_zero(num2hex(rand(1, 1.6777215E7)), 6))
- G.fields["rank"] = "Unassigned"
- G.fields["real_rank"] = "Unassigned"
- G.fields["sex"] = "Male"
- G.fields["age"] = "Unknown"
- G.fields["fingerprint"] = "Unknown"
- G.fields["p_stat"] = "Active"
- G.fields["m_stat"] = "Stable"
- G.fields["species"] = "Human"
- G.fields["home_system"] = "Unknown"
- G.fields["citizenship"] = "Unknown"
- G.fields["faction"] = "Unknown"
- G.fields["religion"] = "Unknown"
- G.fields["photo_front"] = front
- G.fields["photo_side"] = side
- data_core.general += G
-
- qdel(dummy)
- return G
-
-/proc/CreateSecurityRecord(var/name as text, var/id as text)
- var/datum/data/record/R = new /datum/data/record()
- R.fields["name"] = name
- R.fields["id"] = id
- R.name = text("Security Record #[id]")
- R.fields["criminal"] = "None"
- R.fields["mi_crim"] = "None"
- R.fields["mi_crim_d"] = "No minor crime convictions."
- R.fields["ma_crim"] = "None"
- R.fields["ma_crim_d"] = "No major crime convictions."
- R.fields["notes"] = "No notes."
- data_core.security += R
- return R
-
-/proc/find_security_record(field, value)
- return find_record(field, value, data_core.security)
-
-/proc/find_record(field, value, list/L)
- for(var/datum/data/record/R in L)
- if(R.fields[field] == value)
- return R
diff --git a/code/game/antagonist/antagonist_create.dm b/code/game/antagonist/antagonist_create.dm
index 416a774541..69b7f8e9d0 100644
--- a/code/game/antagonist/antagonist_create.dm
+++ b/code/game/antagonist/antagonist_create.dm
@@ -34,10 +34,9 @@
var/obj/item/weapon/card/id/W = new id_type(player)
if(!W) return
- W.name = "[player.real_name]'s ID Card"
W.access |= default_access
W.assignment = "[assignment]"
- W.registered_name = player.real_name
+ W.set_owner_info(player)
if(equip) player.equip_to_slot_or_del(W, slot_wear_id)
return W
diff --git a/code/game/antagonist/outsider/commando.dm b/code/game/antagonist/outsider/commando.dm
index 50d8ac5361..150d1efc19 100644
--- a/code/game/antagonist/outsider/commando.dm
+++ b/code/game/antagonist/outsider/commando.dm
@@ -6,6 +6,7 @@ var/datum/antagonist/deathsquad/mercenary/commandos
role_text = "Syndicate Commando"
role_text_plural = "Commandos"
welcome_text = "You are in the employ of a criminal syndicate hostile to NanoTrasen."
+ id_type = /obj/item/weapon/card/id/centcom/ERT
/datum/antagonist/deathsquad/mercenary/New()
..(1)
@@ -24,7 +25,6 @@ var/datum/antagonist/deathsquad/mercenary/commandos
player.equip_to_slot_or_del(new /obj/item/weapon/rig/merc(player), slot_back)
player.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle(player), slot_r_hand)
- var/obj/item/weapon/card/id/id = create_id("Commando", player)
- id.access |= get_all_station_access()
- id.icon_state = "centcom"
- create_radio(SYND_FREQ, player)
\ No newline at end of file
+ create_id("Commando", player)
+ create_radio(SYND_FREQ, player)
+ return 1
diff --git a/code/game/antagonist/outsider/ert.dm b/code/game/antagonist/outsider/ert.dm
index d847d4ef7a..c6d35ec801 100644
--- a/code/game/antagonist/outsider/ert.dm
+++ b/code/game/antagonist/outsider/ert.dm
@@ -11,6 +11,7 @@ var/datum/antagonist/ert/ert
max_antags = 5
max_antags_round = 5 // ERT mode?
landmark_id = "Response Team"
+ id_type = /obj/item/weapon/card/id/centcom/ERT
flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER | ANTAG_CHOOSE_NAME
@@ -36,10 +37,6 @@ var/datum/antagonist/ert/ert
player.equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(src), slot_shoes)
player.equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(src), slot_gloves)
player.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(src), slot_glasses)
-
- var/obj/item/weapon/card/id/centcom/ERT/W = new(src)
- W.registered_name = player.real_name
- W.name = "[player.real_name]'s ID Card ([W.assignment])"
- player.equip_to_slot_or_del(W, slot_wear_id)
-
+
+ create_id(role_text, player)
return 1
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index 1768ffe642..ff994e8cd3 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -526,10 +526,9 @@ var/global/datum/controller/occupations/job_master
else
C = new /obj/item/weapon/card/id(H)
if(C)
- C.registered_name = H.real_name
C.rank = rank
C.assignment = title ? title : rank
- C.name = "[C.registered_name]'s ID Card ([C.assignment])"
+ C.set_owner_info(H)
//put the player's account number onto the ID
if(H.mind && H.mind.initial_account)
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index 64101d4433..d4af940168 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -623,8 +623,8 @@
return min(..(), .)
-/obj/machinery/alarm/Topic(href, href_list, var/nowindow = 0, var/datum/topic_state/state)
- if(..(href, href_list, nowindow, state))
+/obj/machinery/alarm/Topic(href, href_list, var/datum/topic_state/state)
+ if(..(href, href_list, state))
return 1
// hrefs that can always be called -walter0o
diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm
index 8f048db043..65324f5555 100644
--- a/code/game/machinery/camera/tracking.dm
+++ b/code/game/machinery/camera/tracking.dm
@@ -155,6 +155,11 @@
if(!istype(target)) return
var/mob/living/silicon/ai/U = usr
+ if(target == U.cameraFollow)
+ return
+
+ if(U.cameraFollow)
+ U.ai_cancel_tracking()
U.cameraFollow = target
U << "Now tracking [target.name] on camera."
target.tracking_initiated()
@@ -240,7 +245,8 @@ mob/living/proc/near_camera()
/mob/living/carbon/human/tracking_status()
//Cameras can't track people wearing an agent card or a ninja hood.
- if(wear_id && istype(wear_id.GetID(), /obj/item/weapon/card/id/syndicate))
+ var/obj/item/weapon/card/id/id = GetIdCard(src)
+ if(id && id.prevent_tracking())
return TRACKING_TERMINATE
if(istype(head, /obj/item/clothing/head/helmet/space/rig))
var/obj/item/clothing/head/helmet/space/rig/helmet = head
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index 1f9f13cc4c..090e02c908 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -412,11 +412,11 @@ What a mess.*/
//RECORD CREATE
if ("New Record (Security)")
if ((istype(active1, /datum/data/record) && !( istype(active2, /datum/data/record) )))
- active2 = CreateSecurityRecord(active1.fields["name"], active1.fields["id"])
+ active2 = data_core.CreateSecurityRecord(active1.fields["name"], active1.fields["id"])
screen = 3
if ("New Record (General)")
- active1 = CreateGeneralRecord()
+ active1 = data_core.CreateGeneralRecord()
active2 = null
//FIELD FUNCTIONS
diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm
index 0de14ecbe9..fb2d4ef095 100644
--- a/code/game/machinery/computer/skills.dm
+++ b/code/game/machinery/computer/skills.dm
@@ -303,7 +303,7 @@ What a mess.*/
if ("New Record (General)")
if(PDA_Manifest.len)
PDA_Manifest.Cut()
- active1 = CreateGeneralRecord()
+ active1 = data_core.CreateGeneralRecord()
//FIELD FUNCTIONS
if ("Edit Field")
diff --git a/code/game/machinery/computer3/computers/security.dm b/code/game/machinery/computer3/computers/security.dm
index c13dd9713e..a346c12fac 100644
--- a/code/game/machinery/computer3/computers/security.dm
+++ b/code/game/machinery/computer3/computers/security.dm
@@ -430,11 +430,11 @@ What a mess.*/
//RECORD CREATE
if ("New Record (Security)")
if ((istype(active1, /datum/data/record) && !( istype(active2, /datum/data/record) )))
- active2 = CreateSecurityRecord(active1.fields["name"], active1.fields["id"])
+ active2 = data_core.CreateSecurityRecord(active1.fields["name"], active1.fields["id"])
screen = 3
if ("New Record (General)")
- active1 = CreateGeneralRecord()
+ active1 = data_core.CreateGeneralRecord()
active2 = null
//FIELD FUNCTIONS
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 3df603efbc..83c3ab98d7 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -674,7 +674,7 @@ About the new airlock wires panel:
return ..()
-/obj/machinery/door/airlock/Topic(href, href_list, var/nowindow = 0)
+/obj/machinery/door/airlock/Topic(href, href_list)
if(..())
return 1
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index 74d3a4c52f..c2e7cbace7 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -236,7 +236,7 @@ var/list/turret_icons
return ..()
-/obj/machinery/porta_turret/Topic(href, href_list, var/nowindow = 0)
+/obj/machinery/porta_turret/Topic(href, href_list)
if(..())
return 1
diff --git a/code/game/machinery/telecomms/logbrowser.dm b/code/game/machinery/telecomms/logbrowser.dm
index 2f6165a733..acc2fba198 100644
--- a/code/game/machinery/telecomms/logbrowser.dm
+++ b/code/game/machinery/telecomms/logbrowser.dm
@@ -1,8 +1,11 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
+/obj/machinery/computer/telecomms
+ icon_keyboard = "tech_key"
+
/obj/machinery/computer/telecomms/server
name = "Telecommunications Server Monitor"
- icon_state = "comm_logs"
+ icon_screen = "comm_logs"
var/screen = 0 // the screen number:
var/list/servers = list() // the servers located by the computer
diff --git a/code/game/machinery/telecomms/telemonitor.dm b/code/game/machinery/telecomms/telemonitor.dm
index 7dd30dd8c3..152532894a 100644
--- a/code/game/machinery/telecomms/telemonitor.dm
+++ b/code/game/machinery/telecomms/telemonitor.dm
@@ -9,7 +9,7 @@
/obj/machinery/computer/telecomms/monitor
name = "Telecommunications Monitor"
- icon_state = "comm_monitor"
+ icon_screen = "comm_monitor"
var/screen = 0 // the screen number:
var/list/machinelist = list() // the machines located by the computer
diff --git a/code/game/machinery/telecomms/traffic_control.dm b/code/game/machinery/telecomms/traffic_control.dm
index 1123733103..8337c3aa51 100644
--- a/code/game/machinery/telecomms/traffic_control.dm
+++ b/code/game/machinery/telecomms/traffic_control.dm
@@ -6,7 +6,7 @@
/obj/machinery/computer/telecomms/traffic
name = "Telecommunications Traffic Control"
- icon_state = "computer_generic"
+ icon_screen = "generic"
var/screen = 0 // the screen number:
var/list/servers = list() // the servers located by the computer
diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm
index 77667fa6bc..2ea1424522 100644
--- a/code/game/machinery/turret_control.dm
+++ b/code/game/machinery/turret_control.dm
@@ -139,7 +139,7 @@
ui.open()
ui.set_auto_update(1)
-/obj/machinery/turretid/Topic(href, href_list, var/nowindow = 0)
+/obj/machinery/turretid/Topic(href, href_list)
if(..())
return 1
diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm
index 6b239c6b07..577ee1010b 100644
--- a/code/game/objects/items/devices/aicard.dm
+++ b/code/game/objects/items/devices/aicard.dm
@@ -46,7 +46,7 @@
ui.open()
ui.set_auto_update(1)
-/obj/item/device/aicard/Topic(href, href_list, nowindow, state)
+/obj/item/device/aicard/Topic(href, href_list, state)
if(..())
return 1
diff --git a/code/game/objects/items/devices/uplink_categories.dm b/code/game/objects/items/devices/uplink_categories.dm
index f90c4797bc..ae005022be 100644
--- a/code/game/objects/items/devices/uplink_categories.dm
+++ b/code/game/objects/items/devices/uplink_categories.dm
@@ -15,6 +15,9 @@
/datum/uplink_category/ammunition
name = "Ammunition"
+/datum/uplink_category/grenades
+ name = "Grenades and Thrown Objects"
+
/datum/uplink_category/visible_weapons
name = "Highly Visible and Dangerous Weapons"
@@ -36,5 +39,8 @@
/datum/uplink_category/hardsuit_modules
name = "Hardsuit Modules"
+/datum/uplink_category/services
+ name = "Services"
+
/datum/uplink_category/badassery
name = "Badassery"
diff --git a/code/game/objects/items/devices/uplink_items.dm b/code/game/objects/items/devices/uplink_items.dm
index 2a63f1a38b..939292a6d6 100644
--- a/code/game/objects/items/devices/uplink_items.dm
+++ b/code/game/objects/items/devices/uplink_items.dm
@@ -9,6 +9,7 @@ var/datum/uplink/uplink = new()
items_assoc = list()
items = init_subtypes(/datum/uplink_item)
categories = init_subtypes(/datum/uplink_category)
+ categories = dd_sortedObjectList(categories)
for(var/datum/uplink_item/item in items)
if(!item.name)
@@ -38,15 +39,31 @@ var/datum/uplink/uplink = new()
..()
antag_roles = list()
-/datum/uplink_item/proc/buy(var/obj/item/device/uplink/U, var/mob/user)
- purchase_log(U)
- var/cost = cost(U.uses)
- var/goods = get_goods(U, get_turf(user))
+
+/datum/uplink_item/proc/buy(var/obj/item/device/uplink/U, var/mob/user)
+ var/extra_args = extra_args(user)
+ if(!extra_args)
+ return
+
+ if(!can_buy(U))
+ return
+
+ var/cost = cost(U.uses)
+
+ var/goods = get_goods(U, get_turf(user), user, extra_args)
+ if(!goods)
+ return
+
+ purchase_log(U)
U.uses -= cost
U.used_TC += cost
return goods
+// Any additional arguments you wish to send to the get_goods
+/datum/uplink_item/proc/extra_args(var/mob/user)
+ return 1
+
/datum/uplink_item/proc/can_buy(obj/item/device/uplink/U)
if(cost(U.uses) > U.uses)
return 0
@@ -90,11 +107,14 @@ datum/uplink_item/dd_SortValue()
/********************************
* *
-* Physical Uplink Entires *
+* Physical Uplink Entries *
* *
********************************/
/datum/uplink_item/item/buy(var/obj/item/device/uplink/U, var/mob/user)
var/obj/item/I = ..()
+ if(!I)
+ return
+
if(istype(I, /list))
var/list/L = I
if(L.len) I = L[1]
@@ -156,11 +176,6 @@ datum/uplink_item/dd_SortValue()
/datum/uplink_item/item/visible_weapons
category = /datum/uplink_category/visible_weapons
-/datum/uplink_item/item/visible_weapons/emp
- name = "5xEMP Grenades"
- item_cost = 3
- path = /obj/item/weapon/storage/box/emps
-
/datum/uplink_item/item/visible_weapons/energy_sword
name = "Energy Sword"
item_cost = 4
@@ -452,6 +467,27 @@ datum/uplink_item/dd_SortValue()
item_cost = 8
path = /obj/item/rig_module/mounted
+/***********
+* Grenades *
+************/
+/datum/uplink_item/item/grenades
+ category = /datum/uplink_category/grenades
+
+/datum/uplink_item/item/grenades/anti_photon
+ name = "5xPhoton Disruption Grenades"
+ item_cost = 2
+ path = /obj/item/weapon/storage/box/anti_photons
+
+/datum/uplink_item/item/grenades/emp
+ name = "5xEMP Grenades"
+ item_cost = 3
+ path = /obj/item/weapon/storage/box/emps
+
+/datum/uplink_item/item/grenades/smoke
+ name = "5xSmoke Grenades"
+ item_cost = 2
+ path = /obj/item/weapon/storage/box/smokes
+
/************
* Badassery *
************/
@@ -531,6 +567,124 @@ datum/uplink_item/dd_SortValue()
return "\icon[icon]"
+/********************************
+* *
+* Abstract Uplink Entries *
+* *
+********************************/
+var/image/default_abstract_uplink_icon
+/datum/uplink_item/abstract/log_icon()
+ if(!default_abstract_uplink_icon)
+ default_abstract_uplink_icon = image('icons/obj/pda.dmi', "pda-syn")
+
+ return "\icon[default_abstract_uplink_icon]"
+
+/****************
+* Announcements *
+*****************/
+/datum/uplink_item/abstract/announcements
+ category = /datum/uplink_category/services
+
+/datum/uplink_item/abstract/announcements/buy(var/obj/item/device/uplink/U, var/mob/user)
+ . = ..()
+ if(.)
+ log_and_message_admins("has triggered a falsified [src]", user)
+
+/datum/uplink_item/abstract/announcements/fake_centcom
+ item_cost = DEFAULT_TELECRYSTAL_AMOUNT / 2
+
+/datum/uplink_item/abstract/announcements/fake_centcom/New()
+ ..()
+ name = "[command_name()] Update Announcement"
+ desc = "Causes a falsified [command_name()] Update. Triggers immediately after supplying additional data."
+ antag_roles = list(MODE_MERCENARY)
+
+/datum/uplink_item/abstract/announcements/fake_centcom/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/user, var/list/args)
+ command_announcement.Announce(args.["message"], args.["title"])
+ return 1
+
+/datum/uplink_item/abstract/announcements/fake_crew_arrival
+ name = "Crew Arrival Announcement/Records"
+ desc = "Creates a fake crew arrival announcement as well as fake crew records, using your current appearance (including held items!) and worn id card. Trigger with care!"
+ item_cost = 4
+
+/datum/uplink_item/abstract/announcements/fake_crew_arrival/New()
+ ..()
+ antag_roles = list(MODE_MERCENARY)
+
+/datum/uplink_item/abstract/announcements/fake_crew_arrival/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/user, var/list/args)
+ if(!user)
+ return 0
+
+ var/obj/item/weapon/card/id/I = GetIdCard(user)
+ var/datum/data/record/random_general_record
+ var/datum/data/record/random_medical_record
+ if(data_core.general.len)
+ random_general_record = pick(data_core.general)
+ random_medical_record = find_medical_record("id", random_general_record.fields["id"])
+
+ var/datum/data/record/general = data_core.CreateGeneralRecord(user)
+ if(I)
+ general.fields["age"] = I.age
+ general.fields["rank"] = I.assignment
+ general.fields["real_rank"] = I.assignment
+ general.fields["name"] = I.registered_name
+ general.fields["sex"] = I.sex
+ else
+ var/mob/living/carbon/human/H
+ if(istype(user,/mob/living/carbon/human))
+ H = user
+ general.fields["age"] = H.age
+ else
+ general.fields["age"] = initial(H.age)
+ var/assignment = GetAssignment(user)
+ general.fields["rank"] = assignment
+ general.fields["real_rank"] = assignment
+ general.fields["name"] = user.real_name
+ general.fields["sex"] = capitalize(user.gender)
+
+ general.fields["species"] = user.get_species()
+ var/datum/data/record/medical = data_core.CreateMedicalRecord(general.fields["name"], general.fields["id"])
+ data_core.CreateSecurityRecord(general.fields["name"], general.fields["id"])
+
+ if(!random_general_record)
+ general.fields["citizenship"] = random_general_record.fields["citizenship"]
+ general.fields["faction"] = random_general_record.fields["faction"]
+ general.fields["fingerprint"] = random_general_record.fields["fingerprint"]
+ general.fields["home_system"] = random_general_record.fields["home_system"]
+ general.fields["religion"] = random_general_record.fields["religion"]
+ if(random_medical_record)
+ medical.fields["b_type"] = random_medical_record.fields["b_type"]
+ medical.fields["b_dna"] = random_medical_record.fields["b_type"]
+
+ if(I)
+ general.fields["fingerprint"] = I.fingerprint_hash
+ medical.fields["b_type"] = I.blood_type
+ medical.fields["b_dna"] = I.dna_hash
+
+ AnnounceArrivalSimple(general.fields["name"], general.fields["rank"])
+ return 1
+
+/datum/uplink_item/abstract/announcements/fake_ion_storm
+ name = "Ion Storm Announcement"
+ desc = "Interferes with the station's ion sensors. Triggers immediately upon investment."
+ item_cost = 1
+
+/datum/uplink_item/abstract/announcements/fake_ion_storm/get_goods(var/obj/item/device/uplink/U, var/loc)
+ ion_storm_announcement()
+ return 1
+
+/datum/uplink_item/abstract/announcements/fake_radiation
+ name = "Radiation Storm Announcement"
+ desc = "Interferes with the station's radiation sensors. Triggers immediately upon investment."
+ item_cost = 3
+
+/datum/uplink_item/abstract/announcements/fake_radiation/get_goods(var/obj/item/device/uplink/U, var/loc)
+ var/datum/event_meta/EM = new(EVENT_LEVEL_MUNDANE, "Fake Radiation Storm", add_to_queue = 0)
+ new/datum/event/radiation_storm/syndicate(EM)
+ return 1
+
+
/****************
* Support procs *
****************/
diff --git a/code/game/objects/items/devices/uplink_random_lists.dm b/code/game/objects/items/devices/uplink_random_lists.dm
index 5e843388c5..8889a52d91 100644
--- a/code/game/objects/items/devices/uplink_random_lists.dm
+++ b/code/game/objects/items/devices/uplink_random_lists.dm
@@ -44,7 +44,7 @@ var/datum/uplink_random_selection/default_uplink_selection = new/datum/uplink_ra
items += new/datum/uplink_random_item(/datum/uplink_item/item/ammo/a357)
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/heavysniper, 15, 0)
items += new/datum/uplink_random_item(/datum/uplink_item/item/ammo/sniperammo, 15, 0)
- items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/emp, 50)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/grenades/emp, 50)
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/crossbow, 33)
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/energy_sword, 75)
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index e69d61ee7a..ae6bcbdf0c 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -97,27 +97,75 @@
var/registered_name = "Unknown" // The name registered_name on the card
slot_flags = SLOT_ID
+ var/age = "\[UNSET\]"
var/blood_type = "\[UNSET\]"
var/dna_hash = "\[UNSET\]"
var/fingerprint_hash = "\[UNSET\]"
+ var/sex = "\[UNSET\]"
+ var/icon/front
+ var/icon/side
//alt titles are handled a bit weirdly in order to unobtrusively integrate into existing ID system
var/assignment = null //can be alt title or the actual job
var/rank = null //actual job
- var/dorm = 0 // determines if this ID has claimed a dorm already
+ var/dorm = 0 // determines if this ID has claimed a dorm already
-/obj/item/weapon/card/id/New()
- ..()
- spawn(30)
- if(istype(loc, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = loc
- blood_type = H.dna.b_type
- dna_hash = H.dna.unique_enzymes
- fingerprint_hash = md5(H.dna.uni_identity)
+/obj/item/weapon/card/id/examine(mob/user)
+ set src in oview(1)
+ if(in_range(usr, src))
+ show(usr)
+ usr << desc
+ else
+ usr << "It is too far away."
+
+/obj/item/weapon/card/id/proc/prevent_tracking()
+ return 0
+
+/obj/item/weapon/card/id/proc/show(mob/user as mob)
+ user << browse_rsc(front, "front.png")
+ user << browse_rsc(side, "side.png")
+ var/datum/browser/popup = new(user, "idcard", name, 600, 250)
+ popup.set_content(dat())
+ popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state))
+ popup.open()
+ return
+
+/obj/item/weapon/card/id/proc/update_name()
+ name = "[src.registered_name]'s ID Card ([src.assignment])"
+
+/obj/item/weapon/card/id/proc/set_id_photo(var/mob/M)
+ front = getFlatIcon(M, SOUTH, always_use_defdir = 1)
+ side = getFlatIcon(M, WEST, always_use_defdir = 1)
+
+/obj/item/weapon/card/id/proc/set_owner_info(var/mob/living/carbon/human/H)
+ if(!H || !H.dna)
+ return
+ age = H.age
+ blood_type = H.dna.b_type
+ dna_hash = H.dna.unique_enzymes
+ fingerprint_hash = md5(H.dna.uni_identity)
+ registered_name = H.real_name
+ sex = capitalize(H.gender)
+ set_id_photo(H)
+ update_name()
+
+/obj/item/weapon/card/id/proc/dat()
+ var/dat = ("")
+ dat += text("Name: [] ", registered_name)
+ dat += text("Sex: [] \n", sex)
+ dat += text("Age: [] \n", age)
+ dat += text("Rank: [] \n", assignment)
+ dat += text("Fingerprint: [] \n", fingerprint_hash)
+ dat += text("Blood Type: [] \n", blood_type)
+ dat += text("DNA Hash: []
\n", dna_hash)
+ if(front && side)
+ dat +=" | Photo:
  | "
+ dat += "
"
+ return dat
/obj/item/weapon/card/id/attack_self(mob/user as mob)
- for(var/mob/O in viewers(user, null))
- O.show_message(text("[] shows you: \icon[] []: assignment: []", user, src, src.name, src.assignment), 1)
+ user.visible_message("\The [user] shows you: \icon[src] [src.name]. The assignment on the card: [src.assignment]",\
+ "You flash your ID card: \icon[src] [src.name]. The assignment on the card: [src.assignment]")
src.add_fingerprint(user)
return
@@ -139,7 +187,6 @@
usr << "The fingerprint hash on the card is [fingerprint_hash]."
return
-
/obj/item/weapon/card/id/silver
name = "identification card"
desc = "A silver card which shows honour and dedication."
@@ -152,75 +199,6 @@
icon_state = "gold"
item_state = "gold_id"
-/obj/item/weapon/card/id/syndicate
- name = "agent card"
- origin_tech = list(TECH_ILLEGAL = 3)
- var/registered_user=null
-
-/obj/item/weapon/card/id/syndicate/New(mob/user as mob)
- ..()
- access = syndicate_access.Copy()
- if(!isnull(user)) // Runtime prevention on laggy starts or where users log out because of lag at round start.
- registered_name = ishuman(user) ? user.real_name : user.name
- else
- registered_name = "Agent Card"
- assignment = "Agent"
- name = "[registered_name]'s ID Card ([assignment])"
-
-/obj/item/weapon/card/id/syndicate/afterattack(var/obj/item/weapon/O as obj, mob/user as mob, proximity)
- if(!proximity) return
- if(istype(O, /obj/item/weapon/card/id))
- var/obj/item/weapon/card/id/I = O
- src.access |= I.access
- if(istype(user, /mob/living) && user.mind)
- if(user.mind.special_role)
- usr << "The card's microscanners activate as you pass it over the ID, copying its access."
-
-/obj/item/weapon/card/id/syndicate/attack_self(mob/user as mob)
- if(!src.registered_name)
- //Stop giving the players unsanitized unputs! You are giving ways for players to intentionally crash clients! -Nodrak
- var t = sanitizeName(input(user, "What name would you like to put on this card?", "Agent card name", ishuman(user) ? user.real_name : user.name), MAX_NAME_LEN)
- if(!t) //Same as mob/new_player/prefrences.dm
- alert("Invalid name.")
- return
- src.registered_name = t
-
- var u = sanitize(input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Agent"), MAX_LNAME_LEN)
- if(!u)
- alert("Invalid assignment.")
- src.registered_name = ""
- return
- src.assignment = u
- src.name = "[src.registered_name]'s ID Card ([src.assignment])"
- user << "You successfully forge the ID card."
- registered_user = user
- else if(!registered_user || registered_user == user)
-
- if(!registered_user) registered_user = user //
-
- switch(alert("Would you like to display the ID, or retitle it?","Choose.","Rename","Show"))
- if("Rename")
- var t = sanitize(input(user, "What name would you like to put on this card?", "Agent card name", ishuman(user) ? user.real_name : user.name), 26)
- if(!t || t == "Unknown" || t == "floor" || t == "wall" || t == "r-wall") //Same as mob/new_player/prefrences.dm
- alert("Invalid name.")
- return
- src.registered_name = t
-
- var u = sanitize(input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Assistant"))
- if(!u)
- alert("Invalid assignment.")
- return
- src.assignment = u
- src.name = "[src.registered_name]'s ID Card ([src.assignment])"
- user << "You successfully forge the ID card."
- return
- if("Show")
- ..()
- else
- ..()
-
-
-
/obj/item/weapon/card/id/syndicate_command
name = "syndicate ID card"
desc = "An ID straight from the Syndicate."
@@ -255,4 +233,4 @@
/obj/item/weapon/card/id/centcom/ERT/New()
..()
- access += get_all_station_access()
+ access |= get_all_station_access()
diff --git a/code/game/objects/items/weapons/cards_ids_syndicate.dm b/code/game/objects/items/weapons/cards_ids_syndicate.dm
new file mode 100644
index 0000000000..2475c93534
--- /dev/null
+++ b/code/game/objects/items/weapons/cards_ids_syndicate.dm
@@ -0,0 +1,204 @@
+var/global/list/syndicate_ids = list()
+
+/obj/item/weapon/card/id/syndicate
+ name = "agent card"
+ assignment = "Agent"
+ origin_tech = list(TECH_ILLEGAL = 3)
+ var/electronic_warfare = 1
+ var/registered_user = null
+ var/list/initial_access = list(access_maint_tunnels, access_syndicate, access_external_airlocks)
+
+/obj/item/weapon/card/id/syndicate/New(mob/user as mob)
+ syndicate_ids += src
+ ..()
+ access = initial_access.Copy()
+
+/obj/item/weapon/card/id/syndicate/Destroy()
+ syndicate_ids -= src
+ registered_user = null
+ return ..()
+
+// On mob destruction, ensure any references are cleared
+/mob/Destroy()
+ for(var/obj/item/weapon/card/id/syndicate/SID in syndicate_ids)
+ if(SID.registered_user == src)
+ SID.registered_user = null
+ return ..()
+
+/obj/item/weapon/card/id/syndicate/prevent_tracking()
+ return electronic_warfare
+
+/obj/item/weapon/card/id/syndicate/afterattack(var/obj/item/weapon/O as obj, mob/user as mob, proximity)
+ if(!proximity) return
+ if(istype(O, /obj/item/weapon/card/id))
+ var/obj/item/weapon/card/id/I = O
+ src.access |= I.access
+ if(player_is_antag(user))
+ user << "The microscanner activate as you pass it over the ID, copying its access."
+
+/obj/item/weapon/card/id/syndicate/attack_self(mob/user as mob)
+ if(!registered_user)
+ registered_user = user
+ set_owner_info(user)
+ user << "The microscanner marks you as its owner, preventing others some accessing its internals."
+ if(registered_user == user)
+ switch(alert("Would you like edit the ID, or show it?","Show or Edit?", "Edit","Show"))
+ if("Edit")
+ ui_interact(user)
+ if("Show")
+ ..()
+ else
+ ..()
+
+/obj/item/weapon/card/id/syndicate/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ var/data[0]
+ var/entries[0]
+ entries[++entries.len] = list("name" = "Age", "value" = age)
+ entries[++entries.len] = list("name" = "Appearance", "value" = "Set")
+ entries[++entries.len] = list("name" = "Assignment", "value" = assignment)
+ entries[++entries.len] = list("name" = "Blood Type", "value" = blood_type)
+ entries[++entries.len] = list("name" = "DNA Hash", "value" = dna_hash)
+ entries[++entries.len] = list("name" = "Fingerprint Hash", "value" = fingerprint_hash)
+ entries[++entries.len] = list("name" = "Name", "value" = registered_name)
+ entries[++entries.len] = list("name" = "Photo", "value" = "Update")
+ entries[++entries.len] = list("name" = "Sex", "value" = sex)
+ entries[++entries.len] = list("name" = "Factory Reset", "value" = "Use With Care")
+ data["electronic_warfare"] = electronic_warfare
+ data["entries"] = entries
+
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "agent_id_card.tmpl", "Agent id", 600, 400)
+ ui.set_initial_data(data)
+ ui.open()
+
+/obj/item/weapon/card/id/syndicate/CanUseTopic(mob/user)
+ if(user != registered_user)
+ return STATUS_CLOSE
+ return ..()
+
+/obj/item/weapon/card/id/syndicate/Topic(href, href_list, var/datum/topic_state/state)
+ if(..())
+ return 1
+
+ var/user = usr
+ if(href_list["electronic_warfare"])
+ electronic_warfare = text2num(href_list["electronic_warfare"])
+ user << "Electronic warfare [electronic_warfare ? "enabled" : "disabled"]."
+ else if(href_list["set"])
+ switch(href_list["set"])
+ if("Age")
+ var/new_age = input(user,"What age would you like to put on this card?","Agent Card Age", age) as null|num
+ if(!isnull(new_age) && CanUseTopic(user, state))
+ if(new_age < 0)
+ age = initial(age)
+ else
+ age = new_age
+ user << "Age has been set to '[age]'."
+ . = 1
+ if("Appearance")
+ var/datum/card_state/choice = input(user, "Select the appearance for this card.", "Agent Card Appearance") as null|anything in id_card_states()
+ if(choice && CanUseTopic(user, state))
+ src.icon_state = choice.icon_state
+ src.item_state = choice.item_state
+ usr << "Appearance changed to [choice]."
+ . = 1
+ if("Assignment")
+ var/new_job = sanitize(input(user,"What assignment would you like to put on this card?\nChanging assignment will not grant or remove any access levels.","Agent Card Assignment", assignment) as null|text)
+ if(!isnull(new_job) && CanUseTopic(user, state))
+ src.assignment = new_job
+ user << "Occupation changed to '[new_job]'."
+ update_name()
+ . = 1
+ if("Blood Type")
+ var/default = blood_type
+ if(default == initial(blood_type) && ishuman(user))
+ var/mob/living/carbon/human/H = user
+ if(H.dna)
+ default = H.dna.b_type
+ var/new_blood_type = sanitize(input(user,"What blood type would you like to be written on this card?","Agent Card Blood Type",default) as null|text)
+ if(!isnull(new_blood_type) && CanUseTopic(user, state))
+ src.blood_type = new_blood_type
+ user << "Blood type changed to '[new_blood_type]'."
+ . = 1
+ if("DNA Hash")
+ var/default = dna_hash
+ if(default == initial(dna_hash) && ishuman(user))
+ var/mob/living/carbon/human/H = user
+ if(H.dna)
+ default = H.dna.unique_enzymes
+ var/new_dna_hash = sanitize(input(user,"What DNA hash would you like to be written on this card?","Agent Card DNA Hash",default) as null|text)
+ if(!isnull(new_dna_hash) && CanUseTopic(user, state))
+ src.dna_hash = new_dna_hash
+ user << "DNA hash changed to '[new_dna_hash]'."
+ . = 1
+ if("Fingerprint Hash")
+ var/default = fingerprint_hash
+ if(default == initial(fingerprint_hash) && ishuman(user))
+ var/mob/living/carbon/human/H = user
+ if(H.dna)
+ default = md5(H.dna.uni_identity)
+ var/new_fingerprint_hash = sanitize(input(user,"What fingerprint hash would you like to be written on this card?","Agent Card Fingerprint Hash",default) as null|text)
+ if(!isnull(new_fingerprint_hash) && CanUseTopic(user, state))
+ src.fingerprint_hash = new_fingerprint_hash
+ user << "Fingerprint hash changed to '[new_fingerprint_hash]'."
+ . = 1
+ if("Name")
+ var/new_name = sanitizeName(input(user,"What name would you like to put on this card?","Agent Card Name", registered_name) as null|text)
+ if(!isnull(new_name) && CanUseTopic(user, state))
+ src.registered_name = new_name
+ update_name()
+ user << "Name changed to '[new_name]'."
+ . = 1
+ if("Photo")
+ set_id_photo(user)
+ user << "Photo changed."
+ . = 1
+ if("Sex")
+ var/new_sex = sanitize(input(user,"What sex would you like to put on this card?","Agent Card Sex", sex) as null|text)
+ if(!isnull(new_sex) && CanUseTopic(user, state))
+ src.sex = new_sex
+ user << "Sex changed to '[new_sex]'."
+ . = 1
+ if("Factory Reset")
+ if(alert("This will factory reset the card, including access and owner. Continue?", "Factory Reset", "No", "Yes") == "Yes" && CanUseTopic(user, state))
+ age = initial(age)
+ access = initial_access.Copy()
+ assignment = initial(assignment)
+ blood_type = initial(blood_type)
+ dna_hash = initial(dna_hash)
+ electronic_warfare = initial(electronic_warfare)
+ fingerprint_hash = initial(fingerprint_hash)
+ icon_state = initial(icon_state)
+ name = initial(name)
+ registered_name = initial(registered_name)
+ registered_user = null
+ sex = initial(sex)
+ user << "All information has been deleted from \the [src]."
+ . = 1
+
+ // Always update the UI, or buttons will spin indefinitely
+ nanomanager.update_uis(src)
+
+/var/global/list/id_card_states
+/proc/id_card_states()
+ if(!id_card_states)
+ id_card_states = list()
+ for(var/path in typesof(/obj/item/weapon/card/id))
+ var/obj/item/weapon/card/id/ID = path
+ var/datum/card_state/CS = new()
+ CS.icon_state = initial(ID.icon_state)
+ CS.item_state = initial(ID.item_state)
+ CS.name = initial(ID.name) + " - " + initial(ID.icon_state)
+ id_card_states += CS
+ id_card_states = dd_sortedObjectList(id_card_states)
+
+ return id_card_states
+
+/datum/card_state
+ var/name
+ var/icon_state
+ var/item_state
+
+/datum/card_state/dd_SortValue()
+ return name
diff --git a/code/game/objects/items/weapons/grenades/anti_photon_grenade.dm b/code/game/objects/items/weapons/grenades/anti_photon_grenade.dm
new file mode 100644
index 0000000000..1613ff8800
--- /dev/null
+++ b/code/game/objects/items/weapons/grenades/anti_photon_grenade.dm
@@ -0,0 +1,23 @@
+/obj/item/weapon/grenade/anti_photon
+ desc = "An experimental device for temporarily removing light in a limited area."
+ name = "pgoton disruption grenade"
+ icon = 'icons/obj/grenade.dmi'
+ icon_state = "emp"
+ item_state = "emp"
+ det_time = 20
+ origin_tech = list(TECH_BLUESPACE = 4, TECH_MATERIAL = 4)
+
+/obj/item/weapon/grenade/anti_photon/prime()
+ playsound(src.loc, 'sound/effects/phasein.ogg', 50, 1, 5)
+ set_light(10, -10, "#FFFFFF")
+
+ var/extra_delay = rand(0,90)
+
+ spawn(extra_delay)
+ spawn(200)
+ if(prob(10+extra_delay))
+ set_light(10, 10, "#[num2hex(rand(64,255))][num2hex(rand(64,255))][num2hex(rand(64,255))]")
+ spawn(210)
+ ..()
+ playsound(src.loc, 'sound/effects/bang.ogg', 50, 1, 5)
+ qdel(src)
diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm
index 95c4191622..abc9a39b76 100644
--- a/code/game/objects/items/weapons/storage/boxes.dm
+++ b/code/game/objects/items/weapons/storage/boxes.dm
@@ -298,6 +298,31 @@
new /obj/item/weapon/grenade/empgrenade(src)
new /obj/item/weapon/grenade/empgrenade(src)
+/obj/item/weapon/storage/box/smokes
+ name = "box of smoke bombs"
+ desc = "A box containing 5 smoke bombs."
+ icon_state = "flashbang"
+
+/obj/item/weapon/storage/box/smokes/New()
+ ..()
+ new /obj/item/weapon/grenade/smokebomb(src)
+ new /obj/item/weapon/grenade/smokebomb(src)
+ new /obj/item/weapon/grenade/smokebomb(src)
+ new /obj/item/weapon/grenade/smokebomb(src)
+ new /obj/item/weapon/grenade/smokebomb(src)
+
+/obj/item/weapon/storage/box/anti_photons
+ name = "box of anti-photon grenades"
+ desc = "A box containing 5 experimental photon disruption grenades."
+ icon_state = "flashbang"
+
+/obj/item/weapon/storage/box/anti_photon/New()
+ ..()
+ new /obj/item/weapon/grenade/anti_photon(src)
+ new /obj/item/weapon/grenade/anti_photon(src)
+ new /obj/item/weapon/grenade/anti_photon(src)
+ new /obj/item/weapon/grenade/anti_photon(src)
+ new /obj/item/weapon/grenade/anti_photon(src)
/obj/item/weapon/storage/box/trackimp
name = "boxed tracking implant kit"
@@ -638,4 +663,4 @@
max_w_class = 3
can_hold = list(/obj/item/organ, /obj/item/weapon/reagent_containers/food, /obj/item/weapon/reagent_containers/glass)
max_storage_space = 21
- use_to_pickup = 1 // for picking up broken bulbs, not that most people will try
+ use_to_pickup = 1 // for picking up broken bulbs, not that most people will try
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index cfea392be0..8027d5093b 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -19,9 +19,8 @@
nanomanager.close_uis(src)
return ..()
-/obj/Topic(href, href_list, var/nowindow = 0, var/datum/topic_state/state = default_state)
- // Calling Topic without a corresponding window open causes runtime errors
- if(!nowindow && ..())
+/obj/Topic(href, href_list, var/datum/topic_state/state = default_state)
+ if(usr && ..())
return 1
// In the far future no checks are made in an overriding Topic() beyond if(..()) return
diff --git a/code/global.dm b/code/global.dm
index 4e26bbccc5..3ee50845b3 100644
--- a/code/global.dm
+++ b/code/global.dm
@@ -4,7 +4,7 @@
#endif
// Items that ask to be called every cycle.
-var/global/obj/effect/datacore/data_core = null
+var/global/datum/datacore/data_core = null
var/global/list/all_areas = list()
var/global/list/machines = list()
var/global/list/processing_objects = list()
diff --git a/code/modules/admin/admin_attack_log.dm b/code/modules/admin/admin_attack_log.dm
index 72e85e1d94..967a4375da 100644
--- a/code/modules/admin/admin_attack_log.dm
+++ b/code/modules/admin/admin_attack_log.dm
@@ -4,7 +4,7 @@
proc/log_and_message_admins(var/message as text, var/mob/user = usr)
log_admin(user ? "[key_name(user)] [message]" : "EVENT [message]")
- message_admins(user ? "[key_name(user)] [message]" : "EVENT [message]")
+ message_admins(user ? "[key_name_admin(user)] [message]" : "EVENT [message]")
proc/log_and_message_admins_many(var/list/mob/users, var/message)
if(!users || !users.len)
@@ -17,10 +17,6 @@ proc/log_and_message_admins_many(var/list/mob/users, var/message)
log_admin("[english_list(user_keys)] [message]")
message_admins("[english_list(user_keys)] [message]")
-proc/admin_log_and_message_admins(var/message as text)
- log_admin(usr ? "[key_name_admin(usr)] [message]" : "EVENT [message]")
- message_admins(usr ? "[key_name_admin(usr)] [message]" : "EVENT [message]", 1)
-
proc/admin_attack_log(var/mob/attacker, var/mob/victim, var/attacker_message, var/victim_message, var/admin_message)
if(victim)
victim.attack_log += text("\[[time_stamp()]\] [key_name(attacker)] - [victim_message]")
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index baf5e48f8e..6206071ba2 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -732,7 +732,7 @@ var/list/admin_verbs_mentor = list(
var/new_name = sanitizeSafe(input(src, "Enter new name. Leave blank or as is to cancel.", "[S.real_name] - Enter new silicon name", S.real_name))
if(new_name && new_name != S.real_name)
- admin_log_and_message_admins("has renamed the silicon '[S.real_name]' to '[new_name]'")
+ log_and_message_admins("has renamed the silicon '[S.real_name]' to '[new_name]'")
S.SetName(new_name)
feedback_add_details("admin_verb","RAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -747,7 +747,7 @@ var/list/admin_verbs_mentor = list(
var/datum/nano_module/law_manager/L = new(S)
L.ui_interact(usr, state = admin_state)
- admin_log_and_message_admins("has opened [S]'s law manager.")
+ log_and_message_admins("has opened [S]'s law manager.")
feedback_add_details("admin_verb","MSL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/change_human_appearance_admin()
@@ -760,7 +760,7 @@ var/list/admin_verbs_mentor = list(
var/mob/living/carbon/human/H = input("Select mob.", "Change Mob Appearance - Admin") as null|anything in human_mob_list
if(!H) return
- admin_log_and_message_admins("is altering the appearance of [H].")
+ log_and_message_admins("is altering the appearance of [H].")
H.change_appearance(APPEARANCE_ALL, usr, usr, check_species_whitelist = 0, state = admin_state)
feedback_add_details("admin_verb","CHAA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -780,10 +780,10 @@ var/list/admin_verbs_mentor = list(
switch(alert("Do you wish for [H] to be allowed to select non-whitelisted races?","Alter Mob Appearance","Yes","No","Cancel"))
if("Yes")
- admin_log_and_message_admins("has allowed [H] to change \his appearance, without whitelisting of races.")
+ log_and_message_admins("has allowed [H] to change \his appearance, without whitelisting of races.")
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 0)
if("No")
- admin_log_and_message_admins("has allowed [H] to change \his appearance, with whitelisting of races.")
+ log_and_message_admins("has allowed [H] to change \his appearance, with whitelisting of races.")
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1)
feedback_add_details("admin_verb","CMAS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/verbs/icarus.dm b/code/modules/admin/verbs/icarus.dm
index ef322d40dd..6711c846fc 100644
--- a/code/modules/admin/verbs/icarus.dm
+++ b/code/modules/admin/verbs/icarus.dm
@@ -4,7 +4,7 @@
set category = "Fun"
var/turf/target = get_turf(src.mob)
- admin_log_and_message_admins("has fired the Icarus point defense laser at [target.x]-[target.y]-[target.z]")
+ log_and_message_admins("has fired the Icarus point defense laser at [target.x]-[target.y]-[target.z]")
if(!src.holder)
src << "Only administrators may use this command."
return
@@ -18,7 +18,7 @@
set category = "Fun"
var/turf/target = get_turf(src.mob)
- admin_log_and_message_admins("has fired the Icarus main gun projectile at [target.x]-[target.y]-[target.z]")
+ log_and_message_admins("has fired the Icarus main gun projectile at [target.x]-[target.y]-[target.z]")
if(!src.holder)
src << "Only administrators may use this command."
return
@@ -31,7 +31,7 @@
set desc = "Lets you chose the position of the Icarus in regards to the map."
set category = "Fun"
- admin_log_and_message_admins("is changing the Icarus position.")
+ log_and_message_admins("is changing the Icarus position.")
if(!src.holder)
src << "Only administrators may use this command."
return
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 5534997731..0f3877ea66 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -447,7 +447,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
data_core.manifest_inject(new_character)
if(alert(new_character,"Would you like an active AI to announce this character?",,"No","Yes")=="Yes")
- call(/mob/new_player/proc/AnnounceArrival)(new_character, new_character.mind.assigned_role)
+ call(/proc/AnnounceArrival)(new_character, new_character.mind.assigned_role)
message_admins("\blue [admin] has respawned [player_key] as [new_character.real_name].", 1)
diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm
index b6415f22b5..6cd91f07ef 100644
--- a/code/modules/awaymissions/corpse.dm
+++ b/code/modules/awaymissions/corpse.dm
@@ -59,7 +59,6 @@
M.equip_to_slot_or_del(new src.corpseback(M), slot_back)
if(src.corpseid == 1)
var/obj/item/weapon/card/id/W = new(M)
- W.name = "[M.real_name]'s ID Card"
var/datum/job/jobdatum
for(var/jobtype in typesof(/datum/job))
var/datum/job/J = new jobtype
@@ -75,7 +74,7 @@
W.access = list()
if(corpseidjob)
W.assignment = corpseidjob
- W.registered_name = M.real_name
+ W.set_owner_info(M)
M.equip_to_slot_or_del(W, slot_wear_id)
qdel(src)
diff --git a/code/modules/detectivework/scanning_console.dm b/code/modules/detectivework/scanning_console.dm
index 0bafc88d9c..25658a06f0 100644
--- a/code/modules/detectivework/scanning_console.dm
+++ b/code/modules/detectivework/scanning_console.dm
@@ -1,6 +1,7 @@
/obj/machinery/computer/forensic_scanning
name = "high-res forensic scanning computer"
- icon_state = "forensic"
+ icon_keyboard = "security_key"
+ icon_screen = "forensic"
var/screen = "database"
var/authenticated = 0
diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm
index 0b1b1dbbfd..c478a28daa 100644
--- a/code/modules/events/blob.dm
+++ b/code/modules/events/blob.dm
@@ -4,10 +4,8 @@
var/obj/effect/blob/core/Blob
-
/datum/event/blob/announce()
- command_announcement.Announce("Confirmed outbreak of level 7 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg')
-
+ level_seven_announcement()
/datum/event/blob/start()
var/turf/T = pick(blobstart)
@@ -18,10 +16,9 @@
for(var/i = 1; i < rand(3, 4), i++)
Blob.process()
-
/datum/event/blob/tick()
if(!Blob)
kill()
return
if(IsMultiple(activeFor, 3))
- Blob.process()
\ No newline at end of file
+ Blob.process()
diff --git a/code/modules/events/event.dm b/code/modules/events/event.dm
index 0b69dc89bb..4912b238c8 100644
--- a/code/modules/events/event.dm
+++ b/code/modules/events/event.dm
@@ -5,11 +5,12 @@
var/min_weight = 0 // The minimum weight that this event will have. Only used if non-zero.
var/max_weight = 0 // The maximum weight that this event will have. Only use if non-zero.
var/severity = 0 // The current severity of this event
- var/one_shot = 0 //If true, then the event will not be re-added to the list of available events
+ var/one_shot = 0 // If true, then the event will not be re-added to the list of available events
+ var/add_to_queue= 1 // If true, add back to the queue of events upon finishing.
var/list/role_weights = list()
var/datum/event/event_type
-/datum/event_meta/New(var/event_severity, var/event_name, var/datum/event/type, var/event_weight, var/list/job_weights, var/is_one_shot = 0, var/min_event_weight = 0, var/max_event_weight = 0)
+/datum/event_meta/New(var/event_severity, var/event_name, var/datum/event/type, var/event_weight, var/list/job_weights, var/is_one_shot = 0, var/min_event_weight = 0, var/max_event_weight = 0, var/add_to_queue = 1)
name = event_name
severity = event_severity
event_type = type
@@ -17,6 +18,7 @@
weight = event_weight
min_weight = min_event_weight
max_weight = max_event_weight
+ src.add_to_queue = add_to_queue
if(job_weights)
role_weights = job_weights
diff --git a/code/modules/events/event_manager.dm b/code/modules/events/event_manager.dm
index d5b38f087b..4fca5eb3d9 100644
--- a/code/modules/events/event_manager.dm
+++ b/code/modules/events/event_manager.dm
@@ -41,7 +41,8 @@
// Add the event back to the list of available events
var/datum/event_container/EC = event_containers[E.severity]
var/datum/event_meta/EM = E.event_meta
- EC.available_events += EM
+ if(EM.add_to_queue)
+ EC.available_events += EM
log_debug("Event '[EM.name]' has completed at [worldtime2text()].")
@@ -193,41 +194,41 @@
if(href_list["toggle_report"])
report_at_round_end = !report_at_round_end
- admin_log_and_message_admins("has [report_at_round_end ? "enabled" : "disabled"] the round end event report.")
+ log_and_message_admins("has [report_at_round_end ? "enabled" : "disabled"] the round end event report.")
else if(href_list["dec_timer"])
var/datum/event_container/EC = locate(href_list["event"])
var/decrease = 60 * (10 ** text2num(href_list["dec_timer"]))
EC.next_event_time -= decrease
- admin_log_and_message_admins("decreased timer for [severity_to_string[EC.severity]] events by [decrease/600] minute(s).")
+ log_and_message_admins("decreased timer for [severity_to_string[EC.severity]] events by [decrease/600] minute(s).")
else if(href_list["inc_timer"])
var/datum/event_container/EC = locate(href_list["event"])
var/increase = 60 * (10 ** text2num(href_list["inc_timer"]))
EC.next_event_time += increase
- admin_log_and_message_admins("increased timer for [severity_to_string[EC.severity]] events by [increase/600] minute(s).")
+ log_and_message_admins("increased timer for [severity_to_string[EC.severity]] events by [increase/600] minute(s).")
else if(href_list["select_event"])
var/datum/event_container/EC = locate(href_list["select_event"])
var/datum/event_meta/EM = EC.SelectEvent()
if(EM)
- admin_log_and_message_admins("has queued the [severity_to_string[EC.severity]] event '[EM.name]'.")
+ log_and_message_admins("has queued the [severity_to_string[EC.severity]] event '[EM.name]'.")
else if(href_list["pause"])
var/datum/event_container/EC = locate(href_list["pause"])
EC.delayed = !EC.delayed
- admin_log_and_message_admins("has [EC.delayed ? "paused" : "resumed"] countdown for [severity_to_string[EC.severity]] events.")
+ log_and_message_admins("has [EC.delayed ? "paused" : "resumed"] countdown for [severity_to_string[EC.severity]] events.")
else if(href_list["pause_all"])
config.allow_random_events = text2num(href_list["pause_all"])
- admin_log_and_message_admins("has [config.allow_random_events ? "resumed" : "paused"] countdown for all events.")
+ log_and_message_admins("has [config.allow_random_events ? "resumed" : "paused"] countdown for all events.")
else if(href_list["interval"])
var/delay = input("Enter delay modifier. A value less than one means events fire more often, higher than one less often.", "Set Interval Modifier") as num|null
if(delay && delay > 0)
var/datum/event_container/EC = locate(href_list["interval"])
EC.delay_modifier = delay
- admin_log_and_message_admins("has set the interval modifier for [severity_to_string[EC.severity]] events to [EC.delay_modifier].")
+ log_and_message_admins("has set the interval modifier for [severity_to_string[EC.severity]] events to [EC.delay_modifier].")
else if(href_list["stop"])
if(alert("Stopping an event may have unintended side-effects. Continue?","Stopping Event!","Yes","No") != "Yes")
return
var/datum/event/E = locate(href_list["stop"])
var/datum/event_meta/EM = E.event_meta
- admin_log_and_message_admins("has stopped the [severity_to_string[EM.severity]] event '[EM.name]'.")
+ log_and_message_admins("has stopped the [severity_to_string[EM.severity]] event '[EM.name]'.")
E.kill()
else if(href_list["view_events"])
selected_event_container = locate(href_list["view_events"])
@@ -249,23 +250,23 @@
var/datum/event_meta/EM = locate(href_list["set_weight"])
EM.weight = weight
if(EM != new_event)
- admin_log_and_message_admins("has changed the weight of the [severity_to_string[EM.severity]] event '[EM.name]' to [EM.weight].")
+ log_and_message_admins("has changed the weight of the [severity_to_string[EM.severity]] event '[EM.name]' to [EM.weight].")
else if(href_list["toggle_oneshot"])
var/datum/event_meta/EM = locate(href_list["toggle_oneshot"])
EM.one_shot = !EM.one_shot
if(EM != new_event)
- admin_log_and_message_admins("has [EM.one_shot ? "set" : "unset"] the oneshot flag for the [severity_to_string[EM.severity]] event '[EM.name]'.")
+ log_and_message_admins("has [EM.one_shot ? "set" : "unset"] the oneshot flag for the [severity_to_string[EM.severity]] event '[EM.name]'.")
else if(href_list["toggle_enabled"])
var/datum/event_meta/EM = locate(href_list["toggle_enabled"])
EM.enabled = !EM.enabled
- admin_log_and_message_admins("has [EM.enabled ? "enabled" : "disabled"] the [severity_to_string[EM.severity]] event '[EM.name]'.")
+ log_and_message_admins("has [EM.enabled ? "enabled" : "disabled"] the [severity_to_string[EM.severity]] event '[EM.name]'.")
else if(href_list["remove"])
if(alert("This will remove the event from rotation. Continue?","Removing Event!","Yes","No") != "Yes")
return
var/datum/event_meta/EM = locate(href_list["remove"])
var/datum/event_container/EC = locate(href_list["EC"])
EC.available_events -= EM
- admin_log_and_message_admins("has removed the [severity_to_string[EM.severity]] event '[EM.name]'.")
+ log_and_message_admins("has removed the [severity_to_string[EM.severity]] event '[EM.name]'.")
else if(href_list["add"])
if(!new_event.name || !new_event.event_type)
return
@@ -273,12 +274,12 @@
return
new_event.severity = selected_event_container.severity
selected_event_container.available_events += new_event
- admin_log_and_message_admins("has added \a [severity_to_string[new_event.severity]] event '[new_event.name]' of type [new_event.event_type] with weight [new_event.weight].")
+ log_and_message_admins("has added \a [severity_to_string[new_event.severity]] event '[new_event.name]' of type [new_event.event_type] with weight [new_event.weight].")
new_event = new
else if(href_list["clear"])
var/datum/event_container/EC = locate(href_list["clear"])
if(EC.next_event)
- admin_log_and_message_admins("has dequeued the [severity_to_string[EC.severity]] event '[EC.next_event.name]'.")
+ log_and_message_admins("has dequeued the [severity_to_string[EC.severity]] event '[EC.next_event.name]'.")
EC.next_event = null
Interact(usr)
diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm
index f9da977f33..222a0c4f64 100644
--- a/code/modules/events/ion_storm.dm
+++ b/code/modules/events/ion_storm.dm
@@ -95,7 +95,7 @@
/datum/event/ionstorm/end()
spawn(rand(5000,8000))
if(prob(50))
- command_announcement.Announce("It has come to our attention that the station passed through an ion storm. Please monitor all electronic equipment for malfunctions.", "Anomaly Alert")
+ ion_storm_announcement()
/*
/proc/IonStorm(botEmagChance = 10)
diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm
index 12ec133478..7be0a5c3d2 100644
--- a/code/modules/events/radiation_storm.dm
+++ b/code/modules/events/radiation_storm.dm
@@ -3,6 +3,7 @@
var/const/radIntervall = 5 // Enough time between enter/leave belt for 10 hits, as per original implementation
var/const/leaveBelt = 80
var/const/revokeAccess = 135
+ startWhen = 2
announceWhen = 1
endWhen = revokeAccess
var/postStartTicks = 0
@@ -52,3 +53,6 @@
/datum/event/radiation_storm/end()
revoke_maint_all_access()
+
+/datum/event/radiation_storm/syndicate/radiate()
+ return
diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm
index cf00e4f78b..fef2e3f6b1 100644
--- a/code/modules/events/spacevine.dm
+++ b/code/modules/events/spacevine.dm
@@ -1,11 +1,11 @@
/var/global/spacevines_spawned = 0
/datum/event/spacevine
- announceWhen = 10
+ announceWhen = 60
/datum/event/spacevine/start()
spacevine_infestation()
spacevines_spawned = 1
/datum/event/spacevine/announce()
- command_announcement.Announce("Confirmed outbreak of level 7 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg')
+ level_seven_announcement()
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index dbd0e77197..b1f80ee820 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -27,8 +27,8 @@
..()
-/client/proc/client_dir(input)
- return turn(input, -dir2angle(dir))
+/client/proc/client_dir(input, direction=-1)
+ return turn(input, direction*dir2angle(dir))
/client/Northeast()
diagonal_action(NORTHEAST)
@@ -40,7 +40,7 @@
diagonal_action(SOUTHWEST)
/client/proc/diagonal_action(direction)
- switch(client_dir(direction))
+ switch(client_dir(direction, 1))
if(NORTHEAST)
swap_hand()
return
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 72b3fe23ec..2e8189db66 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -368,12 +368,6 @@
qdel(src)
- proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank, var/join_message)
- if (ticker.current_state == GAME_STATE_PLAYING)
- if(character.mind.role_alt_title)
- rank = character.mind.role_alt_title
- global_announcer.autosay("[character.real_name],[rank ? " [rank]," : " visitor," ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer")
-
proc/AnnounceCyborg(var/mob/living/character, var/rank, var/join_message)
if (ticker.current_state == GAME_STATE_PLAYING)
if(character.mind.role_alt_title)
diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm
index 4486a0fb82..574d5d0931 100644
--- a/code/modules/nano/modules/human_appearance.dm
+++ b/code/modules/nano/modules/human_appearance.dm
@@ -17,7 +17,7 @@
src.whitelist = species_whitelist
src.blacklist = species_blacklist
-/datum/nano_module/appearance_changer/Topic(ref, href_list, var/nowindow, var/datum/topic_state/state = default_state)
+/datum/nano_module/appearance_changer/Topic(ref, href_list, var/datum/topic_state/state = default_state)
if(..())
return 1
diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm
index 9108f23e62..4c61718fff 100644
--- a/code/modules/nano/nanoui.dm
+++ b/code/modules/nano/nanoui.dm
@@ -479,7 +479,7 @@ nanoui is used to open and update nano browser uis
set_map_z_level(text2num(href_list["mapZLevel"]))
map_update = 1
- if ((src_object && src_object.Topic(href, href_list, 0, state)) || map_update)
+ if ((src_object && src_object.Topic(href, href_list, state)) || map_update)
nanomanager.update_uis(src_object) // update all UIs attached to src_object
/**
diff --git a/code/modules/overmap/ships/computers/engine_control.dm b/code/modules/overmap/ships/computers/engine_control.dm
index 933969a91b..49b0f190b6 100644
--- a/code/modules/overmap/ships/computers/engine_control.dm
+++ b/code/modules/overmap/ships/computers/engine_control.dm
@@ -2,7 +2,8 @@
/obj/machinery/computer/engines
name = "engine control console"
- icon_state = "id"
+ icon_keyboard = "tech_key"
+ icon_screen = "id"
var/state = "status"
var/list/engines = list()
var/obj/effect/map/ship/linked
diff --git a/code/modules/overmap/ships/computers/helm.dm b/code/modules/overmap/ships/computers/helm.dm
index e15de31969..b92eebbc7e 100644
--- a/code/modules/overmap/ships/computers/helm.dm
+++ b/code/modules/overmap/ships/computers/helm.dm
@@ -1,6 +1,7 @@
/obj/machinery/computer/helm
name = "helm control console"
- icon_state = "id"
+ icon_keyboard = "med_key"
+ icon_screen = "id"
var/state = "status"
var/obj/effect/map/ship/linked //connected overmap object
var/autopilot = 0
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index 9f6d1e1383..f9f1533624 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -851,7 +851,7 @@
return 0
return 1
-/obj/machinery/power/apc/Topic(href, href_list, var/nowindow = 0)
+/obj/machinery/power/apc/Topic(href, href_list)
if(..())
return 1
diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm
index 0119de8308..997b695a20 100644
--- a/code/modules/power/turbine.dm
+++ b/code/modules/power/turbine.dm
@@ -29,7 +29,8 @@
name = "Gas turbine control computer"
desc = "A computer to remotely control a gas turbine"
icon = 'icons/obj/computer.dmi'
- icon_state = "turbinecomp"
+ icon_keyboard = "tech_key"
+ icon_screen = "turbinecomp"
circuit = /obj/item/weapon/circuitboard/turbine_control
anchored = 1
density = 1
diff --git a/code/modules/virus2/curer.dm b/code/modules/virus2/curer.dm
index ccbbbed9a2..a316663a37 100644
--- a/code/modules/virus2/curer.dm
+++ b/code/modules/virus2/curer.dm
@@ -1,7 +1,8 @@
/obj/machinery/computer/curer
name = "cure research machine"
icon = 'icons/obj/computer.dmi'
- icon_state = "dna"
+ icon_keyboard = "med_key"
+ icon_screen = "dna"
circuit = /obj/item/weapon/circuitboard/curefab
var/curing
var/virusing
diff --git a/html/changelogs/PsiOmegaDelta-Uplinkery.yml b/html/changelogs/PsiOmegaDelta-Uplinkery.yml
new file mode 100644
index 0000000000..c8b8f5e31c
--- /dev/null
+++ b/html/changelogs/PsiOmegaDelta-Uplinkery.yml
@@ -0,0 +1,10 @@
+author: PsiOmegaDelta
+delete-after: true
+changes:
+ - rscadd: "When examined up close id cards now offer a more detailed view."
+ - rscadd: "Agent ids now offer much greater customization, such as being able to toggle termination of AI tracking."
+ - rscadd: "Uplink menu now more organized and with new categories."
+ - rscadd: "Now possible to cause falsified ion storm announcements."
+ - rscadd: "Now possible to cause falsified radiation storm announcements, with expected maintenance access changes."
+ - rscadd: "Now possible for mercenaries to create falsified Central Command Update messages."
+ - rscadd: "Now possible for mercenaries to create falsified crew arrival messages and records."
diff --git a/nano/templates/agent_id_card.tmpl b/nano/templates/agent_id_card.tmpl
new file mode 100644
index 0000000000..7a41dcdf1b
--- /dev/null
+++ b/nano/templates/agent_id_card.tmpl
@@ -0,0 +1,21 @@
+
+{{:helper.syndicateMode()}}
+Available Entries
+
+{{for data.entries}}
+
+ | {{:helper.link('', 'gear', {'set' : value.name})}} | {{:value.name}} | {{:value.value}} |
+
+{{/for}}
+
+
+
+
+ | Electronic warfare: |
+ {{:helper.link('Enabled', null, {'electronic_warfare' : 1}, data.electronic_warfare ? 'selected' : null)}} |
+ {{:helper.link('Disabled',null, {'electronic_warfare' : 0}, data.electronic_warfare ? null : 'selected')}} |
+
+