diff --git a/baystation12.dme b/baystation12.dme index a52e66f6609..d0d51121ffd 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -882,6 +882,8 @@ #include "code\modules\awaymissions\pamphlet.dm" #include "code\modules\awaymissions\trigger.dm" #include "code\modules\awaymissions\zlevel.dm" +#include "code\modules\cciaa\cciaa.dm" +#include "code\modules\cciaa\cciaa_items.dm" #include "code\modules\client\client defines.dm" #include "code\modules\client\client procs.dm" #include "code\modules\client\preferences.dm" diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 36fa534fa95..fcf2f569011 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -289,6 +289,7 @@ proc/tg_list2text(list/list, glue=",") if (rights & R_SPAWN) . += "[seperator]+SPAWN" if (rights & R_MOD) . += "[seperator]+MODERATOR" if (rights & R_MENTOR) . += "[seperator]+MENTOR" + if (rights & R_CCIAA) . += "[seperator]+CCIAA" return . /proc/ui_style2icon(ui_style) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index ceb65c71ab2..6c21fed7523 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -65,6 +65,7 @@ var/list/gamemode_cache = list() var/kick_inactive = 0 //force disconnect for inactive players after this many minutes, if non-0 var/show_mods = 0 var/show_mentors = 0 + var/show_auxiliary_roles = 0 //toggles all secondary staff members. Such as CCIAA, Devs, etcetera. var/mods_can_tempban = 0 var/mods_can_job_tempban = 0 var/mod_tempban_max = 1440 @@ -678,6 +679,9 @@ var/list/gamemode_cache = list() if("sql_whitelists") config.sql_whitelists = 1 + if("show_auxiliary_roles") + config.show_auxiliary_roles = 1 + else log_misc("Unknown setting in configuration: '[name]'") diff --git a/code/datums/mind.dm b/code/datums/mind.dm index c1badaaca85..bda2c114cdf 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -36,6 +36,8 @@ var/mob/living/original //TODO: remove.not used in any meaningful way ~Carn. First I'll need to tweak the way silicon-mobs handle minds. var/active = 0 + var/mob/living/admin_mob_placeholder = null + var/memory var/assigned_role diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm index f12d7741378..d19fc48ddf3 100644 --- a/code/game/verbs/who.dm +++ b/code/game/verbs/who.dm @@ -63,9 +63,11 @@ var/msg = "" var/modmsg = "" var/mentmsg = "" + var/cciaamsg = "" var/num_mods_online = 0 var/num_admins_online = 0 var/num_mentors_online = 0 + var/num_cciaa_online = 0 if(holder) for(var/client/C in admins) if(R_ADMIN & C.holder.rights || (!R_MOD & C.holder.rights && !R_MENTOR & C.holder.rights)) //Used to determine who shows up in admin rows @@ -119,6 +121,20 @@ mentmsg += "\n" num_mentors_online++ + else if (R_CCIAA & C.holder.rights) + cciaamsg += "\t[C]" + if (isobserver(C.mob)) + cciaamsg += " - Observing" + else if (istype(C.mob, /mob/new_player)) + cciaamsg += " - Lobby" + else + cciaamsg += " - Playing" + + if (C.is_afk()) + cciaamsg += " (AFK)" + cciaamsg += "\n" + num_cciaa_online++ + else for(var/client/C in admins) if(R_ADMIN & C.holder.rights || (!R_MOD & C.holder.rights && !R_MENTOR & C.holder.rights)) @@ -131,6 +147,9 @@ else if (R_MENTOR & C.holder.rights) mentmsg += "\t[C] is a [C.holder.rank]\n" num_mentors_online++ + else if (R_CCIAA & C.holder.rights) + cciaamsg += "\t[C] is a [C.holder.rank]\n" + num_cciaa_online++ if(config.admin_irc) src << "Adminhelps are also sent to IRC. If no admins are available in game try anyway and an admin on IRC may see it and respond." @@ -142,4 +161,8 @@ if(config.show_mentors) msg += "\n Current Mentors ([num_mentors_online]):\n" + mentmsg + if (config.show_auxiliary_roles) + if (num_cciaa_online) + msg += "\n Current CCIA Agents ([num_cciaa_online]):\n" + cciaamsg + src << msg diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 877946479b3..17051d11099 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -41,7 +41,8 @@ var/list/admin_ranks = list() //list of all ranks with associated rights if("sound","sounds") rights |= R_SOUNDS if("spawn","create") rights |= R_SPAWN if("mod") rights |= R_MOD - if("mentor") rights |= R_MENTOR + if("mentor") rights |= R_MENTOR + if("cciaa") rights |= R_CCIAA admin_ranks[rank] = rights previous_rights = rights diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 05be2cd7a05..bd4ce2fe742 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -93,6 +93,7 @@ var/list/admin_verbs_admin = list( /client/proc/view_chemical_reaction_logs, /client/proc/makePAI, /datum/admins/proc/paralyze_mob +// /datum/admins/proc/send_admin_fax ) var/list/admin_verbs_ban = list( /client/proc/unban_panel, @@ -119,6 +120,7 @@ var/list/admin_verbs_fun = list( /client/proc/toggle_random_events, /client/proc/editappear, /client/proc/roll_dices +// /datum/admins/proc/send_admin_fax ) var/list/admin_verbs_spawn = list( /datum/admins/proc/spawn_fruit, @@ -301,6 +303,17 @@ var/list/admin_verbs_mentor = list( /client/proc/cmd_admin_subtle_message ) +var/list/admin_verbs_cciaa = list( + /client/proc/cmd_admin_pm_panel, /*admin-pm list*/ + /client/proc/spawn_duty_officer, + /client/proc/cmd_admin_create_centcom_report, + /client/proc/cmd_cciaa_say, + /client/proc/returntobody, +// /client/proc/view_duty_log, +// /datum/admins/proc/send_admin_fax, + /client/proc/check_fax_history +) + /client/proc/add_admin_verbs() if(holder) verbs += admin_verbs_default @@ -321,6 +334,7 @@ var/list/admin_verbs_mentor = list( if(holder.rights & R_SPAWN) verbs += admin_verbs_spawn if(holder.rights & R_MOD) verbs += admin_verbs_mod if(holder.rights & R_MENTOR) verbs += admin_verbs_mentor + if(holder.rights & R_CCIAA) verbs += admin_verbs_cciaa /client/proc/remove_admin_verbs() verbs.Remove( diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index dbd4de64446..ef3b35b45c3 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -8,6 +8,8 @@ var/list/admin_datums = list() var/datum/marked_datum + var/mob/living/original_mob = null + var/admincaster_screen = 0 //See newscaster.dm under machinery for a full description var/datum/feed_message/admincaster_feed_message = new /datum/feed_message //These two will act as holders. var/datum/feed_channel/admincaster_feed_channel = new /datum/feed_channel @@ -43,7 +45,7 @@ var/list/admin_datums = list() owner.holder = src owner.deadmin_holder = null owner.add_admin_verbs() - + /* checks if usr is an admin with at least ONE of the flags in rights_required. (Note, they don't need all the flags) diff --git a/code/modules/admin/verbs/adminsay.dm b/code/modules/admin/verbs/adminsay.dm index faa4d7def5a..60fd1f37971 100644 --- a/code/modules/admin/verbs/adminsay.dm +++ b/code/modules/admin/verbs/adminsay.dm @@ -36,3 +36,21 @@ C << "" + create_text_tag("mod", "MOD:", C) + " [sender_name](JMP): [msg]" feedback_add_details("admin_verb","MS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/cmd_cciaa_say(msg as text) + set category = "Special Verbs" + set name = "CCIAsay" + set hidden = 1 + + if(!check_rights(R_ADMIN|R_CCIAA)) return + + msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN) + if(!msg) return + + log_admin("CCIASAY: [key_name(src)] : [msg]") + + if(check_rights((R_CCIAA|R_ADMIN),0)) + msg = "CCIAAgent: [key_name(usr, 0, 1, 0)]: [msg]" + for(var/client/C in admins) + if(C.holder.rights & (R_ADMIN|R_CCIAA)) + C << msg diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index d987c52260b..313de0150d9 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -29,10 +29,14 @@ //log_admin("HELP: [key_name(src)]: [msg]") /proc/Centcomm_announce(var/msg, var/mob/Sender, var/iamessage) + var/msg_cciaa = "\blue CENTCOMM[iamessage ? " IA" : ""]:[key_name(Sender, 1)] (RPLY): [msg]" msg = "\blue CENTCOMM[iamessage ? " IA" : ""]:[key_name(Sender, 1)] (PP) (VV) (SM) (JMP) (CA) (BSA) (RPLY): [msg]" + for(var/client/C in admins) if(R_ADMIN & C.holder.rights) C << msg + else if (R_CCIAA & C.holder.rights) + C << msg_cciaa /proc/Syndicate_announce(var/msg, var/mob/Sender) msg = "\blue ILLEGAL:[key_name(Sender, 1)] (PP) (VV) (SM) (JMP) (CA) (BSA) (RPLY): [msg]" diff --git a/code/modules/cciaa/cciaa.dm b/code/modules/cciaa/cciaa.dm new file mode 100644 index 00000000000..cee2524f0d4 --- /dev/null +++ b/code/modules/cciaa/cciaa.dm @@ -0,0 +1,323 @@ +/client/proc/spawn_duty_officer() + set category = "Special Verbs" + set name = "Spawn CCIA Agent" + set desc = "Spawns a CCIA Agent to... IA Agent?" + + if(!check_rights(R_CCIAA)) return + + if(!holder) + return //how did they get here? + + if(!ticker) + alert("Wait until the game starts") + return + + if(ticker.current_state < GAME_STATE_PLAYING) + src << "\red The game hasn't started yet!" + return + + if(istype(mob, /mob/new_player)) + src << "\red You can't be in the lobby to join as a duty officer" + return + + if(mob.mind && mob.mind.special_role == "CCIA Agent") + src << "\red You are already a CCIA Agent" + verbs += /client/proc/returntobody + return + + var/wasLiving = 0 + if(istype(mob, /mob/living)) + holder.original_mob = mob + wasLiving = 1 + + for (var/obj/effect/landmark/L in landmarks_list) + if(L.name == "CCIAAgent") + var/new_name = input(usr, "Pick a name","Name") as null|text + var/mob/living/carbon/human/M = new(null) + + var/new_facial = input("Please select facial hair color.", "Character Generation") as color + if(new_facial) + M.r_facial = hex2num(copytext(new_facial, 2, 4)) + M.g_facial = hex2num(copytext(new_facial, 4, 6)) + M.b_facial = hex2num(copytext(new_facial, 6, 8)) + + var/new_hair = input("Please select hair color.", "Character Generation") as color + if(new_facial) + M.r_hair = hex2num(copytext(new_hair, 2, 4)) + M.g_hair = hex2num(copytext(new_hair, 4, 6)) + M.b_hair = hex2num(copytext(new_hair, 6, 8)) + + var/new_eyes = input("Please select eye color.", "Character Generation") as color + if(new_eyes) + M.r_eyes = hex2num(copytext(new_eyes, 2, 4)) + M.g_eyes = hex2num(copytext(new_eyes, 4, 6)) + M.b_eyes = hex2num(copytext(new_eyes, 6, 8)) + + var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation") as text + + if (!new_tone) + new_tone = 35 + M.s_tone = max(min(round(text2num(new_tone)), 220), 1) + M.s_tone = -M.s_tone + 35 + + // hair + var/list/all_hairs = typesof(/datum/sprite_accessory/hair) - /datum/sprite_accessory/hair + var/list/hairs = list() + + // loop through potential hairs + for(var/x in all_hairs) + var/datum/sprite_accessory/hair/H = new x + hairs.Add(H.name) + del(H) + //hair + var/new_hstyle = input(usr, "Select a hair style", "Grooming") as null|anything in hair_styles_list + if(new_hstyle) + M.h_style = new_hstyle + + // facial hair + var/new_fstyle = input(usr, "Select a facial hair style", "Grooming") as null|anything in facial_hair_styles_list + if(new_fstyle) + M.f_style = new_fstyle + + var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female") + if (new_gender) + if(new_gender == "Male") + M.gender = MALE + else + M.gender = FEMALE + //M.rebuild_appearance() + M.update_hair() + M.update_body() + M.check_dna(M) + + M.real_name = new_name + M.name = new_name + M.age = input("Enter your characters age:","Num") as null|num + if(!M.age) + M.age = rand(35,50) + if(M.age < 33 || M.age > 60) + src << "\red The age you selected was not in a valid range for a Duty Officer" + if(M.age < 33) + M.age = 33 + else + M.age = 60 + src << "\red Your age has been set to [M.age]" + + M.dna.ready_dna(M) + + //Creates mind stuff. + M.mind = new + M.mind.current = M + M.mind.original = M + if(wasLiving) + M.mind.admin_mob_placeholder = mob + M.mind.assigned_role = "Central Command Internal Affairs Agent" + M.mind.special_role = "CCIA Agent" + M.loc = L.loc + M.key = key + + if(wasLiving) + clear_cciaa_job(holder.original_mob) + spawn(1) + holder.original_mob.key = "@[key]" + + M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/white(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/clothing/glasses/sunglasses/sechud(M), slot_glasses) + M.equip_to_slot_or_del(new /obj/item/clothing/head/beret/centcom/officer(M), slot_head) + M.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/spray/pepper(M), slot_l_store) + M.equip_to_slot_or_del(new /obj/item/device/taperecorder/cciaa(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_to_slot_or_del(bag, slot_back) + if(M.backbag == 1) + M.equip_to_slot_or_del(new /obj/item/weapon/stamp/centcomm(M.back), slot_in_backpack) + + var /obj/item/weapon/storage/lockbox/lockbox = new(M) + lockbox.req_access = list(access_cent_captain) + lockbox.name = "A CCIA Agent briefcase" + lockbox.desc = "A smart looking briefcase with a NT logo on the side" + lockbox.storage_slots = 8 + lockbox.max_storage_space = 16 + M.equip_to_slot_or_del(lockbox, slot_l_hand) + + var/obj/item/device/pda/central/pda = new(M) + pda.owner = M.real_name + pda.ownjob = "Central Command Internal Affairs Agent" + pda.name = "PDA-[M.real_name] ([pda.ownjob])" + + M.equip_to_slot_or_del(pda, slot_belt) + + M.implant_loyalty(M, 1) + + var/obj/item/weapon/card/id/W = new(M) + W.name = "[M.real_name]'s ID Card" + W.icon_state = "centcom" + W.item_state = "id_inv" + W.access = get_all_accesses() + get_centcom_access("CCIAA") + W.assignment = "Central Command Internal Affairs Agent" + W.registered_name = M.real_name + M.equip_to_slot_or_del(W, slot_wear_id) + + verbs += /client/proc/returntobody + break + +/client/proc/returntobody() + set name = "Return to mob" + set desc = "The Agent's work is done, return to your original mob" + set category = "Special Verbs" + + if(!check_rights(0)) return + + if(!mob.mind || mob.mind.special_role != "CCIA Agent") + verbs -= /client/proc/returntobody + return + + if(!holder) return + + var/mob/M = mob + var/area/A = get_area(M) + + if(M.stat == DEAD) + if(holder.original_mob) + if(holder.original_mob.client) + if(alert(src, "There is someone else in your old body.\nWould you like to ghost instead?", "There is someone else in your old body, you will be ghosted", "Yes", "No") == "Yes") + M.mind.special_role = null + mob.ghostize(1) + return + else + return + holder.original_mob.key = key + holder.original_mob = null + return + M.mind.special_role = null + mob.ghostize(1) + return + + if(!is_type_in_list(A,centcom_areas)) + src << "\red You need to be back at central to do this" + return + + if(holder.original_mob) + if(holder.original_mob == M) + verbs -= /client/proc/returntobody + return + + if(holder.original_mob.client) + if(alert(src, "There is someone else in your old body.\nWould you like to ghost instead?", "There is someone else in your old body, you will be ghosted", "Yes", "No") == "Yes") + M.mind.special_role = null + mob.ghostize(0) + else + return + else + holder.original_mob.key = key + + holder.original_mob = null + else + if(mob.mind.admin_mob_placeholder) + if(mob.mind.admin_mob_placeholder.client) + if(alert(src, "There is someone else in your old body.\nWould you like to ghost instead?", "There is someone else in your old body, you will be ghosted", "Yes", "No") == "Yes") + M.mind.special_role = null + mob.ghostize(0) + else + return + else + mob.mind.admin_mob_placeholder.key = key + M.mind.admin_mob_placeholder = null + else + M.mind.special_role = null + mob.ghostize(0) + verbs -= /client/proc/returntobody + del(M) + +/proc/clear_cciaa_job(var/mob/living/carbon/human/M) + spawn(9000) + if(!M.client) + var/oldjob = M.mind.assigned_role + job_master.FreeRole(oldjob) + return + +/datum/admins/proc/send_admin_fax(var/mob/sender = null, var/obj/machinery/photocopier/faxmachine/fax = null) + set name = "Send admin fax" + set desc = "Send a fax from Central Command" + set category = "Special Verbs" + + if (!check_rights(R_ADMIN|R_CCIAA|R_FUN)) + src.owner << "\red You do not have enough powers to do this." + return + + var/target_department = null + if (!fax) + var/list/all_fax_machines = list() + for (var/obj/machinery/photocopier/faxmachine/F in world) + all_fax_machines += F + target_department = input(src.owner, "Please select a department to send this fax to.", "Target Fax Department", null) as null|anything in all_fax_machines + + if (!fax) + src.owner << "\red Couldn't find the desired fax machine! Sending cancelled!" + + //todo: sanitize + var/input = input(src.owner, "Please enter a message to reply to [sender ? key_name(sender) : "a fax"] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use
for line breaks.", "Outgoing message from Centcomm", "") as message|null + if (!input) + src.owner << "\red Cancelled." + return + + var/customname = input(src.owner, "Pick a title for the report", "Title") as text|null + + // Create the reply message + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( null ) //hopefully the null loc won't cause trouble for us + P.name = "[command_name()]- [customname]" + P.info = input + P.update_icon() + + // Stamps + var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') + stampoverlay.icon_state = "paper_stamp-cent" + if(!P.stamped) + P.stamped = new + P.stamped += /obj/item/weapon/stamp + P.overlays += stampoverlay + P.stamps += "
This paper has been stamped by the Central Command Quantum Relay." + + if(fax.recievefax(P)) + src.owner << "\blue Message reply to transmitted successfully." + log_and_message_admins("sent a fax message to the station.") + else + src.owner << "\red Message reply failed." + + spawn(100) + qdel(P) + return + +/client/proc/check_fax_history() + set name = "Check fax history" + set desc = "Look up the faxes sent this round." + set category = "Special Verbs" + + if (!check_rights(R_ADMIN|R_CCIAA|R_FUN)) + usr << "\red You do not have enough powers to do this." + return + + var/data = "
Send New Fax
" + data += "
" + data += "
Received Faxes:

