diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index d4f06144..a6061fad 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -873,9 +873,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(M), slot_shoes) M.equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(M), slot_gloves) M.equip_to_slot_or_del(new /obj/item/device/radio/headset/ert(M), slot_l_ear) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_belt) - M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses/sechud(M), slot_glasses) M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M.back), slot_in_backpack) var/obj/item/weapon/card/id/W = new(M) W.name = "[M.real_name]'s ID Card" diff --git a/code/modules/admin/verbs/getlogs.dm b/code/modules/admin/verbs/getlogs.dm index ccf86ab4..114f09ec 100644 --- a/code/modules/admin/verbs/getlogs.dm +++ b/code/modules/admin/verbs/getlogs.dm @@ -109,3 +109,20 @@ usr << run( file(path) ) feedback_add_details("admin_verb","SSAL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return + +/client/proc/view_duty_log() + set category = "Special Verbs" + set name = "Get Duty Log" + set desc = "Download a log or file from an investigation" + + var/path = browse_files("data/dutylogs/") + if(!path) + return + + if(file_spam_check()) + return + + message_admins("[key_name_admin(src)] accessed file: [path]") + usr << run( file(path) ) + feedback_add_details("admin_verb","DOGL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + return \ No newline at end of file diff --git a/code/modules/aurora/duty officer.dm b/code/modules/aurora/duty officer.dm index 6ab2b1e8..2586bacc 100644 --- a/code/modules/aurora/duty officer.dm +++ b/code/modules/aurora/duty officer.dm @@ -124,7 +124,12 @@ M.equip_if_possible(new /obj/item/clothing/glasses/sunglasses/sechud(M), slot_glasses) M.equip_if_possible(new /obj/item/clothing/head/beret/centcom/officer(M), slot_head) M.equip_if_possible(new /obj/item/weapon/melee/telebaton(M), slot_l_store) - M.equip_if_possible(new /obj/item/device/taperecorder(M), slot_r_store) + M.equip_if_possible(new /obj/item/device/taperecorder/duty_officer(M), slot_r_store) + + var/obj/item/weapon/storage/backpack/satchel/bag = new(M) + bag.name = "officer's leather satchel" + bag.desc = "A well cared for leather satchel for Nanotrasen officers." + M.equip_if_possible(bag, slot_back) var /obj/item/weapon/storage/lockbox/lockbox = new(M) lockbox.req_access = list(access_cent_captain) diff --git a/code/modules/aurora/duty_officer/recorder.dm b/code/modules/aurora/duty_officer/recorder.dm new file mode 100644 index 00000000..dbf06ae3 --- /dev/null +++ b/code/modules/aurora/duty_officer/recorder.dm @@ -0,0 +1,256 @@ +/obj/item/device/taperecorder/duty_officer + desc = "A device that can record up to an hour of dialogue and play it back. It automatically translates the content in playback." + name = "universal recorder" + icon_state = "taperecorderidle" + item_state = "analyzer" + w_class = 1.0 + recording = 0 + timestamp = list() //This actually turns timestamp into a string later on + + flags = FPRINT | TABLEPASS| CONDUCT + throwforce = 2 + throw_speed = 4 + throw_range = 20 + + //Redundent + matter = list() + playing = 0 + emagged = 0 + timerecorded = 0 + playsleepseconds = 0 + storedinfo = list() + canprint = 1 + + //Specific for Duty Officers + var/paused = 0 + var/assignedUsers = list() + var/sessionLog = list() + var/interviewLog = list() + var/sLogFile = null + var/iLogFile = null + +/obj/item/device/taperecorder/duty_officer/hear_talk(mob/living/M as mob, msg, var/verb="says") + if(recording && !paused) + timestamp = "[get_time()]" + var/fmsg = "\[[timestamp]\] [M.name] [verb], \"[msg]\"" + sLogFile << fmsg + return + +/obj/item/device/taperecorder/duty_officer/proc/get_time() + return "[round(world.time / 36000)+12]:[(world.time / 600 % 60) < 10 ? add_zero(world.time / 600 % 60, 1) : world.time / 600 % 60]:[(world.time / 60 % 60) < 10 ? add_zero(world.time / 60 % 60, 1) : world.time / 60 % 60]" + + +/obj/item/device/taperecorder/duty_officer/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/card/id)) + var/obj/item/weapon/card/id/ID = W + if(ID.GetAccess(access_cent_captain)) + if(!user in assignedUsers) + assignedUsers += user + else + user << "The device beeps and flashes \"Already Registered\"." + return + else + user << "The device beeps and appears to shutdown." + return + if(istype(W, /obj/item/weapon/paper)) + var/obj/item/weapon/paper/P = W + logPaper(user, P) + ..() + +/obj/item/device/taperecorder/duty_officer/proc/logPaper(var/mob/M, var/obj/item/weapon/paper/P) + if(!P) + return + var/case = input(usr, "Enter case name","Case Name") as null|text + if(!case || case == "") + usr << "The device beeps and flashes \"No data entered, Aborting\"." + return + var/reference = input(usr, "Enter reference","Reference") as null|text + if(!reference || reference == "") + usr << "The device beeps and flashes \"No data entered, Aborting\"." + return + + var/date_string = time2text(world.realtime, "YYYY_MM_DD") + var/fileLoc = "data/dutylogs/[M.ckey]/[date_string]-[case].log" + var/fileName = "[date_string]-[case].log" + if(fexists(fileLoc)) + var/safe = 0 + var/i = 1 + while(!safe) + fileLoc = "data/dutylogs/[M.ckey]/[date_string]-[case][i].log" + if(!fexists(fileLoc)) + fileName = "[date_string]-[case][i].log" + safe = 1 + break + i++ + + iLogFile = file(fileLoc) + iLogFile << "[P.name]-[reference]" + iLogFile << "Case file: [case]" + iLogFile << "Reference: [reference]" + iLogFile << "Date: [date_string]" + iLogFile << "Filed by: [M]" + iLogFile << "--------------------------------" + iLogFile << "[P.info]" + iLogFile << "[P.stamps]" + iLogFile = null + usr << "The device beeps and flashes \"Writing to [fileName]\"." + return + +/obj/item/device/taperecorder/duty_officer/record() + set name = "Start Recording" + set category = "Recorder" + + if(!usr.client.holder) + usr << "The device beeps and flashes \"Unauthorised user.\"." + return + if(usr.stat) + return + if(recording) + usr << "The device beeps and flashes \"Already recording, Aborting\"." + return + + var/case = input(usr, "Enter case name","Case Name") as null|text + if(!case || case == "") + usr << "The device beeps and flashes \"No data entered, Aborting\"." + return + var/interviewee = input(usr, "Enter interviewee name","Interviewee Name") as null|text + if(!interviewee || interviewee == "") + usr << "The device beeps and flashed \"No data entered, Aborting\"." + return + + var/date_string = time2text(world.realtime, "YYYY_MM_DD") + var/fileLoc = "data/dutylogs/[usr.ckey]/[date_string]-[case]-[interviewee].log" + var/fileName = "[date_string]-[case].log" + if(fexists(fileLoc)) + var/safe = 0 + var/i = 1 + while(!safe) + fileLoc = "data/dutylogs/[usr.ckey]/[date_string]-[case]-[interviewee]-[i].log" + if(!fexists(fileLoc)) + fileName = "[date_string]-[case]-[interviewee]-[i].log" + safe = 1 + break + i++ + sLogFile = file(fileLoc) + sLogFile << "[case]-[interviewee]" + sLogFile << "Case file: [case]" + sLogFile << "--------------------------------" + sLogFile << "Date: [date_string]" + sLogFile << "--------------------------------" + sLogFile << "Interviewer: [usr.name]" + sLogFile << "Interviewee: [interviewee]" + sLogFile << "Recorder started: [get_time()]" + sLogFile << "--------------------------------" + + recording = 1 + icon_state = "taperecorderrecording" + usr << "The device beeps and flashes \"Writing to [fileName]\"." + + return + +/obj/item/device/taperecorder/duty_officer/stop() + set name = "Stop" + set category = "Recorder" + + if(usr.stat) + return + if(!usr.client.holder) + usr << "The device beeps and flashes \"Unauthorised user.\"." + return + if(!recording) + usr << "The device beeps and flashes \"Not recording, Aborting\"." + return + + recording = 0 + paused = 0 + sLogFile << "--------------------------------" + sLogFile << "Recorder stopped: [get_time()]" + sLogFile << "--------------------------------" + sLogFile = null + usr << "The device beeps and flashes \"Recording stopped log saved.\"." + icon_state = "taperecorderidle" + + return + +/obj/item/device/taperecorder/duty_officer/print_transcript() + set name = "Print Transcript" + set category = "Recorder" + + if(usr.stat) + return + if(!usr.client.holder) + usr << "The device beeps and flashes \"Unauthorised user\"." + return + if(recording) + usr << "The device beeps and flashes \"Device recording, Aborting\"." + return + + var/path = usr.client.browse_files("data/dutylogs/") + if(!path) + return + + message_admins("[key_name_admin(usr)] accessed file: [path]") + var/list/lFile = file2list(path) + var/dat = "" + var/firstLine = null + for(var/line in lFile) + if(!line) + continue + if(!firstLine) + firstLine = "[line]" + continue + + dat += "[line]
" + + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(src) + P.name = "[firstLine]" + P.info = "[dat]" + P.update_icon() + P.loc = get_turf(src.loc) + + return + +/obj/item/device/taperecorder/duty_officer/verb/pause_recording() + set name = "Pause" + set category = "Recorder" + + if(usr.stat) + return + if(!usr.client.holder) + usr << "The device beeps and flashes \"Unauthorised user.\"." + return + if(!recording) + usr << "The device beeps and flashes \"Not recording, Aborting\"." + return + + if(!paused) + sLogFile << "--------------------------------" + sLogFile << "Recorder paused at: [get_time()]" + usr << "The device beeps and flashes \"Recording resumed\"." + paused = 1 + else + sLogFile << "Recorder resumed at: [get_time()]" + sLogFile << "--------------------------------" + usr << "The device beeps and flashes \"Recording paused\"." + paused = 0 + return + +/obj/item/device/taperecorder/duty_officer/attack_self(mob/user) + return + +//redundent for now +/obj/item/device/taperecorder/duty_officer/clear_memory() + set name = "Clear Memory" + set category = null + + return + +/obj/item/device/taperecorder/duty_officer/playback_memory() + set name = "Playback Memory" + set category = null + + return + +/obj/item/device/taperecorder/duty_officer/explode() + return +