diff --git a/code/defines/mob/living/living.dm b/code/defines/mob/living/living.dm
index d4709674483..8e6d241673a 100644
--- a/code/defines/mob/living/living.dm
+++ b/code/defines/mob/living/living.dm
@@ -5,3 +5,4 @@
var/t_n2 = null
var/now_pushing = null
var/cameraFollow = null
+ var/tod = null // Time of death
diff --git a/code/defines/mob/living/silicon/ai.dm b/code/defines/mob/living/silicon/ai.dm
index e9fc9c75502..c916c51a904 100644
--- a/code/defines/mob/living/silicon/ai.dm
+++ b/code/defines/mob/living/silicon/ai.dm
@@ -15,6 +15,7 @@
var/lawcheck[1]
var/ioncheck[1]
var/icon/holo_icon//Default is assigned when AI is created.
+ var/obj/item/device/pda/ai/aiPDA = null
//MALFUNCTION
var/datum/AI_Module/module_picker/malf_picker
diff --git a/code/defines/procs/helpers.dm b/code/defines/procs/helpers.dm
index 4be223c0988..8107839b324 100644
--- a/code/defines/procs/helpers.dm
+++ b/code/defines/procs/helpers.dm
@@ -246,6 +246,29 @@
/proc/capitalize(var/t as text)
return uppertext(copytext(t, 1, 2)) + copytext(t, 2)
+/proc/sortRecord(var/list/datum/data/record/L, var/field = "name", var/order = 1)
+ if(L.len < 2)
+ return L
+ var/middle = L.len / 2 + 1
+ return mergeRecordLists(sortRecord(L.Copy(0, middle), field, order), sortRecord(L.Copy(middle), field, order), field, order)
+
+
+/proc/mergeRecordLists(var/list/datum/data/record/L, var/list/datum/data/record/R, var/field = "name", var/order = 1)
+ var/Li=1
+ var/Ri=1
+ var/list/result = new()
+ while(Li <= L.len && Ri <= R.len)
+ var/datum/data/record/rL = L[Li]
+ var/datum/data/record/rR = R[Ri]
+ if(sorttext(rL.fields[field], rR.fields[field]) == order)
+ result += L[Li++]
+ else
+ result += R[Ri++]
+
+ if(Li <= L.len)
+ return (result + L.Copy(Li, 0))
+ return (result + R.Copy(Ri, 0))
+
/proc/sortList(var/list/L)
if(L.len < 2)
return L
@@ -1846,3 +1869,6 @@ proc/get_mob_with_client_list()
if (M.client)
mobs += M
return mobs
+
+proc/worldtime2text()
+ return "[round(world.time / 36000)+12]:[(world.time / 600 % 60) < 10 ? add_zero(world.time / 600 % 60, 1) : world.time / 600 % 60]"
diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm
index ea5b5ead99d..9084174db6d 100644
--- a/code/game/gamemodes/changeling/changeling_powers.dm
+++ b/code/game/gamemodes/changeling/changeling_powers.dm
@@ -560,10 +560,13 @@ Tarjan shit, not recoding this -Sieve{R}*/
L.remove_changeling_powers()
L.emote("gasp")
+ if(isnull(L.tod)) // If we weren't already dead
+ L.tod = worldtime2text()
spawn(1200)
L.stat = 0
//usr.fireloss = 0
+ L.tod = null
L.setToxLoss(0)
//usr.bruteloss = 0
L.setOxyLoss(0)
diff --git a/code/game/gamemodes/events/ninja_equipment.dm b/code/game/gamemodes/events/ninja_equipment.dm
index ddbad486468..3f33707ab7e 100644
--- a/code/game/gamemodes/events/ninja_equipment.dm
+++ b/code/game/gamemodes/events/ninja_equipment.dm
@@ -255,7 +255,7 @@ ________________________________________________________________________________
else
dat += "
SpiderOS v.ERR-RR00123
"
dat += "
"
- dat += "
Current Time: [round(world.time / 36000)+12]:[(world.time / 600 % 60) < 10 ? add_zero(world.time / 600 % 60, 1) : world.time / 600 % 60]
"
+ dat += "
Current Time: [worldtime2text()]
"
dat += "
Battery Life: [round(cell.charge/100)]%
"
dat += "
Smoke Bombs: \Roman [s_bombs]
"
dat += "
pai Device: "
diff --git a/code/game/machinery/camera.dm b/code/game/machinery/camera.dm
index 0a5e693731a..e6f458cbeee 100644
--- a/code/game/machinery/camera.dm
+++ b/code/game/machinery/camera.dm
@@ -77,6 +77,8 @@
creatures[name] = M
+ creatures = sortList(creatures)
+
var/target_name = input(usr, "Which creature should you track?") as null|anything in creatures
if (!target_name)
diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm
index a1c1c6d1a33..1415497fbaf 100644
--- a/code/game/machinery/computer/card.dm
+++ b/code/game/machinery/computer/card.dm
@@ -52,9 +52,13 @@
return
if (mode) // accessing crew manifest
var/crew = ""
- for(var/datum/data/record/t in data_core.general)
- crew += "[t.fields["name"]] - [t.fields["rank"]]
"
- dat = "Crew Manifest:
Please use security record computer to modify entries.
[crew]Print
Access ID modification console.
"
+ var/list/L = list()
+ for (var/datum/data/record/t in data_core.general)
+ var/R = t.fields["name"] + " - " + t.fields["rank"]
+ L += R
+ for(var/R in sortList(L))
+ crew += "[R]
"
+ dat = "Crew Manifest:
Please use security record computer to modify entries.
[crew]Print
Access ID modification console.
"
else
var/header = "Identification Card Modifier
"
@@ -248,8 +252,12 @@
sleep(50)
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( loc )
var/t1 = "Crew Manifest:
"
- for(var/datum/data/record/t in data_core.general)
- t1 += "[t.fields["name"]] - [t.fields["rank"]]
"
+ var/list/L = list()
+ for (var/datum/data/record/t in data_core.general)
+ var/R = t.fields["name"] + " - " + t.fields["rank"]
+ L += R
+ for(var/R in sortList(L))
+ t1 += "[R]
"
P.info = t1
P.name = "paper- 'Crew Manifest'"
printing = null
diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm
index 2b6d0c627a6..d1646749e77 100644
--- a/code/game/machinery/computer/crew.dm
+++ b/code/game/machinery/computer/crew.dm
@@ -67,7 +67,9 @@
t += "
Refresh"
t += "
Close"
t += "| Name | Vitals | Position |
"
+ var/list/logs = list()
for(var/obj/item/clothing/under/C in src.tracked)
+ var/log = ""
if((C) && (C.has_sensor) && (C.loc) && (C.loc.z == 1) && C.sensor_mode)
if(istype(C.loc, /mob/living/carbon/human))
var/mob/living/carbon/human/H = C.loc
@@ -77,16 +79,20 @@
var/dam4 = round(H.getBruteLoss(),1)
if(H.wear_id)
- t += "| [H.wear_id.name] | "
+ log += "
| [H.wear_id.name] | "
else
- t += "
| Unknown: | "
+ log += "
| Unknown: | "
switch(C.sensor_mode)
if(1)
- t+= "[H.stat > 1 ? "Deceased" : "Living"] | Not Available |
"
+ log+= "[H.stat > 1 ? "Deceased" : "Living"] | Not Available | "
if(2)
- t += "[H.stat > 1 ? "Deceased" : "Living"], [dam1] - [dam2] - [dam3] - [dam4] | Not Available | "
+ log += "[H.stat > 1 ? "Deceased" : "Living"], [dam1] - [dam2] - [dam3] - [dam4] | Not Available | "
if(3)
- t += "[H.stat > 1 ? "Deceased" : "Living"], [dam2] - [dam2] - [dam3] - [dam4] | [get_area(H)] ([H.x], [H.y]) | "
+ log+= "[H.stat > 1 ? "Deceased" : "Living"], [dam2] - [dam2] - [dam3] - [dam4] | [get_area(H)] ([H.x], [H.y]) | "
+ logs += log
+ logs = sortList(logs)
+ for(var/log in logs)
+ t += log
t += "
"
t += ""
user << browse(t, "window=crewcomp;size=900x600")
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index 2aa4ccbb4ae..828a55d1f1f 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -45,7 +45,7 @@
"}
if(2.0)
dat += "Record List:
"
- for(var/datum/data/record/R in data_core.general)
+ for(var/datum/data/record/R in sortRecord(data_core.general))
dat += text("[]: []
", src, R, R.fields["id"], R.fields["name"])
//Foreach goto(132)
dat += text("
Back", src)
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index 5eaa46470d5..a77d9ed4779 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -18,6 +18,9 @@
var/can_change_id = 0
var/list/Perp
var/tempname = null
+ //Sorting Variables
+ var/sortBy = "name"
+ var/order = 1 // -1 = Descending - 1 = Ascending
/obj/machinery/computer/secure_data/attackby(obj/item/O as obj, user as mob)
@@ -60,13 +63,13 @@
-| Name |
-ID |
-Rank |
-Fingerprints |
+Name |
+ID |
+Rank |
+Fingerprints |
Criminal Status |
"}
- for(var/datum/data/record/R in data_core.general)
+ for(var/datum/data/record/R in sortRecord(data_core.general, sortBy, order))
var/crimstat = ""
for(var/datum/data/record/E in data_core.security)
if ((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"]))
@@ -182,6 +185,18 @@ What a mess.*/
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon)))
usr.machine = src
switch(href_list["choice"])
+// SORTING!
+ if("Sorting")
+ // Reverse the order if clicked twice
+ if(sortBy == href_list["sort"])
+ if(order == 1)
+ order = -1
+ else
+ order = 1
+ else
+ // New sorting order!
+ sortBy = href_list["sort"]
+ order = initial(order)
//BASIC FUNCTIONS
if("Clear Screen")
temp = null
@@ -502,6 +517,7 @@ What a mess.*/
del(active2)
else
temp = "This function does not appear to be working at the moment. Our apologies."
+
add_fingerprint(usr)
updateUsrDialog()
return
diff --git a/code/game/objects/devices/PDA/PDA.dm b/code/game/objects/devices/PDA/PDA.dm
index e4e4902cdcf..aff5cfdf240 100644
--- a/code/game/objects/devices/PDA/PDA.dm
+++ b/code/game/objects/devices/PDA/PDA.dm
@@ -171,6 +171,17 @@ var/global/list/obj/item/device/pda/PDAs = list()
default_cartridge = /obj/item/weapon/cartridge/medical
icon_state = "pda-gene"
+// Special AI PDA that cannot explode.
+/obj/item/device/pda/ai
+ icon_state = "NONE"
+ ttone = "data"
+
+/obj/item/device/pda/ai/attack_self(mob/user as mob)
+ if ((honkamt > 0) && (prob(60)))//For clown virus.
+ honkamt--
+ playsound(loc, 'bikehorn.ogg', 30, 1)
+ return
+
/*
* The Actual PDA
*/
@@ -196,15 +207,14 @@ var/global/list/obj/item/device/pda/PDAs = list()
return 0
var/mob/M = loc
- if(!M.canmove)
+ if(!M.canmove && !isAI(M))
return 0
- if((src in M.contents) || ( istype(loc, /turf) && in_range(src, M) ) )
+ if((src in M.contents) || ( istype(loc, /turf) && in_range(src, M) ))
return 1
else
return 0
-
/obj/item/device/pda/MouseDrop(obj/over_object as obj, src_location, over_location)
var/mob/M = usr
if((!istype(over_object, /obj/screen)) && !M.restrained() && !M.stat && can_use())
@@ -213,6 +223,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
//NOTE: graphic resources are loaded on client login
/obj/item/device/pda/attack_self(mob/user as mob)
+
user.machine = src
var/dat = "Personal Data Assistant"
@@ -238,7 +249,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
dat += text("ID: [id ? "[id.registered_name], [id.assignment]" : "----------"]")
dat += text("
[id ? "Update PDA Info" : ""]
")
- dat += "Station Time: [round(world.time / 36000)+12]:[(world.time / 600 % 60) < 10 ? add_zero(world.time / 600 % 60, 1) : world.time / 600 % 60]"//:[world.time / 100 % 6][world.time / 100 % 10]"
+ dat += "Station Time: [worldtime2text()]"//:[world.time / 100 % 6][world.time / 100 % 10]"
dat += "
"
@@ -339,7 +350,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
for (var/obj/item/device/pda/P in PDAs)
if (!P.owner||P.toff||P == src) continue
dat += "[P]"
- if (istype(cartridge, /obj/item/weapon/cartridge/syndicate))
+ if (istype(cartridge, /obj/item/weapon/cartridge/syndicate) && !istype(P, /obj/item/device/pda/ai))
dat += " (
*Detonate*)"
if (istype(cartridge, /obj/item/weapon/cartridge/clown))
dat += " (
*Send Virus*)"
@@ -544,94 +555,8 @@ var/global/list/obj/item/device/pda/PDAs = list()
U << browse(null, "window=pda")
return
if("Message")
- var/t = input(U, "Please enter message", name, null) as text
- t = copytext(sanitize(t), 1, MAX_MESSAGE_LEN)
- if (!t)
- return
- if (!in_range(src, U) && loc != U)
- return
var/obj/item/device/pda/P = locate(href_list["target"])
- if(!istype(P)) return
-
- if(istype(P, /obj/item/device/pda))
- if (isnull(P)||P.toff || toff)
- return
-
- if (last_text && world.time < last_text + 5)
- return
-
- last_text = world.time
- // check if telecomms I/O route 1459 is stable
- //var/telecomms_intact = telecomms_process(P.owner, owner, t)
- var/obj/machinery/message_server/useMS = null
- if(message_servers)
- for (var/obj/machinery/message_server/MS in message_servers)
- //PDAs are now dependant on the Message Server.
- if(MS.active)
- useMS = MS
- break
- if(useMS) // only send the message if it's stable
- useMS.send_pda_message("[P.owner]","[owner]","[t]")
-
- tnote += "→ To [P.owner]:
[t]
"
- P.tnote += "← From [owner] ([ownjob]):
[t]
"
-
- if (prob(15)) //Give the AI a chance of intercepting the message
- var/who = src.owner
- if(prob(50))
- who = P:owner
- for(var/mob/living/silicon/ai/ai in world)
- ai.show_message("Intercepted message from [who]: [t]")
-
- if (!P.silent)
- playsound(P.loc, 'twobeep.ogg', 50, 1)
- for (var/mob/O in hearers(3, P.loc))
- O.show_message(text("\icon[P] *[P.ttone]*"))
- if( P.loc && ishuman(P.loc) )
- var/mob/living/carbon/human/H = P.loc
- H << "\icon[P] Message from [src.owner] ([ownjob]), \"[t]\" (Reply)"
- log_pda("[usr] (PDA: [src.name]) sent \"[t]\" to [P.name]")
- P.overlays = null
- P.overlays += image('pda.dmi', "pda-r")
- else
- U << "ERROR: Server isn't responding."
-
- // pAI Message
- else
-
- //var/telecomms_intact = telecomms_process(P.owner, owner, t)
- var/obj/machinery/message_server/useMS = null
- if(message_servers)
- for (var/obj/machinery/message_server/MS in message_servers)
- //PDAs are now dependant on the Message Server.
- if(MS.active)
- useMS = MS
- break
- if(useMS) // only send the message if it's stable
- useMS.send_pda_message("[P.owner]","[owner]","[t]")
- tnote += "→ To [P]:
[t]
"
- P.tnote += "← From [src]:
[t]
"
-
-
- if (prob(15)) //Give the AI a chance of intercepting the message
- var/who = src
- if(prob(50))
- who = P
- for (var/mob/living/silicon/ai/ai in world)
- ai.show_message("Intercepted message from [who]: [t]")
-
- if (!P.silent)
- playsound(P.loc, 'twobeep.ogg', 50, 1)
- for (var/mob/O in hearers(3, P.loc))
- O.show_message(text("\icon[P] *[P.ttone]*"))
- if( P.loc && ishuman(P.loc) )
- var/mob/living/carbon/human/H = P.loc
- H << "\icon[P] Message from [src.owner] ([ownjob]), \"[t]\" (Reply)"
- log_pda("[usr] (PDA: [src.name]) sent \"[t]\" to [P.name]")
- else
- U << "ERROR: Server isn't responding."
-
-
+ src.create_message(U, P)
if("Send Honk")//Honk virus
if(istype(cartridge, /obj/item/weapon/cartridge/clown))//Cartridge checks are kind of unnecessary since everything is done through switch.
@@ -678,6 +603,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
if(uplink)
uplink.active = 0
note = uplink.orignote
+ mode = 0 // To stop people metagaming that PDAs on the note screen means it is an uplink PDA.
if("Detonate")//Detonate PDA
if(istype(cartridge, /obj/item/weapon/cartridge/syndicate))
var/obj/item/device/pda/P = locate(href_list["target"])
@@ -794,6 +720,99 @@ var/global/list/obj/item/device/pda/PDAs = list()
return telecomms_intact
+/obj/item/device/pda/proc/create_message(var/mob/living/U = usr, var/obj/item/device/pda/P)
+
+ var/t = input(U, "Please enter message", name, null) as text
+ t = copytext(sanitize(t), 1, MAX_MESSAGE_LEN)
+ if (!t)
+ return
+ if (!in_range(src, U) && loc != U)
+ return
+
+ if(!istype(P)) return
+
+ if(istype(P, /obj/item/device/pda))
+ if (isnull(P)||P.toff || toff)
+ return
+
+ if (last_text && world.time < last_text + 5)
+ return
+
+ last_text = world.time
+ // check if telecomms I/O route 1459 is stable
+ //var/telecomms_intact = telecomms_process(P.owner, owner, t)
+ var/obj/machinery/message_server/useMS = null
+ if(message_servers)
+ for (var/obj/machinery/message_server/MS in message_servers)
+ //PDAs are now dependant on the Message Server.
+ if(MS.active)
+ useMS = MS
+ break
+ if(useMS) // only send the message if it's stable
+ useMS.send_pda_message("[P.owner]","[owner]","[t]")
+
+ tnote += "→ To [P.owner]:
[t]
"
+ P.tnote += "← From [owner] ([ownjob]):
[t]
"
+
+ if (prob(15)) //Give the AI a chance of intercepting the message
+ var/who = src.owner
+ if(prob(50))
+ who = P:owner
+ for(var/mob/living/silicon/ai/ai in world)
+ // Allows other AIs to intercept the message but the AI won't intercept their own message.
+ if(ai.aiPDA != P && ai.aiPDA != src)
+ ai.show_message("Intercepted message from [who]: [t]")
+
+ if (!P.silent)
+ playsound(P.loc, 'twobeep.ogg', 50, 1)
+ for (var/mob/O in hearers(3, P.loc))
+ if(!P.silent) O.show_message(text("\icon[P] *[P.ttone]*"))
+ if( P.loc && isliving(P.loc) )
+ var/mob/living/L = P.loc
+ L << "\icon[P] Message from [src.owner] ([ownjob]), \"[t]\" (Reply)"
+
+ log_pda("[usr] (PDA: [src.name]) sent \"[t]\" to [P.name]")
+ P.overlays = null
+ P.overlays += image('pda.dmi', "pda-r")
+ else
+ U << "ERROR: Server isn't responding."
+
+ // pAI Message
+ else
+
+ //var/telecomms_intact = telecomms_process(P.owner, owner, t)
+ var/obj/machinery/message_server/useMS = null
+ if(message_servers)
+ for (var/obj/machinery/message_server/MS in message_servers)
+ //PDAs are now dependant on the Message Server.
+ if(MS.active)
+ useMS = MS
+ break
+ if(useMS) // only send the message if it's stable
+ useMS.send_pda_message("[P.owner]","[owner]","[t]")
+ tnote += "→ To [P]:
[t]
"
+ P.tnote += "← From [src]:
[t]
"
+
+
+ if (prob(15)) //Give the AI a chance of intercepting the message
+ var/who = src
+ if(prob(50))
+ who = P
+ for (var/mob/living/silicon/ai/ai in world)
+ // Allows other AIs to intercept the message but the AI won't intercept their own message.
+ if(ai.aiPDA != P && ai.aiPDA != src)
+ ai.show_message("Intercepted message from [who]: [t]")
+
+ if (!P.silent)
+ playsound(P.loc, 'twobeep.ogg', 50, 1)
+ for (var/mob/O in hearers(3, P.loc))
+ if(!P.silent) O.show_message(text("\icon[P] *[P.ttone]*"))
+ if( P.loc && isliving(P.loc) )
+ var/mob/living/L = P.loc
+ L << "\icon[P] Message from [src.owner] ([ownjob]), \"[t]\" (Reply)"
+ log_pda("[usr] (PDA: [src.name]) sent \"[t]\" to [P.name]")
+ else
+ U << "ERROR: Server isn't responding."
/obj/item/device/pda/verb/verb_remove_id()
set category = "Object"
@@ -904,7 +923,8 @@ var/global/list/obj/item/device/pda/PDAs = list()
user.show_message("\blue \t Damage Specifics: [C.getOxyLoss() > 50 ? "\red" : "\blue"][C.getOxyLoss()]-[C.getToxLoss() > 50 ? "\red" : "\blue"][C.getToxLoss()]-[C.getFireLoss() > 50 ? "\red" : "\blue"][C.getFireLoss()]-[C.getBruteLoss() > 50 ? "\red" : "\blue"][C.getBruteLoss()]", 1)
user.show_message("\blue \t Key: Suffocation/Toxin/Burns/Brute", 1)
user.show_message("\blue \t Body Temperature: [C.bodytemperature-T0C]°C ([C.bodytemperature*1.8-459.67]°F)", 1)
-
+ if(!isnull(C.tod) && (C.stat == 2 || (C.reagents && C.reagents.has_reagent("zombiepowder")) || (C.changeling && C.changeling.changeling_fakedeath)))
+ user.show_message("\blue \t Time of Death: [C.tod]")
if(istype(C, /mob/living/carbon/human))
var/mob/living/carbon/human/H = C
var/list/damaged = H.get_damaged_organs(1,1)
@@ -990,6 +1010,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
note = A:info
user << "\blue Paper scanned." //concept of scanning paper copyright brainoblivion 2009
+
/obj/item/device/pda/proc/explode() //This needs tuning.
var/turf/T = get_turf(src.loc)
@@ -1006,6 +1027,9 @@ var/global/list/obj/item/device/pda/PDAs = list()
del(src)
return
+/obj/item/device/pda/ai/explode()
+ return // No explosions for the AI pda!
+
/obj/item/device/pda/Del()
PDAs -= src
if (src.id)
@@ -1033,7 +1057,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
/mob/living/silicon/ai/verb/cmd_send_pdamesg()
set category = "AI Commands"
- set name = "Send PDA Message"
+ set name = "PDA - Send Message"
var/list/names = list()
var/list/plist = list()
var/list/namecounts = list()
@@ -1042,6 +1066,10 @@ var/global/list/obj/item/device/pda/PDAs = list()
usr << "You can't send PDA messages because you are dead!"
return
+ if(src.aiPDA.toff)
+ usr << "Turn on your receiver in order to send messages."
+ return
+
for (var/obj/item/device/pda/P in PDAs)
if (!P.owner)
continue
@@ -1049,6 +1077,8 @@ var/global/list/obj/item/device/pda/PDAs = list()
continue
else if (P.toff)
continue
+ else if (P == src.aiPDA)
+ continue
var/name = P.owner
if (name in names)
@@ -1060,44 +1090,52 @@ var/global/list/obj/item/device/pda/PDAs = list()
plist[text("[name]")] = P
- var/c = input(usr, "Please select a PDA") as null|anything in plist
+ var/c = input(usr, "Please select a PDA") as null|anything in sortList(plist)
if (!c)
return
var/selected = plist[c]
- ai_send_pdamesg(selected)
+ src.aiPDA.create_message(src, selected)
-/mob/living/silicon/ai/proc/ai_send_pdamesg(obj/selected as obj)
- var/t = input(usr, "Please enter message", src.name, null) as text
- t = copytext(sanitize(t), 1, MAX_MESSAGE_LEN)
- if (!t)
+
+/mob/living/silicon/ai/verb/cmd_toggle_pda_receiver()
+ set category = "AI Commands"
+ set name = "PDA - Toggle Sender/Receiver"
+ if(usr.stat == 2)
+ usr << "You can't do that because you are dead!"
return
-
- if (selected:toff)
- return
- var/obj/machinery/message_server/useMS = null
- if(!isnull(message_servers))
- for (var/obj/machinery/message_server/MS in message_servers)
- //PDAs are now dependant on the Message Server.
- if(MS.active)
- useMS = MS
- break
- if(!isnull(useMS)) // only send the message if it's stable
- useMS.send_pda_message("[selected:owner]","[usr.name]","[t]")
-
- usr.show_message("PDA message to [selected:owner]: [t]")
- selected:tnote += "← From (AI) [usr.name]:
[t]
"
-
- if (!selected:silent)
- playsound(selected.loc, 'twobeep.ogg', 50, 1)
- for (var/mob/O in hearers(3, selected.loc))
- O.show_message(text("\icon[selected] *[selected:ttone]*"))
-
- selected.overlays = null
- selected.overlays += image('pda.dmi', "pda-r")
+ if(!isnull(aiPDA))
+ aiPDA.toff = !aiPDA.toff
+ usr << "PDA sender/receiver toggled [(aiPDA.toff ? "Off" : "On")]!"
else
- usr << "ERROR: Server isn't responding."
+ usr << "You do not have a PDA. You should make an issue report about this."
+
+/mob/living/silicon/ai/verb/cmd_toggle_pda_silent()
+ set category = "AI Commands"
+ set name = "PDA - Toggle Ringer"
+ if(usr.stat == 2)
+ usr << "You can't do that because you are dead!"
+ return
+ if(!isnull(aiPDA))
+ aiPDA.silent = !aiPDA.silent
+ usr << "PDA ringer toggled [(aiPDA.silent ? "Off" : "On")]!"
+ else
+ usr << "You do not have a PDA. You should make an issue report about this."
+
+/mob/living/silicon/ai/verb/cmd_show_message_log()
+ set category = "AI Commands"
+ set name = "PDA - Show Message Log"
+ if(usr.stat == 2)
+ usr << "You can't do that because you are dead!"
+ return
+ if(!isnull(aiPDA))
+ var/HTML = "AI PDA Message Log[aiPDA.tnote]"
+ usr << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0")
+ else
+ usr << "You do not have a PDA. You should make an issue report about this."
+
+
//Some spare PDAs in a box
diff --git a/code/game/objects/devices/PDA/cart.dm b/code/game/objects/devices/PDA/cart.dm
index 2e188ff6693..643231bb193 100644
--- a/code/game/objects/devices/PDA/cart.dm
+++ b/code/game/objects/devices/PDA/cart.dm
@@ -261,7 +261,7 @@ Code:
menu = "
Crew Manifest
"
menu += "Entries cannot be modified from this terminal.
"
- for (var/datum/data/record/t in data_core.general)
+ for (var/datum/data/record/t in sortRecord(data_core.general))
menu += "[t.fields["name"]] - [t.fields["rank"]]
"
menu += "
"
@@ -335,7 +335,7 @@ Code:
if (44) //medical records //This thing only displays a single screen so it's hard to really get the sub-menu stuff working.
menu = "
Medical Record List
"
- for (var/datum/data/record/R in data_core.general)
+ for (var/datum/data/record/R in sortRecord(data_core.general))
menu += "[R.fields["id"]]: [R.fields["name"]]
"
menu += "
"
if(441)
@@ -378,7 +378,7 @@ Code:
if (45) //security records
menu = "
Security Record List
"
- for (var/datum/data/record/R in data_core.general)
+ for (var/datum/data/record/R in sortRecord(data_core.general))
menu += "[R.fields["id"]]: [R.fields["name"]]
"
menu += "
"
diff --git a/code/game/objects/devices/scanners.dm b/code/game/objects/devices/scanners.dm
index 6673546f2bd..c57e92fb3e8 100644
--- a/code/game/objects/devices/scanners.dm
+++ b/code/game/objects/devices/scanners.dm
@@ -101,7 +101,9 @@ MASS SPECTROMETER
user.show_message(text("\blue \t Damage Specifics: []-[]-[]-[]", M.getOxyLoss() > 50 ? "\red [M.getOxyLoss()]" : M.getOxyLoss(), M.getToxLoss() > 50 ? "\red [M.getToxLoss()]" : M.getToxLoss(), M.getFireLoss() > 50 ? "\red[M.getFireLoss()]" : M.getFireLoss(), M.getBruteLoss() > 50 ? "\red[M.getBruteLoss()]" : M.getBruteLoss()), 1)
user.show_message("\blue Key: Suffocation/Toxin/Burns/Brute", 1)
user.show_message("\blue Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1)
- if(mode == 1 && istype(M, /mob/living/carbon/human))
+ if(!isnull(M.tod) && (M.stat == 2 || (M.reagents && M.reagents.has_reagent("zombiepowder")) || (M.changeling && M.changeling.changeling_fakedeath)))
+ user.show_message("\blue Time of Death: [M.tod]")
+ if(istype(M, /mob/living/carbon/human) && mode == 1)
var/mob/living/carbon/human/H = M
var/list/damaged = H.get_damaged_organs(1,1)
user.show_message("\blue Localized Damage, Brute/Burn:",1)
diff --git a/code/modules/chemical/Chemistry-Reagents.dm b/code/modules/chemical/Chemistry-Reagents.dm
index 113e9fdf398..86a42679ea7 100644
--- a/code/modules/chemical/Chemistry-Reagents.dm
+++ b/code/modules/chemical/Chemistry-Reagents.dm
@@ -1481,6 +1481,7 @@ datum
M.adjustToxLoss(0.5)
M.Weaken(10)
M.silent = max(M.silent, 10)
+ M.tod = worldtime2text()
..()
return
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 8325b6c7509..ccf6540413f 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -181,7 +181,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/target = null //Chosen target.
dest += getmobs() //Fill list, prompt user with list
- target = input("Please, select a player!", "Jump to Mob", null, null) as null|anything in dest
+ target = input("Please, select a player!", "Jump to Mob", null, null) as null|anything in sortList(dest)
if (!target)//Make sure we actually have a target
return
diff --git a/code/modules/mob/living/carbon/alien/humanoid/death.dm b/code/modules/mob/living/carbon/alien/humanoid/death.dm
index 01eb6e2f257..3a48378c4c1 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/death.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/death.dm
@@ -27,7 +27,7 @@
if(src.key && src.stat == 2)
src.verbs += /mob/proc/ghost
- var/tod = time2text(world.realtime,"hh:mm:ss") //weasellos time of death patch
+ tod = worldtime2text() //weasellos time of death patch
if (mind) mind.store_memory("Time of death: [tod]", 0)
else src << "We seem to have misplaced your mind datum, so we can't add this to your memory, but you died at [tod]"
diff --git a/code/modules/mob/living/carbon/alien/larva/death.dm b/code/modules/mob/living/carbon/alien/larva/death.dm
index 86d32617808..8e2fe185497 100644
--- a/code/modules/mob/living/carbon/alien/larva/death.dm
+++ b/code/modules/mob/living/carbon/alien/larva/death.dm
@@ -26,7 +26,7 @@
src.verbs += /mob/proc/ghost
if(mind) // Skie - Added check that there's someone controlling the alien
- var/tod = time2text(world.realtime,"hh:mm:ss") //weasellos time of death patch
+ tod = worldtime2text() //weasellos time of death patch
mind.store_memory("Time of death: [tod]", 0)
return ..(gibbed)
diff --git a/code/modules/mob/living/carbon/brain/death.dm b/code/modules/mob/living/carbon/brain/death.dm
index 021ef285d97..7564ad46272 100644
--- a/code/modules/mob/living/carbon/brain/death.dm
+++ b/code/modules/mob/living/carbon/brain/death.dm
@@ -14,7 +14,7 @@
see_in_dark = 8
see_invisible = 2
- var/tod = time2text(world.realtime,"hh:mm:ss") //weasellos time of death patch
+ tod = worldtime2text() //weasellos time of death patch
store_memory("Time of death: [tod]", 0)
if (key)
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index 0a42cb9e11f..945266c4c38 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -83,7 +83,7 @@
if(client && src.stat == 2)
verbs += /mob/proc/ghost
- var/tod = time2text(world.realtime,"hh:mm:ss") //weasellos time of death patch
+ tod = worldtime2text() //weasellos time of death patch
if(mind)
mind.store_memory("Time of death: [tod]", 0)
sql_report_death(src)
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 1ee631741d0..37471dba251 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -27,6 +27,11 @@
verbs += /mob/living/silicon/ai/proc/show_laws_verb
+ aiPDA = new/obj/item/device/pda/ai(src)
+ aiPDA.owner = name
+ aiPDA.ownjob = "AI"
+ aiPDA.name = name + " (" + aiPDA.ownjob + ")"
+
if (istype(loc, /turf))
verbs.Add(/mob/living/silicon/ai/proc/ai_call_shuttle,/mob/living/silicon/ai/proc/ai_camera_track, \
/mob/living/silicon/ai/proc/ai_camera_list, /mob/living/silicon/ai/proc/ai_network_change, \
@@ -147,12 +152,14 @@
/mob/living/silicon/ai/proc/ai_roster()
set category = "AI Commands"
set name = "Show Crew Manifest"
-
var/dat = "Crew RosterCrew Roster:
"
+ var/list/L = list()
for (var/datum/data/record/t in data_core.general)
- dat += "[t.fields["name"]] - [t.fields["rank"]]
"
-
+ var/R = t.fields["name"] + " - " + t.fields["rank"]
+ L += R
+ for(var/R in sortList(L))
+ dat += "[R]
"
dat += ""
src << browse(dat, "window=airoster")
@@ -454,6 +461,8 @@
cameralist[C.network] = C.network
network = input(usr, "Which network would you like to view?") as null|anything in cameralist
+ if(isnull(network))
+ network = initial(network) // If nothing is selected, default to SS13 (or the initial network)
src << "\blue Switched to [network] camera network."
//End of code by Mord_Sith
diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm
index 79c4a7783c4..385ebfe1b6d 100644
--- a/code/modules/mob/living/silicon/ai/death.dm
+++ b/code/modules/mob/living/silicon/ai/death.dm
@@ -47,7 +47,7 @@
if (istype(loc, /obj/item/device/aicard))
loc.icon_state = "aicard-404"
- var/tod = time2text(world.realtime,"hh:mm:ss") //weasellos time of death patch
+ tod = worldtime2text() //weasellos time of death patch
if(mind) mind.store_memory("Time of death: [tod]", 0)
if (key)
diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm
index 8096b9681f3..37b0513ba5d 100644
--- a/code/modules/mob/living/silicon/ai/life.dm
+++ b/code/modules/mob/living/silicon/ai/life.dm
@@ -14,6 +14,10 @@
src.update_mind()
+ if(aiPDA && aiPDA.name != name)
+ aiPDA.owner = name
+ aiPDA.name = name + " (" + aiPDA.ownjob + ")"
+
if (src.malfhack)
if (src.malfhack.aidisabled)
src << "\red ERROR: APC access disabled, hack attempt canceled."
diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm
index ab035c15923..641a4d84b58 100644
--- a/code/modules/mob/living/silicon/pai/software.dm
+++ b/code/modules/mob/living/silicon/pai/software.dm
@@ -238,7 +238,6 @@
if(!AnsweringMS)
return alert("ERROR: No response from server!")
-
tnote += "→ To [P]:
[t]
"
P.tnote += "← From [src]:
[t]
"
@@ -443,8 +442,13 @@
/mob/living/silicon/pai/proc/softwareManifest()
var/dat = ""
dat += "Crew Manifest
"
- for (var/datum/data/record/t in data_core.general)
- dat += "[t.fields["name"]] - [t.fields["rank"]]
"
+ var/list/L = list()
+ for (var/datum/data/record/t in sortRecord(data_core.general))
+ var/R = t.fields["name"] + " - " + t.fields["rank"]
+ L += R
+ for(var/R in sortList(L))
+ dat += "[R]
"
+ dat += ""
return dat
// Medical Records
@@ -452,7 +456,7 @@
var/dat = ""
if(src.subscreen == 0)
dat += "Medical Records
"
- for(var/datum/data/record/R in data_core.general)
+ for(var/datum/data/record/R in sortRecord(data_core.general))
dat += text("[]: []
", src, R, R.fields["id"], R.fields["name"])
//dat += text("
Back", src)
if(src.subscreen == 1)
@@ -474,7 +478,7 @@
var/dat = ""
if(src.subscreen == 0)
dat += "Security Records
"
- for(var/datum/data/record/R in data_core.general)
+ for(var/datum/data/record/R in sortRecord(data_core.general))
dat += text("[]: []
", src, R, R.fields["id"], R.fields["name"])
if(src.subscreen == 1)
dat += "Security Record
"
diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm
index fefedcfe593..397a403a2b8 100644
--- a/code/modules/mob/living/silicon/robot/death.dm
+++ b/code/modules/mob/living/silicon/robot/death.dm
@@ -64,7 +64,7 @@
src.see_invisible = 2
src.updateicon()
- var/tod = time2text(world.realtime,"hh:mm:ss") //weasellos time of death patch
+ tod = worldtime2text() //weasellos time of death patch
store_memory("Time of death: [tod]", 0)
sql_report_cyborg_death(src)
diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi
index 1c23b6c25bc..ea9bd39b416 100644
Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