" + + if (arrived_faxes && arrived_faxes.len) + for (var/obj/item/item in arrived_faxes) + data += "[item.name] - view message
" + else + data += "
No faxes have been received.
" + + data += "
Sent Faxes:

" + + if (sent_faxes && sent_faxes.len) + for (var/obj/item/item in sent_faxes) + data += "[item.name] - view message
" + else + data += "
No faxes have been sent out.
" + + usr << browse("Centcomm Fax History[data]", "window=Centcomm Fax History") diff --git a/code/modules/cciaa/cciaa_items.dm b/code/modules/cciaa/cciaa_items.dm new file mode 100644 index 00000000000..a5246585938 --- /dev/null +++ b/code/modules/cciaa/cciaa_items.dm @@ -0,0 +1,253 @@ +//CCIAA's PDA. +/obj/item/device/pda/central + default_cartridge = /obj/item/weapon/cartridge/captain + icon_state = "pda-h" + detonate = 0 + +//CCIAA's tape recorder +/obj/item/device/taperecorder/cciaa + w_class = 1.0 + recording = 0 + timestamp = list() //This actually turns timestamp into a string later on + + //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/cciaa/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/cciaa/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/cciaa/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/cciaa/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/cciaa/record() + set name = "Start Recording" + set category = "Recorder" + + if(!usr.client.holder && !(usr.client.holder.rights & R_CCIAA)) + 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]-[interviewee].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/cciaa/stop() + set name = "Stop" + set category = "Recorder" + + if(usr.stat) + return + if(!usr.client.holder && !(usr.client.holder.rights & R_CCIAA)) + 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/cciaa/print_transcript() + set name = "Print Transcript" + set category = "Recorder" + + if(usr.stat) + return + if(!usr.client.holder && !(usr.client.holder.rights & R_CCIAA)) + 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/cciaa/verb/pause_recording() + set name = "Pause" + set category = "Recorder" + + if(usr.stat) + return + if(!usr.client.holder && !(usr.client.holder.rights & R_CCIAA)) + 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/cciaa/attack_self(mob/user) + return + +//redundent for now +/obj/item/device/taperecorder/cciaa/clear_memory() + set name = "Clear Memory" + set category = null + + return + +/obj/item/device/taperecorder/cciaa/playback_memory() + set name = "Playback Memory" + set category = null + + return + +/obj/item/device/taperecorder/cciaa/explode() + return diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index 7cd104870f4..f5a48a5b9bb 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -2,7 +2,8 @@ var/list/obj/machinery/photocopier/faxmachine/allfaxes = list() var/list/admin_departments = list("Central Command", "Sol Government") var/list/alldepartments = list() -var/list/adminfaxes = list() //cache for faxes that have been sent to admins +var/list/arrived_faxes = list() //cache for faxes that have been sent to the admins +var/list/sent_faxes = list() //cache for faxes that have been sent by the admins /obj/machinery/photocopier/faxmachine name = "fax machine" @@ -60,7 +61,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins dat += "Transmitter arrays realigning. Please stand by.
" else - + dat += "Send
" dat += "Currently sending: [copyitem.name]
" dat += "Sending to: [destination]
" @@ -89,7 +90,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins send_admin_fax(usr, destination) else sendfax(destination) - + if (sendcooldown) spawn(sendcooldown) // cooldown time sendcooldown = 0 @@ -138,14 +139,14 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins /obj/machinery/photocopier/faxmachine/proc/sendfax(var/destination) if(stat & (BROKEN|NOPOWER)) return - + use_power(200) - + var/success = 0 for(var/obj/machinery/photocopier/faxmachine/F in allfaxes) if( F.department == destination ) success = F.recievefax(copyitem) - + if (success) visible_message("[src] beeps, \"Message transmitted successfully.\"") //sendcooldown = 600 @@ -155,16 +156,16 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins /obj/machinery/photocopier/faxmachine/proc/recievefax(var/obj/item/incoming) if(stat & (BROKEN|NOPOWER)) return 0 - + if(department == "Unknown") return 0 //You can't send faxes to "Unknown" flick("faxreceive", src) playsound(loc, "sound/items/polaroid1.ogg", 50, 1) - + // give the sprite some time to flick sleep(20) - + if (istype(incoming, /obj/item/weapon/paper)) copy(incoming) else if (istype(incoming, /obj/item/weapon/photo)) @@ -180,7 +181,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins /obj/machinery/photocopier/faxmachine/proc/send_admin_fax(var/mob/sender, var/destination) if(stat & (BROKEN|NOPOWER)) return - + use_power(200) var/obj/item/rcvdcopy @@ -193,10 +194,10 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins else visible_message("[src] beeps, \"Error transmitting message.\"") return - + rcvdcopy.loc = null //hopefully this shouldn't cause trouble - adminfaxes += rcvdcopy - + arrived_faxes += rcvdcopy + //message badmins that a fax has arrived switch(destination) if ("Central Command") @@ -204,11 +205,11 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins if ("Sol Government") message_admins(sender, "SOL GOVERNMENT FAX", rcvdcopy, "CentcommFaxReply", "#1F66A0") //message_admins(sender, "SOL GOVERNMENT FAX", rcvdcopy, "SolGovFaxReply", "#1F66A0") - + sendcooldown = 1800 sleep(50) visible_message("[src] beeps, \"Message transmitted successfully.\"") - + /obj/machinery/photocopier/faxmachine/proc/message_admins(var/mob/sender, var/faxname, var/obj/item/sent, var/reply_type, font_colour="#006100") var/msg = "\blue [faxname]: [key_name(sender, 1)] (PP) (VV) (SM) (JMP) (CA) (REPLY): Receiving '[sent.name]' via secure connection ... view message" diff --git a/code/setup.dm b/code/setup.dm index 5429081c2f3..831e6626b98 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -539,8 +539,9 @@ #define R_MOD 8192 #define R_MENTOR 16384 #define R_HOST 32768 +#define R_CCIAA 65536 -#define R_MAXPERMISSION 32768 // This holds the maximum value for a permission. It is used in iteration, so keep it updated. +#define R_MAXPERMISSION 65536 // This holds the maximum value for a permission. It is used in iteration, so keep it updated. // Preference toggles. #define SOUND_ADMINHELP 1 diff --git a/code/stylesheet.dm b/code/stylesheet.dm index 673712a1c1b..fcdba6edb95 100644 --- a/code/stylesheet.dm +++ b/code/stylesheet.dm @@ -35,6 +35,7 @@ em {font-style: normal;font-weight: bold;} .mod_channel {color: #735638; font-weight: bold;} .mod_channel .admin {color: #b82e00; font-weight: bold;} .admin_channel {color: #9611D4; font-weight: bold;} +.cciaasay {color: #C19A3B;} /* Radio: Misc */ .deadsay {color: #530FAD;}