diff --git a/code/__DEFINES/mob_hud.dm b/code/__DEFINES/mob_hud.dm
index 303c9523332e..7ed3680acc12 100644
--- a/code/__DEFINES/mob_hud.dm
+++ b/code/__DEFINES/mob_hud.dm
@@ -13,8 +13,6 @@
#define XENO_HOSTILE_SLOW "13" // xeno-inflicted slow. used by a bunch of MOBA xenos stuff
#define XENO_HOSTILE_TAG "14" // dancer prae 'tag'
#define XENO_HOSTILE_FREEZE "15" // Any xeno-inflifcted root
-#define XENO_EXECUTE "28" // Execute thershold, vampire
-
#define HEALTH_HUD_XENO "16" // health HUD for xenos
#define PLASMA_HUD "17" // indicates the plasma level of xenos.
#define PHEROMONE_HUD "18" // indicates which pheromone is active on a xeno.
@@ -27,7 +25,9 @@
#define HUNTER_CLAN "25" //Displays a colored icon to represent ingame Hunter Clans
#define HUNTER_HUD "26" //Displays various statuses on mobs for Hunters to identify targets
#define HOLOCARD_HUD "27" //Displays the holocards set by medical personnel
+#define XENO_EXECUTE "28" // Execute thershold, vampire
#define NEW_PLAYER_HUD "29" //Makes it easy to see new players.
+#define SPYCAM_HUD "30" //Remote control spy cameras.
//data HUD (medhud, sechud) defines
#define MOB_HUD_SECURITY_BASIC 1
@@ -51,6 +51,7 @@
#define MOB_HUD_HUNTER_CLAN 19
#define MOB_HUD_EXECUTE 20
#define MOB_HUD_NEW_PLAYER 21
+#define MOB_HUD_SPYCAMS 22
//for SL/FTL/LZ targeting on locator huds
#define TRACKER_SL "track_sl"
diff --git a/code/__DEFINES/mode.dm b/code/__DEFINES/mode.dm
index 421400499431..555b04e2e5cd 100644
--- a/code/__DEFINES/mode.dm
+++ b/code/__DEFINES/mode.dm
@@ -300,6 +300,11 @@ DEFINE_BITFIELD(whitelist_status, list(
#define FACTION_LIST_MARINE_TWE list(FACTION_MARINE, FACTION_TWE)
#define FACTION_LIST_YAUTJA list(FACTION_YAUTJA)
#define FACTION_LIST_HUNTED list(FACTION_HUNTED)
+#define FACTION_LIST_COLONY list(FACTION_SURVIVOR, FACTION_COLONIST)
+#define FACTION_LIST_NEUTRAL list(FACTION_NEUTRAL)
+
+/// The list of factions loosely allied with the USCM
+#define FACTION_LIST_MARINE_FAXES list(FACTION_MARINE, FACTION_WY, FACTION_MARSHAL, FACTION_TWE)
// Xenomorphs
#define FACTION_PREDALIEN "Predalien"
diff --git a/code/_globalvars/lists/mapping_globals.dm b/code/_globalvars/lists/mapping_globals.dm
index 2fccad48134f..c0d105d52536 100644
--- a/code/_globalvars/lists/mapping_globals.dm
+++ b/code/_globalvars/lists/mapping_globals.dm
@@ -32,6 +32,7 @@ GLOBAL_LIST_EMPTY(zombie_landmarks)
GLOBAL_LIST_EMPTY(newplayer_start)
GLOBAL_LIST_EMPTY_TYPED(observer_starts, /obj/effect/landmark/observer_start)
+GLOBAL_LIST_EMPTY_TYPED(spycam_starts, /obj/effect/landmark/spycam_start)
GLOBAL_LIST_EMPTY(map_items)
GLOBAL_LIST_EMPTY(xeno_tunnels)
diff --git a/code/datums/mob_hud.dm b/code/datums/mob_hud.dm
index fb5dddae496e..900f0f4e3173 100644
--- a/code/datums/mob_hud.dm
+++ b/code/datums/mob_hud.dm
@@ -23,6 +23,7 @@ GLOBAL_LIST_INIT_TYPED(huds, /datum/mob_hud, list(
MOB_HUD_HUNTER_CLAN = new /datum/mob_hud/hunter_clan(),
MOB_HUD_EXECUTE = new /datum/mob_hud/execute_hud(),
MOB_HUD_NEW_PLAYER = new /datum/mob_hud/new_player(),
+ MOB_HUD_SPYCAMS = new /datum/mob_hud/spy_cams(),
))
/datum/mob_hud
@@ -227,6 +228,9 @@ GLOBAL_LIST_INIT_TYPED(huds, /datum/mob_hud, list(
/datum/mob_hud/faction/observer
hud_icons = list(FACTION_HUD, ORDER_HUD, HUNTER_CLAN, HOLOCARD_HUD)
+/datum/mob_hud/spy_cams
+ hud_icons = list(SPYCAM_HUD)
+
///////// MOB PROCS //////////////////////////////:
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index 8a4e0b2f98b2..9d1a597bb220 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -38,6 +38,8 @@
var/autoname = FALSE
var/autonumber = 0 //camera number in area
+ var/list/owner_factions = FACTION_LIST_NEUTRAL
+
GLOBAL_LIST_EMPTY_TYPED(all_cameras, /obj/structure/machinery/camera)
/obj/structure/machinery/camera/Initialize(mapload, ...)
. = ..()
@@ -314,6 +316,9 @@ GLOBAL_LIST_EMPTY_TYPED(all_cameras, /obj/structure/machinery/camera)
linked_broadcasting = camera_item
c_tag = linked_broadcasting.get_broadcast_name()
+/obj/structure/machinery/camera/overwatch
+ network = list(CAMERA_NET_OVERWATCH)
+
/obj/structure/machinery/camera/mortar
alpha = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm
index 221c35f95368..469e95d54abc 100644
--- a/code/game/machinery/camera/presets.dm
+++ b/code/game/machinery/camera/presets.dm
@@ -59,6 +59,7 @@
icon = 'icons/obj/vehicles/interiors/general.dmi'
icon_state = "vehicle_camera"
network = list(CAMERA_NET_VEHICLE)
+ owner_factions = FACTION_LIST_HUMANOID
/obj/structure/machinery/camera/vehicle/toggle_cam_status(on = FALSE)
if(on)
@@ -92,6 +93,7 @@
/obj/structure/machinery/camera/autoname/almayer
name = "military-grade camera"
network = list(CAMERA_NET_ALMAYER)
+ owner_factions = FACTION_LIST_MARINE_WY
/obj/structure/machinery/camera/autoname/almayer/containment
name = "containment camera"
@@ -104,6 +106,7 @@
/obj/structure/machinery/camera/autoname/almayer/containment/hidden
network = list(CAMERA_NET_CONTAINMENT_HIDDEN)
+ owner_factions = FACTION_LIST_WY
/obj/structure/machinery/camera/autoname/almayer/containment/ares
name = "ares core camera"
@@ -125,6 +128,7 @@
colony_camera_mapload = FALSE
emp_proof = TRUE
+ owner_factions = FACTION_LIST_HUMANOID
/obj/structure/machinery/camera/autoname/lz_camera/ex_act()
return
diff --git a/code/game/machinery/computer/fax_responder_spy.dm b/code/game/machinery/computer/fax_responder_spy.dm
new file mode 100644
index 000000000000..e179425ae6be
--- /dev/null
+++ b/code/game/machinery/computer/fax_responder_spy.dm
@@ -0,0 +1,329 @@
+/obj/structure/machinery/computer/spy_camera
+ name = "remote monitoring computer"
+
+ icon_state = "terminal"
+
+ var/mob/hologram/spy_camera/spy_eye
+ var/spy_range = 5
+ var/spy_faction = FACTION_NEUTRAL
+
+ var/turf/last_location
+ var/turf/start_location
+
+ /// Computer and Spycam can only be used if this variable is cleared
+ var/locked = FALSE
+
+/obj/structure/machinery/computer/spy_camera/attackby(obj/I as obj, mob/user as mob) //Can't break or disassemble.
+ return
+
+/obj/structure/machinery/computer/spy_camera/bullet_act(obj/projectile/Proj) //Can't shoot it
+ return FALSE
+
+/obj/structure/machinery/computer/spy_camera/proc/set_operator(mob/living/carbon/human/new_operator)
+ if(!istype(new_operator))
+ return
+ remove_current_operator()
+
+ operator = new_operator
+ var/datum/mob_hud/spy_hud = GLOB.huds[MOB_HUD_SPYCAMS]
+ spy_hud.add_hud_to(new_operator, src)
+ RegisterSignal(operator, COMSIG_PARENT_QDELETING, PROC_REF(remove_current_operator))
+ RegisterSignal(operator, COMSIG_MOVABLE_MOVED, PROC_REF(remove_current_operator))
+
+ if(!last_location)
+ last_location = loc
+
+ start_location = last_location
+
+ spy_eye = new(last_location, new_operator, src)
+ //RegisterSignal(eye, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(check_and_set_zlevel))
+ RegisterSignal(spy_eye, COMSIG_PARENT_QDELETING, PROC_REF(remove_current_operator))
+
+/obj/structure/machinery/computer/spy_camera/proc/remove_current_operator()
+ SIGNAL_HANDLER
+ if(!operator) return
+
+ if(spy_eye)
+ last_location = spy_eye.loc
+ if(spy_eye.gc_destroyed)
+ spy_eye = null
+ else
+ QDEL_NULL(spy_eye)
+
+ UnregisterSignal(operator, list(
+ COMSIG_PARENT_QDELETING,
+ COMSIG_MOVABLE_PRE_MOVE,
+ COMSIG_MOB_POST_CLICK
+ ))
+ operator.update_sight()
+ var/datum/mob_hud/spy_hud = GLOB.huds[MOB_HUD_SPYCAMS]
+ spy_hud.remove_hud_from(operator, src)
+ operator = null
+
+/obj/structure/machinery/computer/spy_camera/attack_hand(mob/living/carbon/human/pos_operator)
+ if(..())
+ return
+
+ if(!istype(pos_operator))
+ return
+
+ if(locked || (!(pos_operator.faction == FACTION_FAX) && !(spy_faction in pos_operator.faction_group)))
+ to_chat(pos_operator, SPAN_WARNING("The remote camera system is locked out!"))
+ return FALSE
+
+ if(operator && operator.stat == CONSCIOUS)
+ to_chat(pos_operator, SPAN_WARNING("Someone is already using this computer!"))
+ return
+
+ if(tgui_alert(pos_operator, "Change the camera focus?", "Spycam Computer", list("Yes", "No")) == "Yes")
+ var/obj/effect/landmark/spycam_start/start_point = tgui_input_list(pos_operator, "Where do you want to focus the camera?", "Camera Focus", GLOB.spycam_starts)
+ if(!start_point)
+ return
+ last_location = start_point.loc
+
+ set_operator(pos_operator)
+
+
+/obj/effect/landmark/spycam_start
+ name = "Spycam Landmark"
+ icon_state = "spycam"
+
+/obj/effect/landmark/spycam_start/Initialize()
+ . = ..()
+ name = "Spycam [get_area_name(src, TRUE)]"
+ GLOB.spycam_starts += src
+
+/obj/effect/landmark/spycam_start/Destroy()
+ GLOB.spycam_starts -= src
+ return ..()
+
+/mob/hologram/spy_camera
+ name = "Spy Camera"
+ motion_sensed = FALSE
+ icon_state = "spycam"
+
+ color = "#10948d"
+
+ hud_possible = list(SPYCAM_HUD)
+ hears_speech = TRUE
+
+ var/mob/living/carbon/is_watching
+
+ var/spy_range = 5
+ var/spy_faction = FACTION_NEUTRAL
+
+ var/list/temporary_list = list()
+ var/list/temporary_list_2 = list()
+
+ ///Whether or not the camera is on cooldown for a warning message it can't move to a certain tile, locked to one message every 3 seconds.
+ var/move_warn = FALSE
+
+
+/mob/hologram/spy_camera/Initialize(mapload, mob/living/carbon/spy_operator, obj/structure/machinery/computer/spy_camera/console)
+ if(!console || !spy_operator)
+ return INITIALIZE_HINT_QDEL
+
+ if(!istype(console))
+ stack_trace("Tried to initialize a /mob/hologram/spy_camera on type ([console.type])")
+ return INITIALIZE_HINT_QDEL
+
+ spy_range = console.spy_range
+ spy_faction = console.spy_faction
+ faction = spy_faction
+
+ switch(spy_faction)
+ if(FACTION_MARINE, FACTION_MARSHAL)
+ color = "#0947bb"
+ if(FACTION_CLF)
+ color = "#717fbd"
+ if(FACTION_UPP)
+ color = "#0f3d11"
+ if(FACTION_TWE)
+ color = "#b350c0"
+ if(FACTION_WY)
+ color = "#b6b6b6"
+
+ . = ..()
+
+ name = "Spy Camera ([spy_faction])"
+ RegisterSignal(spy_operator, COMSIG_MOB_PRE_CLICK, PROC_REF(handle_overwatch))
+ //RegisterSignal(spy_operator, COMSIG_XENO_OVERWATCH_XENO, PROC_REF(start_watching))
+ //RegisterSignal(spy_operator, list(
+ // COMSIG_XENO_STOP_OVERWATCH,
+ // COMSIG_XENO_STOP_OVERWATCH_XENO
+ //), PROC_REF(stop_watching))
+ RegisterSignal(src, COMSIG_MOVABLE_TURF_ENTER, PROC_REF(can_spy_turf))
+
+ med_hud_set_status()
+ add_to_all_mob_huds()
+
+ spy_operator.sight |= SEE_TURFS|SEE_OBJS
+
+/mob/hologram/spy_camera/proc/exit_hologram()
+ SIGNAL_HANDLER
+ qdel(src)
+
+/mob/hologram/spy_camera/handle_move(mob/living/carbon/human/spy_operator, NewLoc, direct)
+ if(is_watching && (can_spy_turf(src, is_watching.loc) & COMPONENT_TURF_DENY_MOVEMENT))
+ return COMPONENT_OVERRIDE_MOVE
+
+ return ..()
+
+/mob/hologram/spy_camera/proc/start_watching(mob/living/carbon/human/source_mob, mob/living/carbon/human/target_mob)
+ SIGNAL_HANDLER
+ forceMove(target_mob)
+ is_watching = target_mob
+
+ RegisterSignal(target_mob, COMSIG_PARENT_QDELETING, PROC_REF(target_watching_qdeleted))
+ return
+
+// able to stop watching here before the loc is set to null
+/mob/hologram/spy_camera/proc/target_watching_qdeleted(mob/living/carbon/target)
+ SIGNAL_HANDLER
+ stop_watching(linked_mob, target)
+
+/mob/hologram/spy_camera/proc/stop_watching(mob/living/carbon/human/responder, mob/living/carbon/human/target)
+ SIGNAL_HANDLER
+ if(target)
+ if(loc == target)
+ var/turf/target_turf = get_turf(target)
+
+ if(target_turf)
+ forceMove(target_turf)
+ UnregisterSignal(target, COMSIG_PARENT_QDELETING)
+
+ if(!isturf(loc) || (can_spy_turf(src, loc) & COMPONENT_TURF_DENY_MOVEMENT))
+ forceMove(target.loc)
+
+ is_watching = null
+ target.reset_view()
+ return
+
+/mob/hologram/spy_camera/proc/can_spy_turf(mob/self, turf/crossing_turf)
+ SIGNAL_HANDLER
+
+ if(!crossing_turf || istype(crossing_turf, /turf/open/space) || istype(get_area(crossing_turf), /area/space))
+ return COMPONENT_TURF_DENY_MOVEMENT
+
+ if(istype(crossing_turf, /turf/closed/wall))
+ var/turf/closed/wall/crossing_wall = crossing_turf
+ if(crossing_wall.hull)
+ if(!move_warn)
+ move_warn = TRUE
+ addtimer(CALLBACK(src, PROC_REF(reset_warn)), 3 SECONDS)
+ to_chat(linked_mob, SPAN_WARNING("You cannot move the camera here, it's a solid wall!"))
+ return COMPONENT_TURF_DENY_MOVEMENT
+
+ if(is_mainship_level(z))
+ if(spy_faction in FACTION_LIST_MARINE_FAXES)
+ return COMPONENT_TURF_ALLOW_MOVEMENT
+
+ var/list/turf_area = view(spy_range, crossing_turf)
+ temporary_list = turf_area
+
+ var/list/obj/structure/machinery/camera/camera_list = list()
+ temporary_list_2 = camera_list
+
+ for(var/obj/structure/machinery/camera/nearby_camera in turf_area)
+ camera_list += nearby_camera
+ for(var/mob/living/carbon/human/local_mob in turf_area)
+ if(istype(local_mob.head, /obj/item/clothing/head/helmet/marine))
+ var/obj/item/clothing/head/helmet/marine/helm = local_mob.head
+ camera_list += helm.camera
+
+ for(var/obj/structure/machinery/camera/possible_camera in camera_list)
+ if(spy_faction in possible_camera.owner_factions)
+ return COMPONENT_TURF_ALLOW_MOVEMENT
+
+ if(!move_warn)
+ move_warn = TRUE
+ addtimer(CALLBACK(src, PROC_REF(reset_warn)), 3 SECONDS)
+ to_chat(linked_mob, SPAN_WARNING("You can't move the spy here, there's no camera you have access to nearby!"))
+ return COMPONENT_TURF_DENY_MOVEMENT
+
+/mob/hologram/spy_camera/proc/reset_warn()
+ move_warn = FALSE
+
+/mob/hologram/spy_camera/proc/is_spy_faction(atom/target_atom)
+ if(!ismob(target_atom))
+ return FALSE
+ var/mob/living/carbon/target_mob = target_atom
+ if(!(spy_faction in target_mob.faction_group))
+ return FALSE
+ return TRUE
+
+/mob/hologram/spy_camera/proc/handle_overwatch(mob/living/carbon/human/spy_operator, atom/target_atom, mods)
+ SIGNAL_HANDLER
+
+ var/turf/target_turf = get_turf(target_atom)
+ if(!istype(target_turf))
+ return
+
+ if(!mods["ctrl"])
+ return
+
+ // I want to make this mimic observer follow.
+ //if(is_spy_faction(target_atom))
+ // var/mob/living/carbon/target_mob = target_atom
+ // return COMPONENT_INTERRUPT_CLICK
+
+
+ if(!(can_spy_turf(src, target_turf) & COMPONENT_TURF_ALLOW_MOVEMENT))
+ return
+
+ forceMove(target_turf)
+
+ return COMPONENT_INTERRUPT_CLICK
+
+/mob/hologram/spy_camera/handle_view(mob/spy_operator, atom/target)
+ if(spy_operator.client)
+ spy_operator.client.perspective = EYE_PERSPECTIVE
+
+ if(is_watching)
+ spy_operator.client.eye = is_watching
+ else
+ spy_operator.client.eye = src
+
+ return COMPONENT_OVERRIDE_VIEW
+
+/mob/hologram/spy_camera/Destroy()
+ if(linked_mob)
+ linked_mob.sight &= ~(SEE_TURFS|SEE_OBJS)
+
+ remove_from_all_mob_huds()
+ is_watching = null
+
+ return ..()
+
+/mob/hologram/spy_camera/add_to_all_mob_huds()
+ var/datum/mob_hud/hud = GLOB.huds[MOB_HUD_SPYCAMS]
+ hud.add_to_hud(src)
+
+/mob/hologram/spy_camera/remove_from_all_mob_huds()
+ var/datum/mob_hud/hud = GLOB.huds[MOB_HUD_SPYCAMS]
+ hud.remove_from_hud(src)
+
+/mob/hologram/spy_camera/med_hud_set_status()
+ var/image/holder = hud_list[SPYCAM_HUD]
+ holder.icon_state = "hudeye"
+ holder.color = color
+
+
+
+/obj/structure/machinery/computer/spy_camera/uscm
+ spy_faction = FACTION_MARINE
+
+/obj/structure/machinery/computer/spy_camera/wy
+ spy_faction = FACTION_WY
+
+/obj/structure/machinery/computer/spy_camera/twe
+ spy_faction = FACTION_TWE
+
+/obj/structure/machinery/computer/spy_camera/clf
+ spy_faction = FACTION_CLF
+
+/obj/structure/machinery/computer/spy_camera/upp
+ spy_faction = FACTION_UPP
+
+/obj/structure/machinery/computer/spy_camera/cmb
+ spy_faction = FACTION_MARSHAL
diff --git a/code/game/machinery/fax_machine.dm b/code/game/machinery/fax_machine.dm
index 411e85cd16f9..abeb0e4f998b 100644
--- a/code/game/machinery/fax_machine.dm
+++ b/code/game/machinery/fax_machine.dm
@@ -1,17 +1,25 @@
-GLOBAL_LIST_INIT_TYPED(all_faxmachines, /obj/structure/machinery/faxmachine, list())
-GLOBAL_LIST_EMPTY(all_fax_departments)
-GLOBAL_LIST_EMPTY(all_faxcodes)
-
-#define DEPARTMENT_WY "Weyland-Yutani"
-#define DEPARTMENT_HC "USCM High Command"
-#define DEPARTMENT_CMB "CMB Incident Command Center, Local Operations"
-#define DEPARTMENT_PROVOST "USCM Provost Office"
-#define DEPARTMENT_PRESS "Various Press Organizations"
-#define DEPARTMENT_TWE "Three World Empire"
-#define DEPARTMENT_UPP "Union of Progress Peoples"
-#define DEPARTMENT_CLF "Colonial Liberation Front"
-#define DEPARTMENT_TARGET "Specific Machine Code"//Used to send to a single specific machine.
-#define HIGHCOM_DEPARTMENTS list(DEPARTMENT_WY, DEPARTMENT_HC, DEPARTMENT_CMB, DEPARTMENT_PROVOST, DEPARTMENT_PRESS, DEPARTMENT_TWE, DEPARTMENT_UPP, DEPARTMENT_CLF)
+/datum/fax_network
+ var/list/all_departments = list()
+ var/list/all_faxcodes = list()
+
+GLOBAL_DATUM_INIT(fax_network, /datum/fax_network, new)
+
+#define FAX_DEPARTMENT_WY "Weyland-Yutani"
+#define FAX_DEPARTMENT_HC "USCM High Command"
+#define FAX_DEPARTMENT_CMB "CMB Incident Command Center, Local Operations"
+#define FAX_DEPARTMENT_PROVOST "USCM Provost Office"
+#define FAX_DEPARTMENT_PRESS "Various Press Organizations"
+#define FAX_DEPARTMENT_TWE "Three World Empire"
+#define FAX_DEPARTMENT_UPP "Union of Progress Peoples"
+#define FAX_DEPARTMENT_CLF "Colonial Liberation Front"
+#define FAX_DEPARTMENT_SPECIFIC_CODE "Specific Machine Code"//Used to send to a single specific machine.
+#define FAX_HIGHCOM_DEPARTMENTS list(FAX_DEPARTMENT_WY, FAX_DEPARTMENT_HC, FAX_DEPARTMENT_CMB, FAX_DEPARTMENT_PROVOST, FAX_DEPARTMENT_PRESS, FAX_DEPARTMENT_TWE, FAX_DEPARTMENT_UPP, FAX_DEPARTMENT_CLF)
+
+#define FAX_DEPARTMENT_ALMAYER "USS Almayer"
+#define FAX_DEPARTMENT_ALMAYER_COMMAND "USS Almayer Command"
+#define FAX_DEPARTMENT_ALMAYER_BRIG "USS Almayer Brig"
+#define FAX_DEPARTMENT_ALMAYER_AICORE "USS Almayer AI Core"
+#define FAX_DEPARTMENT_GENERAL_PUBLIC "General Public"
#define FAX_NET_USCM "USCM Encrypted Network"
#define FAX_NET_USCM_HC "USCM High Command Quantum Relay"
@@ -47,12 +55,24 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
// copy of the original fax in paper format, we want the original item (i.e. photo, paper bundle) not be changed as the user will need to eject it.
var/obj/item/paper/fax_paper_copy
- ///Our department
- var/department = "General Public"
+ /// Our department
+ var/department = FAX_DEPARTMENT_GENERAL_PUBLIC
+ /// The name of the machine within the department, if it has one.
+ var/sub_name
+ /// Unique identifier for the fax machine.
+ var/machine_id_tag
+ /// Whether or not the ID tag can be changed by proc.
+ var/fixed_id_tag = FALSE
+ /// The identifying name of the machine within the department, listed when being sent something.
+ var/identity_name
+
+ /// The radio prefix used for radio alerts, if there is one.
+ var/radio_alert_tag = null
- ///Target department
- var/target_department = DEPARTMENT_WY
+ /// Target department
+ var/target_department = FAX_DEPARTMENT_WY
var/target_machine_id = "No ID Selected"
+ var/target_machine = "Undefined"
// list for img and their photo reference to be stored into the admin's cache.
var/list/photo_list = list()
@@ -63,19 +83,21 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
///storer var for cooldown on sending faxes
var/fax_cooldown = 300
COOLDOWN_DECLARE(send_cooldown)
-
- /// Unique identifier for the fax machine.
- var/machine_id_tag
- /// Whether or not the ID tag can be changed by proc.
- var/fixed_id_tag = FALSE
+ /// Whether or not the next fax to be sent is a priority one.
+ var/is_priority_fax = FALSE
+ /// If this machine can send priority faxes.
+ var/can_send_priority = FALSE
+ /// If this machine is sending only to one machine at a time or not.
+ var/single_sending = FALSE
/obj/structure/machinery/faxmachine/Initialize(mapload, ...)
. = ..()
- GLOB.all_faxmachines += src
- update_departments()
generate_id_tag()
+ update_departments()
+ if(!(identity_name in GLOB.fax_network.all_departments[department]))
+ GLOB.fax_network.all_departments[department][identity_name] = src
- if(mapload && (department in HIGHCOM_DEPARTMENTS))
+ if(mapload && (department in FAX_HIGHCOM_DEPARTMENTS))
for(var/datum/fax/fax as anything in GLOB.fax_contents)
if(fax.department != department)
continue
@@ -90,7 +112,7 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
if(fixed_id_tag && !force)
return FALSE
if(machine_id_tag)
- GLOB.all_faxcodes -= machine_id_tag
+ GLOB.fax_network.all_faxcodes -= machine_id_tag
var/id_tag_prefix
var/id_tag_suffix = "[rand(1000, 9999)][pick(GLOB.alphabet_uppercase)][pick(GLOB.alphabet_uppercase)]"
@@ -125,19 +147,20 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
if(!id_tag_final)
id_tag_final = "[id_tag_prefix]-[id_tag_suffix]"
- if(id_tag_final in GLOB.all_faxcodes)
+ if(id_tag_final in GLOB.fax_network.all_faxcodes)
generate_id_tag()
return FALSE
machine_id_tag = id_tag_final
+ identity_name = sub_name ? "[sub_name], [machine_id_tag]" : machine_id_tag
if(machine_id_tag == network)
return TRUE
- GLOB.all_faxcodes += id_tag_final
+ GLOB.fax_network.all_faxcodes[id_tag_final] = src
return TRUE
/obj/structure/machinery/faxmachine/Destroy()
- GLOB.all_faxmachines -= src
- GLOB.all_faxcodes -= machine_id_tag
+ GLOB.fax_network.all_faxcodes -= machine_id_tag
+ GLOB.fax_network.all_departments[department] -= identity_name
. = ..()
/obj/structure/machinery/faxmachine/initialize_pass_flags(datum/pass_flags_container/PF)
@@ -214,26 +237,27 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
return
/obj/structure/machinery/faxmachine/proc/update_departments()
- if(!(DEPARTMENT_TARGET in GLOB.all_fax_departments))
- GLOB.all_fax_departments += DEPARTMENT_TARGET
- if( !("[department]" in GLOB.all_fax_departments) ) //Initialize departments. This will work with multiple fax machines.
- GLOB.all_fax_departments += department
- if(!(DEPARTMENT_WY in GLOB.all_fax_departments))
- GLOB.all_fax_departments += DEPARTMENT_WY
- if(!(DEPARTMENT_HC in GLOB.all_fax_departments))
- GLOB.all_fax_departments += DEPARTMENT_HC
- if(!(DEPARTMENT_PROVOST in GLOB.all_fax_departments))
- GLOB.all_fax_departments += DEPARTMENT_PROVOST
- if(!(DEPARTMENT_CMB in GLOB.all_fax_departments))
- GLOB.all_fax_departments += DEPARTMENT_CMB
- if(!(DEPARTMENT_PRESS in GLOB.all_fax_departments))
- GLOB.all_fax_departments += DEPARTMENT_PRESS
- if(!(DEPARTMENT_TWE in GLOB.all_fax_departments))
- GLOB.all_fax_departments += DEPARTMENT_TWE
- if(!(DEPARTMENT_UPP in GLOB.all_fax_departments))
- GLOB.all_fax_departments += DEPARTMENT_UPP
- if(!(DEPARTMENT_CLF in GLOB.all_fax_departments))
- GLOB.all_fax_departments += DEPARTMENT_CLF
+ if(!(FAX_DEPARTMENT_SPECIFIC_CODE in GLOB.fax_network.all_departments))
+ GLOB.fax_network.all_departments[FAX_DEPARTMENT_SPECIFIC_CODE] = list()
+ if(!(FAX_DEPARTMENT_WY in GLOB.fax_network.all_departments))
+ GLOB.fax_network.all_departments[FAX_DEPARTMENT_WY] = list()
+ if(!(FAX_DEPARTMENT_HC in GLOB.fax_network.all_departments))
+ GLOB.fax_network.all_departments[FAX_DEPARTMENT_HC] = list()
+ if(!(FAX_DEPARTMENT_PROVOST in GLOB.fax_network.all_departments))
+ GLOB.fax_network.all_departments[FAX_DEPARTMENT_PROVOST] = list()
+ if(!(FAX_DEPARTMENT_CMB in GLOB.fax_network.all_departments))
+ GLOB.fax_network.all_departments[FAX_DEPARTMENT_CMB] = list()
+ if(!(FAX_DEPARTMENT_PRESS in GLOB.fax_network.all_departments))
+ GLOB.fax_network.all_departments[FAX_DEPARTMENT_PRESS] = list()
+ if(!(FAX_DEPARTMENT_TWE in GLOB.fax_network.all_departments))
+ GLOB.fax_network.all_departments[FAX_DEPARTMENT_TWE] = list()
+ if(!(FAX_DEPARTMENT_UPP in GLOB.fax_network.all_departments))
+ GLOB.fax_network.all_departments[FAX_DEPARTMENT_UPP] = list()
+ if(!(FAX_DEPARTMENT_CLF in GLOB.fax_network.all_departments))
+ GLOB.fax_network.all_departments[FAX_DEPARTMENT_CLF] = list()
+ if(!("[department]" in GLOB.fax_network.all_departments)) //Initialize departments. This will work with multiple fax machines.
+ GLOB.fax_network.all_departments[department] = list()
+ GLOB.fax_network.all_departments[department][identity_name] = src
// TGUI SHIT \\
@@ -271,10 +295,13 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
data["authenticated"] = authenticated
data["target_department"] = target_department
- if(target_department == DEPARTMENT_TARGET)
- data["target_department"] = target_machine_id
+ data["target_machine"] = target_machine
+ data["sending_to_specific"] = FALSE
+ if(target_department == FAX_DEPARTMENT_SPECIFIC_CODE)
+ data["target_department"] = "Specific ID - [target_machine_id]"
+ data["sending_to_specific"] = TRUE
- if(target_department in HIGHCOM_DEPARTMENTS)
+ if(target_department in FAX_HIGHCOM_DEPARTMENTS)
data["highcom_dept"] = TRUE
else
data["highcom_dept"] = FALSE
@@ -285,43 +312,78 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
data["nextfaxtime"] = send_cooldown
data["faxcooldown"] = fax_cooldown
+ data["can_send_priority"] = can_send_priority
+ data["is_priority_fax"] = is_priority_fax
+ data["is_single_sending"] = single_sending
+
+
return data
/obj/structure/machinery/faxmachine/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
+ var/mob/user = ui.user
switch(action)
+ if("toggle_priority")
+ if(!can_send_priority)
+ return
+ is_priority_fax = !is_priority_fax
+ to_chat(user, SPAN_NOTICE("Priority Alert is now [is_priority_fax ? "Enabled" : "Disabled"]."))
+ . = TRUE
+
+ if("toggle_single_send")
+ if(target_department in FAX_HIGHCOM_DEPARTMENTS)
+ single_sending = FALSE
+ return
+ if(target_department == FAX_DEPARTMENT_SPECIFIC_CODE)
+ single_sending = TRUE
+ return
+ single_sending = !single_sending
+ to_chat(user, SPAN_NOTICE("Individual Sending is now [single_sending ? "Enabled" : "Disabled"]."))
+ . = TRUE
+
if("send")
if(!original_fax)
- to_chat(ui.user, SPAN_NOTICE("No paper loaded."))
+ to_chat(user, SPAN_NOTICE("No paper loaded."))
return
+ if(single_sending && (target_machine == "Undefined") && !(target_department == FAX_DEPARTMENT_SPECIFIC_CODE))
+ to_chat(user, SPAN_WARNING("No target machine selected!"))
+ return
+
+ if(single_sending)
+ var/the_target_machine = GLOB.fax_network.all_departments[target_department][target_machine]
+ if(the_target_machine == src)
+ to_chat(user, SPAN_WARNING("You cannot send a fax to your own machine!"))
+ return
+
if(istype(original_fax, /obj/item/paper_bundle))
var/obj/item/paper_bundle/bundle = original_fax
if(bundle.amount > 5)
- to_chat(ui.user, SPAN_NOTICE("\The [src] is jammed!"))
+ to_chat(user, SPAN_NOTICE("\The [src] is jammed!"))
return
copy_fax_paper()
- outgoing_fax_message(ui.user)
+ outgoing_fax_message(user, is_priority_fax)
+ is_priority_fax = FALSE
COOLDOWN_START(src, send_cooldown, fax_cooldown)
- to_chat(ui.user, "Message transmitted successfully.")
+ to_chat(user, "Message transmitted successfully.")
. = TRUE
if("ejectpaper")
if(!original_fax)
- to_chat(ui.user, SPAN_NOTICE("No paper loaded."))
- if(!ishuman(ui.user))
- to_chat(ui.user, SPAN_NOTICE("You can't do that."))
+ to_chat(user, SPAN_NOTICE("No paper loaded."))
+ if(!ishuman(user))
+ to_chat(user, SPAN_NOTICE("You can't do that."))
return
- original_fax.forceMove(ui.user.loc)
- ui.user.put_in_hands(original_fax)
- to_chat(ui.user, SPAN_NOTICE("You take \the [original_fax.name] out of \the [src]."))
+ original_fax.forceMove(user.loc)
+ user.put_in_hands(original_fax)
+ to_chat(user, SPAN_NOTICE("You take the [original_fax.name] out of [src]."))
original_fax = null
fax_paper_copy = null
photo_list = null
@@ -329,31 +391,31 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
if("insertpaper")
var/jammed = FALSE
- var/obj/item/I = ui.user.get_active_hand()
+ var/obj/item/I = user.get_active_hand()
if(istype(I, /obj/item/paper_bundle))
var/obj/item/paper_bundle/bundle = I
if(bundle.amount > 5)
jammed = TRUE
// Repeating code? This is not ideal. Why not put this functionality inside of a proc?
if(istype(I, /obj/item/paper) || istype(I, /obj/item/paper_bundle) || istype(I, /obj/item/photo))
- ui.user.drop_inv_item_to_loc(I, src)
+ user.drop_inv_item_to_loc(I, src)
original_fax = I
if(!jammed)
- to_chat(ui.user, SPAN_NOTICE("You put \the [original_fax.name] into \the [src]."))
+ to_chat(user, SPAN_NOTICE("You put the [original_fax.name] into [src]."))
else
- to_chat(ui.user, SPAN_NOTICE("\The [src] jammed! It can only accept up to five papers at once."))
+ to_chat(user, SPAN_NOTICE("[src] jammed! It can only accept up to five papers at once."))
playsound(src, "sound/machines/terminal_insert_disc.ogg", 50, TRUE)
flick("[initial(icon_state)]send", src)
. = TRUE
if("ejectid")
- if(!scan || !ishuman(ui.user))
- to_chat(ui.user, SPAN_WARNING("You can't do that."))
+ if(!scan || !ishuman(user))
+ to_chat(user, SPAN_WARNING("You can't do that."))
return
- to_chat(ui.user, SPAN_NOTICE("You take \the [scan] out of \the [src]."))
- scan.forceMove(ui.user.loc)
- if(!ui.user.get_active_hand())
- ui.user.put_in_hands(scan)
+ to_chat(user, SPAN_NOTICE("You take [scan] out of [src]."))
+ scan.forceMove(user.loc)
+ if(!user.get_active_hand())
+ user.put_in_hands(scan)
scan = null
else
scan.forceMove(src.loc)
@@ -362,17 +424,33 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
playsound(src, 'sound/machines/terminal_eject.ogg', 15, TRUE)
. = TRUE
- if("select")
+ if("select_dept")
var/last_target_department = target_department
- target_department = tgui_input_list(ui.user, "Which department?", "Choose a department", GLOB.all_fax_departments)
+ target_department = tgui_input_list(user, "Which department?", "Choose a department", GLOB.fax_network.all_departments)
if(!target_department)
target_department = last_target_department
- if(target_department == DEPARTMENT_TARGET)
- var/new_target_machine_id = tgui_input_list(ui.user, "Which machine?", "Choose a machine code", GLOB.all_faxcodes)
+ if(target_department != last_target_department)
+ target_machine = "Undefined"
+ if(target_department in FAX_HIGHCOM_DEPARTMENTS)
+ single_sending = FALSE
+ if(target_department == FAX_DEPARTMENT_SPECIFIC_CODE)
+ var/new_target_machine_id = tgui_input_list(user, "Which machine?", "Choose a machine code", GLOB.fax_network.all_faxcodes)
if(!new_target_machine_id)
target_department = last_target_department
+ else if(new_target_machine_id == machine_id_tag)
+ to_chat(user, SPAN_WARNING("You cannot send a fax to your own machine!"))
+ target_department = last_target_department
else
target_machine_id = new_target_machine_id
+ single_sending = TRUE
+ . = TRUE
+
+ if("select_machine")
+ var/last_target_machine = target_machine
+ target_machine = tgui_input_list(user, "Which machine?", "Choose a machine", GLOB.fax_network.all_departments[target_department])
+ if(!target_machine)
+ target_machine = last_target_machine
+
. = TRUE
if("auth")
@@ -386,7 +464,7 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
authenticated = FALSE
. = TRUE
- add_fingerprint(ui.user)
+ add_fingerprint(user)
/obj/structure/machinery/faxmachine/vv_get_dropdown()
. = ..()
@@ -433,7 +511,7 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
photo_list += list("tmp_photo[content].png" = (faxed_photo.img))
fax_paper_copy.info += ""
-/obj/structure/machinery/faxmachine/proc/outgoing_fax_message(mob/user)
+/obj/structure/machinery/faxmachine/proc/outgoing_fax_message(mob/user, sending_priority)
var/datum/fax/faxcontents = new(fax_paper_copy.info, photo_list, fax_paper_copy.name, target_department, machine_id_tag)
@@ -441,41 +519,41 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
var/scan_department = target_department
var/the_target_department = target_department
- if(department in HIGHCOM_DEPARTMENTS)
+ if(department in FAX_HIGHCOM_DEPARTMENTS)
scan_department = department
- else if(target_department == DEPARTMENT_TARGET)
+ else if(target_department == FAX_DEPARTMENT_SPECIFIC_CODE)
the_target_department = "Fax Machine [target_machine_id]"
var/msg_admin = SPAN_STAFF_IC("[the_target_department]: [key_name(user, 1)] ")
msg_admin += "[CC_MARK(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_JMP_USER(user)] "
switch(scan_department)
- if(DEPARTMENT_HC)
- GLOB.USCMFaxes.Add("\['[original_fax.name]' from [key_name(usr)], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
+ if(FAX_DEPARTMENT_HC)
+ GLOB.USCMFaxes.Add("\['[original_fax.name]' from [user.real_name], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
msg_admin += "(RPLY): "
- if(DEPARTMENT_PROVOST)
- GLOB.ProvostFaxes.Add("\['[original_fax.name]' from [key_name(usr)], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
+ if(FAX_DEPARTMENT_PROVOST)
+ GLOB.ProvostFaxes.Add("\['[original_fax.name]' from [user.real_name], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
msg_admin += "(RPLY): "
- if(DEPARTMENT_CMB)
- GLOB.CMBFaxes.Add("\['[original_fax.name]' from [key_name(usr)], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
+ if(FAX_DEPARTMENT_CMB)
+ GLOB.CMBFaxes.Add("\['[original_fax.name]' from [user.real_name], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
msg_admin += "(RPLY): "
- if(DEPARTMENT_WY)
- GLOB.WYFaxes.Add("\['[original_fax.name]' from [key_name(usr)], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
+ if(FAX_DEPARTMENT_WY)
+ GLOB.WYFaxes.Add("\['[original_fax.name]' from [user.real_name], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
msg_admin += "(RPLY): "
- if(DEPARTMENT_PRESS)
- GLOB.PressFaxes.Add("\['[original_fax.name]' from [key_name(usr)], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
+ if(FAX_DEPARTMENT_PRESS)
+ GLOB.PressFaxes.Add("\['[original_fax.name]' from [user.real_name], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
msg_admin += "(RPLY): "
- if(DEPARTMENT_TWE)
- GLOB.TWEFaxes.Add("\['[original_fax.name]' from [key_name(usr)], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
+ if(FAX_DEPARTMENT_TWE)
+ GLOB.TWEFaxes.Add("\['[original_fax.name]' from [user.real_name], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
msg_admin += "(RPLY): "
- if(DEPARTMENT_UPP)
- GLOB.UPPFaxes.Add("\['[original_fax.name]' from [key_name(usr)], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
+ if(FAX_DEPARTMENT_UPP)
+ GLOB.UPPFaxes.Add("\['[original_fax.name]' from [user.real_name], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
msg_admin += "(RPLY): "
- if(DEPARTMENT_CLF)
- GLOB.CLFFaxes.Add("\['[original_fax.name]' from [key_name(usr)], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
+ if(FAX_DEPARTMENT_CLF)
+ GLOB.CLFFaxes.Add("\['[original_fax.name]' from [user.real_name], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
msg_admin += "(RPLY): "
else
- GLOB.GeneralFaxes.Add("\['[original_fax.name]' from [key_name(usr)], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
+ GLOB.GeneralFaxes.Add("\['[original_fax.name]' from [user.real_name], [scan] at [time2text(world.timeofday, "hh:mm:ss")]\]REPLY")
msg_admin += "(RPLY): "
msg_admin += SPAN_STAFF_IC("Receiving fax via secure connection ... view message")
@@ -483,7 +561,7 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
var/msg_ghost = SPAN_NOTICE("[the_target_department]: ")
msg_ghost += "Receiving fax via secure connection ... view message"
- send_fax(faxcontents)
+ send_fax(faxcontents, sending_priority)
announce_fax(msg_admin, msg_ghost)
@@ -511,26 +589,36 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
C << 'sound/effects/incoming-fax.ogg'
-/obj/structure/machinery/faxmachine/proc/send_fax(datum/fax/faxcontents)
- var/list/target_machines = list()
- for(var/obj/structure/machinery/faxmachine/pos_target in GLOB.all_faxmachines)
- if(target_department == DEPARTMENT_TARGET)
- if(pos_target != src && pos_target.machine_id_tag == target_machine_id)
- target_machines += pos_target
- else
- if(pos_target != src && pos_target.department == target_department)
- target_machines += pos_target
+/obj/structure/machinery/faxmachine/proc/send_fax(datum/fax/faxcontents, sending_priority)
+ var/list/receiving_machines = list()
+ if(target_department == FAX_DEPARTMENT_SPECIFIC_CODE)
+ var/the_target_machine = GLOB.fax_network.all_faxcodes[target_machine_id]
+ if(the_target_machine == src)
+ return
+ receiving_machines += the_target_machine
+ else if(!single_sending || (target_department in FAX_HIGHCOM_DEPARTMENTS))
+ for(var/pos_target in GLOB.fax_network.all_departments[target_department])
+ var/obj/structure/machinery/faxmachine/receiver = GLOB.fax_network.all_departments[target_department][pos_target]
+ if(receiver != src)
+ receiving_machines += receiver
+ else
+ var/the_target_machine = GLOB.fax_network.all_departments[target_department][target_machine]
+ if(the_target_machine == src)
+ return
+ receiving_machines += the_target_machine
- for(var/obj/structure/machinery/faxmachine/target in target_machines)
+ var/sent_radio_alert = FALSE
+ for(var/obj/structure/machinery/faxmachine/receiver in receiving_machines)
if(!faxcontents)
return
- if(!(target.inoperable()))
+ if(!(receiver.inoperable()))
- flick("[initial(icon_state)]receive", target)
+ flick("[initial(icon_state)]receive", receiver)
+ playsound(receiver.loc, "sound/machines/fax.ogg", 15)
// give the sprite some time to flick
spawn(30)
- var/obj/item/paper/P = new(target.loc,faxcontents.photo_list)
+ var/obj/item/paper/P = new(receiver.loc,faxcontents.photo_list)
if(!faxcontents.paper_name)
P.name = "faxed message"
else
@@ -575,13 +663,19 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
else
P.stamps += "
This paper has been sent by [machine_id_tag]."
P.overlays += stampoverlay
- playsound(target.loc, "sound/items/polaroid1.ogg", 15, 1)
+ if(sending_priority)
+ playsound(receiver.loc, "sound/machines/twobeep.ogg", 45)
+ receiver.langchat_speech("beeps with a priority message", get_mobs_in_view(GLOB.world_view_size, receiver), GLOB.all_languages, skip_language_check = TRUE, animation_style = LANGCHAT_FAST_POP, additional_styles = list("langchat_small", "emote"))
+ receiver.visible_message("[SPAN_BOLD(receiver)] beeps with a priority message.")
+ if((receiver.radio_alert_tag != null) && !sent_radio_alert)
+ ai_silent_announcement("COMMUNICATIONS REPORT: [single_sending ? "Fax Machine [receiver.machine_id_tag], [receiver.sub_name ? "[receiver.sub_name]" : ""]," : "[receiver.department]"] now receiving priority fax.", "[receiver.radio_alert_tag]")
+ sent_radio_alert = TRUE
qdel(faxcontents)
/obj/structure/machinery/faxmachine/cmb
name = "\improper CMB Incident Command Center Fax Machine"
network = FAX_NET_CMB
- department = DEPARTMENT_CMB
+ department = FAX_DEPARTMENT_CMB
/obj/structure/machinery/faxmachine/corporate
name = "\improper W-Y Corporate Fax Machine"
@@ -591,78 +685,100 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
/obj/structure/machinery/faxmachine/corporate/liaison
department = "W-Y Liaison"
+/obj/structure/machinery/faxmachine/corporate/liaison/almayer
+ department = FAX_DEPARTMENT_ALMAYER
+ sub_name = "W-Y Liaison"
+ radio_alert_tag = ":Y"
+
/obj/structure/machinery/faxmachine/corporate/highcom
- department = DEPARTMENT_WY
- target_department = "W-Y Liaison"
+ department = FAX_DEPARTMENT_WY
+ target_department = FAX_DEPARTMENT_ALMAYER
network = FAX_NET_WY_HC
+ can_send_priority = TRUE
/obj/structure/machinery/faxmachine/uscm
name = "\improper USCM Military Fax Machine"
department = "USCM Local Operations"
network = FAX_NET_USCM
- target_department = DEPARTMENT_HC
+ target_department = FAX_DEPARTMENT_HC
+
+/obj/structure/machinery/faxmachine/uscm/almayer
+ department = FAX_DEPARTMENT_ALMAYER
-/obj/structure/machinery/faxmachine/uscm/command
- department = "CIC"
+/obj/structure/machinery/faxmachine/uscm/almayer/ai_core
+ department = FAX_DEPARTMENT_ALMAYER_AICORE
+ radio_alert_tag = ":+"
-/obj/structure/machinery/faxmachine/uscm/command/capt
- department = "Commanding Officer"
+/obj/structure/machinery/faxmachine/uscm/almayer/command
+ department = FAX_DEPARTMENT_ALMAYER_COMMAND
-/obj/structure/machinery/faxmachine/uscm/command/highcom
- department = DEPARTMENT_HC
- target_department = "Commanding Officer"
+/obj/structure/machinery/faxmachine/uscm/almayer/command/capt
+ sub_name = "Commanding Officer"
+ can_send_priority = TRUE
+
+/obj/structure/machinery/faxmachine/uscm/highcom
+ department = FAX_DEPARTMENT_HC
+ target_department = FAX_DEPARTMENT_ALMAYER_COMMAND
network = FAX_NET_USCM_HC
+ can_send_priority = TRUE
-/obj/structure/machinery/faxmachine/uscm/brig
+/obj/structure/machinery/faxmachine/uscm/almayer/brig
name = "\improper USCM Provost Fax Machine"
- department = "Brig"
- target_department = DEPARTMENT_PROVOST
+ department = FAX_DEPARTMENT_ALMAYER_BRIG
+ target_department = FAX_DEPARTMENT_PROVOST
+ radio_alert_tag = ":P"
-/obj/structure/machinery/faxmachine/uscm/brig/chief
- department = "Chief MP"
+/obj/structure/machinery/faxmachine/uscm/almayer/brig/chief
+ sub_name = "Chief MP"
-/obj/structure/machinery/faxmachine/uscm/brig/provost
- department = DEPARTMENT_PROVOST
- target_department = "Brig"
+/obj/structure/machinery/faxmachine/uscm/provost
+ name = "\improper USCM Provost Fax Machine"
+ department = FAX_DEPARTMENT_PROVOST
+ target_department = FAX_DEPARTMENT_ALMAYER_BRIG
network = FAX_NET_USCM_HC
+ can_send_priority = TRUE
/obj/structure/machinery/faxmachine/upp
name = "\improper UPP Military Fax Machine"
department = "UPP Local Operations"
network = FAX_NET_UPP
- target_department = DEPARTMENT_UPP
+ target_department = FAX_DEPARTMENT_UPP
/obj/structure/machinery/faxmachine/upp/highcom
- department = DEPARTMENT_UPP
+ department = FAX_DEPARTMENT_UPP
network = FAX_NET_UPP_HC
target_department = "UPP Local Operations"
+ can_send_priority = TRUE
/obj/structure/machinery/faxmachine/clf
name = "\improper Hacked General Purpose Fax Machine"
department = "CLF Local Operations"
network = FAX_NET_CLF
- target_department = DEPARTMENT_CLF
+ target_department = FAX_DEPARTMENT_CLF
/obj/structure/machinery/faxmachine/clf/highcom
- department = DEPARTMENT_CLF
+ department = FAX_DEPARTMENT_CLF
network = FAX_NET_CLF_HC
target_department = "CLF Local Operations"
+ can_send_priority = TRUE
/obj/structure/machinery/faxmachine/twe
name = "\improper TWE Military Fax Machine"
department = "TWE Local Operations"
network = FAX_NET_TWE
- target_department = DEPARTMENT_TWE
+ target_department = FAX_DEPARTMENT_TWE
/obj/structure/machinery/faxmachine/twe/highcom
- department = DEPARTMENT_TWE
+ department = FAX_DEPARTMENT_TWE
network = FAX_NET_TWE_HC
target_department = "TWE Local Operations"
+ can_send_priority = TRUE
/obj/structure/machinery/faxmachine/press/highcom
- department = DEPARTMENT_PRESS
+ department = FAX_DEPARTMENT_PRESS
network = FAX_NET_PRESS_HC
- target_department = "General Public"
+ target_department = FAX_DEPARTMENT_GENERAL_PUBLIC
+ can_send_priority = TRUE
///The deployed fax machine backpack
/obj/structure/machinery/faxmachine/backpack
@@ -679,7 +795,7 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
if(portable_id_tag)
machine_id_tag = portable_id_tag
fixed_id_tag = TRUE
- GLOB.all_faxcodes += machine_id_tag
+ GLOB.fax_network.all_faxcodes[machine_id_tag] = src
///The wearable and deployable part of the fax machine backpack
/obj/item/device/fax_backpack
@@ -777,25 +893,25 @@ GLOBAL_LIST_EMPTY(all_faxcodes)
/obj/structure/machinery/faxmachine/proc/is_department_responder_awake(target_department)
- if(!(target_department in HIGHCOM_DEPARTMENTS))
+ if(!(target_department in FAX_HIGHCOM_DEPARTMENTS))
return FALSE
var/target_job = JOB_FAX_RESPONDER
switch(target_department)
- if(DEPARTMENT_CLF)
+ if(FAX_DEPARTMENT_CLF)
target_job = JOB_FAX_RESPONDER_CLF
- if(DEPARTMENT_CMB)
+ if(FAX_DEPARTMENT_CMB)
target_job = JOB_FAX_RESPONDER_CMB
- if(DEPARTMENT_HC)
+ if(FAX_DEPARTMENT_HC)
target_job = JOB_FAX_RESPONDER_USCM_HC
- if(DEPARTMENT_PRESS)
+ if(FAX_DEPARTMENT_PRESS)
target_job = JOB_FAX_RESPONDER_PRESS
- if(DEPARTMENT_PROVOST)
+ if(FAX_DEPARTMENT_PROVOST)
target_job = JOB_FAX_RESPONDER_USCM_PVST
- if(DEPARTMENT_TWE)
+ if(FAX_DEPARTMENT_TWE)
target_job = JOB_FAX_RESPONDER_TWE
- if(DEPARTMENT_UPP)
+ if(FAX_DEPARTMENT_UPP)
target_job = JOB_FAX_RESPONDER_UPP
- if(DEPARTMENT_WY)
+ if(FAX_DEPARTMENT_WY)
target_job = JOB_FAX_RESPONDER_WY
for(var/mob/living/carbon/human/responder in SSticker.mode.fax_responders)
diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm
index 089886db0e56..ccc6617a3ade 100644
--- a/code/game/objects/items/devices/radio/encryptionkey.dm
+++ b/code/game/objects/items/devices/radio/encryptionkey.dm
@@ -45,12 +45,6 @@
//MARINE ENCRYPTION KEYS
-/obj/item/device/encryptionkey/ai_integrated
- name = "AI Integrated Encryption Key"
- desc = "Integrated encryption key"
- icon_state = "cap_key"
- channels = list(RADIO_CHANNEL_ALMAYER = TRUE, RADIO_CHANNEL_COMMAND = TRUE, RADIO_CHANNEL_MP = TRUE, RADIO_CHANNEL_ENGI = TRUE, RADIO_CHANNEL_MEDSCI = TRUE, RADIO_CHANNEL_REQ = TRUE, SQUAD_MARINE_1 = TRUE, SQUAD_MARINE_2 = TRUE, SQUAD_MARINE_3 = TRUE, SQUAD_MARINE_4 = TRUE, SQUAD_MARINE_5 = TRUE, SQUAD_MARINE_CRYO = TRUE, RADIO_CHANNEL_JTAC = TRUE, RADIO_CHANNEL_INTEL = TRUE)
-
/obj/item/device/encryptionkey/sentry_laptop
name = "Sentry Network Status Encryption Key"
desc = "Automated channel to broadcast sentry gun updates"
@@ -143,7 +137,7 @@
/obj/item/device/encryptionkey/mcom/cl
name = "\improper Corporate Liaison radio encryption key"
icon_state = "cap_key"
- channels = list(RADIO_CHANNEL_COMMAND = TRUE, RADIO_CHANNEL_ENGI = TRUE, RADIO_CHANNEL_MEDSCI = TRUE, RADIO_CHANNEL_REQ = TRUE, RADIO_CHANNEL_JTAC = TRUE, RADIO_CHANNEL_INTEL = TRUE, RADIO_CHANNEL_WY = TRUE)
+ channels = list(RADIO_CHANNEL_COMMAND = TRUE, RADIO_CHANNEL_ENGI = TRUE, RADIO_CHANNEL_MEDSCI = TRUE, RADIO_CHANNEL_REQ = TRUE, RADIO_CHANNEL_JTAC = TRUE, RADIO_CHANNEL_INTEL = TRUE, RADIO_CHANNEL_ALMAYER = TRUE, RADIO_CHANNEL_WY = TRUE)
/obj/item/device/encryptionkey/mcom/rep
name = "\improper Representative radio encryption key"
@@ -170,8 +164,10 @@
icon_state = "req_key"
channels = list(RADIO_CHANNEL_REQ = TRUE, RADIO_CHANNEL_COMMAND = FALSE)
-/obj/item/device/encryptionkey/mcom/ai //AI only.
- channels = list(RADIO_CHANNEL_COMMAND = TRUE, RADIO_CHANNEL_MP = TRUE, SQUAD_MARINE_1 = TRUE, SQUAD_MARINE_2 = TRUE, SQUAD_MARINE_3 = TRUE, SQUAD_MARINE_4 = TRUE, SQUAD_MARINE_5 = TRUE, SQUAD_MARINE_CRYO = TRUE, RADIO_CHANNEL_ENGI = TRUE, RADIO_CHANNEL_MEDSCI = TRUE, RADIO_CHANNEL_REQ = TRUE, RADIO_CHANNEL_JTAC = TRUE, RADIO_CHANNEL_INTEL = TRUE)
+/obj/item/device/encryptionkey/cmpcom/synth/ai //AI only.
+ name = "AI Integrated Radio Encryption Key"
+ channels = list(RADIO_CHANNEL_COMMAND = TRUE, RADIO_CHANNEL_MP = TRUE, SQUAD_MARINE_1 = TRUE, SQUAD_MARINE_2 = TRUE, SQUAD_MARINE_3 = TRUE, SQUAD_MARINE_4 = TRUE, SQUAD_MARINE_5 = TRUE, SQUAD_MARINE_CRYO = TRUE, RADIO_CHANNEL_ENGI = TRUE, RADIO_CHANNEL_MEDSCI = TRUE, RADIO_CHANNEL_REQ = TRUE, RADIO_CHANNEL_JTAC = TRUE, RADIO_CHANNEL_INTEL = TRUE, RADIO_CHANNEL_WY = TRUE)
+ translate_apollo = TRUE
// MARINE SQUADS
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index 4b7223c3eb2e..20e4ab616218 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -418,25 +418,6 @@
/obj/item/device/radio/headset/binary
initial_keys = list(/obj/item/device/encryptionkey/binary)
-/obj/item/device/radio/headset/ai_integrated //No need to care about icons, it should be hidden inside the AI anyway.
- name = "AI Subspace Transceiver"
- desc = "Integrated AI radio transceiver."
- icon = 'icons/obj/items/robot_component.dmi'
- icon_state = "radio"
- item_state = "headset"
- item_icons = list(
- WEAR_L_HAND = 'icons/mob/humans/onmob/inhands/equipment/devices_lefthand.dmi',
- WEAR_R_HAND = 'icons/mob/humans/onmob/inhands/equipment/devices_righthand.dmi',
- )
- initial_keys = list(/obj/item/device/encryptionkey/ai_integrated)
- var/myAi = null // Atlantis: Reference back to the AI which has this radio.
- var/disabledAi = 0 // Atlantis: Used to manually disable AI's integrated radio via intellicard menu.
-
-/obj/item/device/radio/headset/ai_integrated/receive_range(freq, level)
- if (disabledAi)
- return -1 //Transceiver Disabled.
- return ..(freq, level, 1)
-
//MARINE HEADSETS
/obj/item/device/radio/headset/almayer
@@ -670,7 +651,7 @@
)
/obj/item/device/radio/headset/almayer/mcom/ai
- initial_keys = list(/obj/item/device/encryptionkey/mcom/ai)
+ initial_keys = list(/obj/item/device/encryptionkey/cmpcom/synth/ai)
volume = RADIO_VOLUME_CRITICAL
/obj/item/device/radio/headset/almayer/marine
@@ -680,7 +661,7 @@
name = "radio headset"
desc = "A radio headset."
frequency = CIA_FREQ
- initial_keys = list(/obj/item/device/encryptionkey/cia, /obj/item/device/encryptionkey/soc, /obj/item/device/encryptionkey/listening_bug/freq_a)
+ initial_keys = list(/obj/item/device/encryptionkey/cia, /obj/item/device/encryptionkey/soc, /obj/item/device/encryptionkey/public)
//############################## ALPHA ###############################
diff --git a/code/game/objects/items/devices/radio/listening_bugs.dm b/code/game/objects/items/devices/radio/listening_bugs.dm
index a87c19245ac3..b41efc96fa74 100644
--- a/code/game/objects/items/devices/radio/listening_bugs.dm
+++ b/code/game/objects/items/devices/radio/listening_bugs.dm
@@ -273,12 +273,17 @@
-///An automatically active bug used to listen to things by a Fax Responder.
+///An automatically active bug used to listen to things by a Fax Responder. Mapping side, not intended for spawning in manually.
/obj/item/device/radio/listening_bug/radio_linked/fax
name = "Comms Relay Device"
subspace_switchable = FALSE
broadcasting = TRUE
bug_broadcast_level = LISTENING_BUG_NEVER //Don't want fax responder devices broadcasting to ghosts because it will duplicate a lot of messages every round all the time.
+ alpha = 0
+ mouse_opacity = FALSE
+ anchored = TRUE
+ explo_proof = TRUE
+ emp_proof = TRUE
/obj/item/device/radio/listening_bug/radio_linked/fax/wy
frequency = FAX_WY_FREQ
diff --git a/code/modules/admin/tabs/event_tab.dm b/code/modules/admin/tabs/event_tab.dm
index be2a44e11439..8f79a083dbb2 100644
--- a/code/modules/admin/tabs/event_tab.dm
+++ b/code/modules/admin/tabs/event_tab.dm
@@ -359,7 +359,7 @@
message_admins("[key_name_admin(usr)] admin-started self-destruct system.")
/client/proc/view_faxes()
- set name = "View Faxes"
+ set name = "Reply to Faxes"
set desc = "View faxes from this round"
set category = "Admin.Events"
diff --git a/code/modules/admin/topic/topic.dm b/code/modules/admin/topic/topic.dm
index 69d60e69cc3a..91585ba99320 100644
--- a/code/modules/admin/topic/topic.dm
+++ b/code/modules/admin/topic/topic.dm
@@ -1270,20 +1270,25 @@
to_chat(H, "You hear something crackle in your headset for a moment before a voice speaks. \"Please stand by for a message from your benefactor. Message as follows, agent. \"[input]\" Message ends.\"")
else if(href_list["UpdateFax"])
- var/obj/structure/machinery/faxmachine/fax = locate(href_list["originfax"])
- fax.update_departments()
+ var/obj/structure/machinery/faxmachine/origin_fax = locate(href_list["originfax"])
+ origin_fax.update_departments()
else if(href_list["PressFaxReply"])
- var/mob/living/carbon/human/H = locate(href_list["PressFaxReply"])
- var/obj/structure/machinery/faxmachine/fax = locate(href_list["originfax"])
+ var/mob/user = usr
+ if(!user.client || !CLIENT_IS_STAFF(user.client))
+ to_chat(user, SPAN_WARNING("You cannot send fax replies!"))
+ return FALSE
+
+ var/mob/living/carbon/human/target_human = locate(href_list["PressFaxReply"])
+ var/obj/structure/machinery/faxmachine/origin_fax = locate(href_list["originfax"])
- var/template_choice = tgui_input_list(usr, "Use which template or roll your own?", "Fax Templates", list("Template", "Custom"))
+ var/template_choice = tgui_input_list(user, "Use which template or roll your own?", "Fax Templates", list("Template", "Custom"))
if(!template_choice) return
var/datum/fax/fax_message
var/organization_type = ""
switch(template_choice)
if("Custom")
- var/input = input(src.owner, "Please enter a message to reply to [key_name(H)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use for line breaks.", "Outgoing message from Press", "") as message|null
+ var/input = input(src.owner, "Please enter a message to reply to [key_name(target_human)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use for line breaks.", "Outgoing message from Press", "") as message|null
if(!input)
return
fax_message = new(input)
@@ -1292,9 +1297,9 @@
if(!subject)
return
var/addressed_to = ""
- var/address_option = tgui_input_list(usr, "Address it to the sender or custom?", "Fax Template", list("Sender", "Custom"))
+ var/address_option = tgui_input_list(user, "Address it to the sender or custom?", "Fax Template", list("Sender", "Custom"))
if(address_option == "Sender")
- addressed_to = "[H.real_name]"
+ addressed_to = "[target_human.real_name]"
else if(address_option == "Custom")
addressed_to = input(src.owner, "Enter Addressee Line", "Outgoing message from Press", "") as message|null
if(!addressed_to)
@@ -1312,60 +1317,29 @@
return
fax_message = new(generate_templated_fax(0, organization_type, subject, addressed_to, message_body, sent_by, "Editor in Chief", organization_type))
- show_browser(usr, "[fax_message.data]", "pressfaxpreview", "size=500x400")
- var/send_choice = tgui_input_list(usr, "Send this fax?", "Fax Template", list("Send", "Cancel"))
+ show_browser(user, "[fax_message.data]", "pressfaxpreview", "size=500x400")
+ var/send_choice = tgui_input_list(usr, "Send this fax?", "Fax Confirmation", list("Send", "Cancel"))
if(send_choice != "Send")
return
- GLOB.fax_contents += fax_message // save a copy
- var/customname = input(src.owner, "Pick a title for the report", "Title") as text|null
-
- GLOB.PressFaxes.Add("\[view '[customname]' from [key_name(usr)] at [time2text(world.timeofday, "hh:mm:ss")]\]")
-
- var/msg_ghost = SPAN_NOTICE("PRESS REPLY: ")
- msg_ghost += "Transmitting '[customname]' via secure connection ... "
- msg_ghost += "view message"
- announce_fax(msg_ghost = msg_ghost)
-
- for(var/obj/structure/machinery/faxmachine/F in GLOB.machines)
- if(F == fax)
- if(!(F.inoperable()))
-
- // animate! it's alive!
- flick("faxreceive", F)
+ var/is_priority_fax = tgui_alert(usr, "Is this a priority fax?", "Priority Fax?", list("Yes", "No"))
- // give the sprite some time to flick
- spawn(20)
- var/obj/item/paper/P = new /obj/item/paper( F.loc )
- P.name = "[organization_type] - [customname]"
- P.info = fax_message.data
- P.update_icon()
-
- playsound(F.loc, "sound/machines/fax.ogg", 15)
-
- // Stamps
- var/image/stampoverlay = image('icons/obj/items/paper.dmi')
- stampoverlay.icon_state = "paper_stamp-rd"
- if(!P.stamped)
- P.stamped = new
- P.stamped += /obj/item/tool/stamp
- P.overlays += stampoverlay
- P.stamps += "This paper has been stamped by the Free Press Quantum Relay."
-
- to_chat(src.owner, "Message reply to transmitted successfully.")
- message_admins(SPAN_STAFF_IC("[key_name_admin(src.owner)] replied to a fax message from [key_name_admin(H)]"), 1)
- return
- to_chat(src.owner, "/red Unable to locate fax!")
+ send_admin_fax("Press", fax_message, origin_fax, is_priority_fax, target_human, organization_type)
else if(href_list["USCMFaxReply"])
- var/mob/living/carbon/human/H = locate(href_list["USCMFaxReply"])
- var/obj/structure/machinery/faxmachine/fax = locate(href_list["originfax"])
+ var/mob/user = usr
+ if(!user.client || !CLIENT_IS_STAFF(user.client))
+ to_chat(user, SPAN_WARNING("You cannot send fax replies!"))
+ return FALSE
+
+ var/mob/living/carbon/human/target_human = locate(href_list["USCMFaxReply"])
+ var/obj/structure/machinery/faxmachine/origin_fax = locate(href_list["originfax"])
- var/template_choice = tgui_input_list(usr, "Use which template or roll your own?", "Fax Templates", list("USCM High Command", "USCM Provost General", "Custom"))
+ var/template_choice = tgui_input_list(user, "Use which template or roll your own?", "Fax Templates", list("USCM High Command", "USCM Provost General", "Custom"))
if(!template_choice) return
var/datum/fax/fax_message
switch(template_choice)
if("Custom")
- var/input = input(src.owner, "Please enter a message to reply to [key_name(H)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use for line breaks.", "Outgoing message from USCM", "") as message|null
+ var/input = input(src.owner, "Please enter a message to reply to [key_name(target_human)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use for line breaks.", "Outgoing message from USCM", "") as message|null
if(!input)
return
fax_message = new(input)
@@ -1374,9 +1348,9 @@
if(!subject)
return
var/addressed_to = ""
- var/address_option = tgui_input_list(usr, "Address it to the sender or custom?", "Fax Template", list("Sender", "Custom"))
+ var/address_option = tgui_input_list(user, "Address it to the sender or custom?", "Fax Template", list("Sender", "Custom"))
if(address_option == "Sender")
- addressed_to = "[H.real_name]"
+ addressed_to = "[target_human.real_name]"
else if(address_option == "Custom")
addressed_to = input(src.owner, "Enter Addressee Line", "Outgoing message from USCM", "") as message|null
if(!addressed_to)
@@ -1394,61 +1368,29 @@
sent_title = "USCM High Command"
fax_message = new(generate_templated_fax(0, "USCM CENTRAL COMMAND", subject,addressed_to, message_body,sent_by, sent_title, "United States Colonial Marine Corps"))
- show_browser(usr, "[fax_message.data]", "uscmfaxpreview", "size=500x400")
- var/send_choice = tgui_input_list(usr, "Send this fax?", "Fax Template", list("Send", "Cancel"))
+ show_browser(user, "[fax_message.data]", "uscmfaxpreview", "size=500x400")
+ var/send_choice = tgui_input_list(usr, "Send this fax?", "Fax Confirmation", list("Send", "Cancel"))
if(send_choice != "Send")
return
- GLOB.fax_contents += fax_message // save a copy
-
- var/customname = input(src.owner, "Pick a title for the report", "Title") as text|null
-
- GLOB.USCMFaxes.Add("\[view '[customname]' from [key_name(usr)] at [time2text(world.timeofday, "hh:mm:ss")]\]")
-
- var/msg_ghost = SPAN_NOTICE("USCM FAX REPLY: ")
- msg_ghost += "Transmitting '[customname]' via secure connection ... "
- msg_ghost += "view message"
- announce_fax( ,msg_ghost)
-
- for(var/obj/structure/machinery/faxmachine/F in GLOB.machines)
- if(F == fax)
- if(!(F.inoperable()))
-
- // animate! it's alive!
- flick("faxreceive", F)
+ var/is_priority_fax = tgui_alert(usr, "Is this a priority fax?", "Priority Fax?", list("Yes", "No"))
- // give the sprite some time to flick
- spawn(20)
- var/obj/item/paper/P = new /obj/item/paper( F.loc )
- P.name = "USCM High Command - [customname]"
- P.info = fax_message.data
- P.update_icon()
-
- playsound(F.loc, "sound/machines/fax.ogg", 15)
-
- // Stamps
- var/image/stampoverlay = image('icons/obj/items/paper.dmi')
- stampoverlay.icon_state = "paper_stamp-uscm"
- if(!P.stamped)
- P.stamped = new
- P.stamped += /obj/item/tool/stamp
- P.overlays += stampoverlay
- P.stamps += "This paper has been stamped by the USCM High Command Quantum Relay."
-
- to_chat(src.owner, "Message reply to transmitted successfully.")
- message_admins(SPAN_STAFF_IC("[key_name_admin(src.owner)] replied to a fax message from [key_name_admin(H)]"), 1)
- return
- to_chat(src.owner, "/red Unable to locate fax!")
+ send_admin_fax(FACTION_MARINE, fax_message, origin_fax, is_priority_fax, target_human)
else if(href_list["WYFaxReply"])
- var/mob/living/carbon/human/H = locate(href_list["WYFaxReply"])
- var/obj/structure/machinery/faxmachine/fax = locate(href_list["originfax"])
+ var/mob/user = usr
+ if(!user.client || !CLIENT_IS_STAFF(user.client))
+ to_chat(user, SPAN_WARNING("You cannot send fax replies!"))
+ return FALSE
+
+ var/mob/living/carbon/human/target_human = locate(href_list["WYFaxReply"])
+ var/obj/structure/machinery/faxmachine/origin_fax = locate(href_list["originfax"])
- var/template_choice = tgui_input_list(usr, "Use the template or roll your own?", "Fax Template", list("Template", "Custom"))
+ var/template_choice = tgui_input_list(user, "Use the template or roll your own?", "Fax Template", list("Template", "Custom"))
if(!template_choice) return
var/datum/fax/fax_message
switch(template_choice)
if("Custom")
- var/input = input(src.owner, "Please enter a message to reply to [key_name(H)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use for line breaks.", "Outgoing message from Weyland-Yutani", "") as message|null
+ var/input = input(src.owner, "Please enter a message to reply to [key_name(target_human)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use for line breaks.", "Outgoing message from Weyland-Yutani", "") as message|null
if(!input)
return
fax_message = new(input)
@@ -1457,9 +1399,9 @@
if(!subject)
return
var/addressed_to = ""
- var/address_option = tgui_input_list(usr, "Address it to the sender or custom?", "Fax Template", list("Sender", "Custom"))
+ var/address_option = tgui_input_list(user, "Address it to the sender or custom?", "Fax Template", list("Sender", "Custom"))
if(address_option == "Sender")
- addressed_to = "[H.real_name]"
+ addressed_to = "[target_human.real_name]"
else if(address_option == "Custom")
addressed_to = input(src.owner, "Enter Addressee Line", "Outgoing message from Weyland-Yutani", "") as message|null
if(!addressed_to)
@@ -1473,64 +1415,29 @@
if(!sent_by)
return
fax_message = new(generate_templated_fax(1, "WEYLAND-YUTANI CORPORATE AFFAIRS - [MAIN_SHIP_NAME]", subject, addressed_to, message_body, sent_by, "Corporate Affairs Director", "Weyland-Yutani"))
- show_browser(usr, "[fax_message.data]", "clfaxpreview", "size=500x400")
- var/send_choice = tgui_input_list(usr, "Send this fax?", "Fax Confirmation", list("Send", "Cancel"))
+ show_browser(user, "[fax_message.data]", "clfaxpreview", "size=500x400")
+ var/send_choice = tgui_input_list(user, "Send this fax?", "Fax Confirmation", list("Send", "Cancel"))
if(send_choice != "Send")
return
- GLOB.fax_contents += fax_message // save a copy
-
- var/customname = input(src.owner, "Pick a title for the report", "Title") as text|null
- if(!customname)
- return
-
- GLOB.WYFaxes.Add("\[view '[customname]' from [key_name(usr)] at [time2text(world.timeofday, "hh:mm:ss")]\]") //Add replies so that mods know what the hell is goin on with the RP
-
- var/msg_ghost = SPAN_NOTICE("WEYLAND-YUTANI FAX REPLY: ")
- msg_ghost += "Transmitting '[customname]' via secure connection ... "
- msg_ghost += "view message"
- announce_fax( ,msg_ghost)
-
+ var/is_priority_fax = tgui_alert(usr, "Is this a priority fax?", "Priority Fax?", list("Yes", "No"))
- for(var/obj/structure/machinery/faxmachine/F in GLOB.machines)
- if(F == fax)
- if(!(F.inoperable()))
-
- // animate! it's alive!
- flick("faxreceive", F)
-
- // give the sprite some time to flick
- spawn(20)
- var/obj/item/paper/P = new /obj/item/paper( F.loc )
- P.name = "Weyland-Yutani - [customname]"
- P.info = fax_message.data
- P.update_icon()
-
- playsound(F.loc, "sound/machines/fax.ogg", 15)
-
- // Stamps
- var/image/stampoverlay = image('icons/obj/items/paper.dmi')
- stampoverlay.icon_state = "paper_stamp-weyyu"
- if(!P.stamped)
- P.stamped = new
- P.stamped += /obj/item/tool/stamp
- P.overlays += stampoverlay
- P.stamps += "This paper has been stamped and encrypted by the Weyland-Yutani Quantum Relay (tm)."
-
- to_chat(src.owner, "Message reply to transmitted successfully.")
- message_admins(SPAN_STAFF_IC("[key_name_admin(src.owner)] replied to a fax message from [key_name_admin(H)]"), 1)
- return
- to_chat(src.owner, "/red Unable to locate fax!")
+ send_admin_fax(FACTION_WY, fax_message, origin_fax, is_priority_fax, target_human)
else if(href_list["TWEFaxReply"])
- var/mob/living/carbon/human/H = locate(href_list["TWEFaxReply"])
- var/obj/structure/machinery/faxmachine/fax = locate(href_list["originfax"])
+ var/mob/user = usr
+ if(!user.client || !CLIENT_IS_STAFF(user.client))
+ to_chat(user, SPAN_WARNING("You cannot send fax replies!"))
+ return FALSE
+
+ var/mob/living/carbon/human/target_human = locate(href_list["TWEFaxReply"])
+ var/obj/structure/machinery/faxmachine/origin_fax = locate(href_list["originfax"])
- var/template_choice = tgui_input_list(usr, "Use the template or roll your own?", "Fax Template", list("Template", "Custom"))
+ var/template_choice = tgui_input_list(user, "Use the template or roll your own?", "Fax Template", list("Template", "Custom"))
if(!template_choice) return
var/datum/fax/fax_message
switch(template_choice)
if("Custom")
- var/input = input(src.owner, "Please enter a message to reply to [key_name(H)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use for line breaks.", "Outgoing message from TWE", "") as message|null
+ var/input = input(src.owner, "Please enter a message to reply to [key_name(target_human)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use for line breaks.", "Outgoing message from TWE", "") as message|null
if(!input)
return
fax_message = new(input)
@@ -1539,9 +1446,9 @@
if(!subject)
return
var/addressed_to = ""
- var/address_option = tgui_input_list(usr, "Address it to the sender or custom?", "Fax Template", list("Sender", "Custom"))
+ var/address_option = tgui_input_list(user, "Address it to the sender or custom?", "Fax Template", list("Sender", "Custom"))
if(address_option == "Sender")
- addressed_to = "[H.real_name]"
+ addressed_to = "[target_human.real_name]"
else if(address_option == "Custom")
addressed_to = input(src.owner, "Enter Addressee Line", "Outgoing message from TWE", "") as message|null
if(!addressed_to)
@@ -1555,63 +1462,29 @@
if(!sent_by)
return
fax_message = new(generate_templated_fax(0, "THREE WORLD EMPIRE - ROYAL MILITARY COMMAND", subject, addressed_to, message_body, sent_by, "Office of Military Communications", "Three World Empire"))
- show_browser(usr, "[fax_message.data]", "PREVIEW OF TWE FAX", "size=500x400")
- var/send_choice = tgui_input_list(usr, "Send this fax?", "Fax Confirmation", list("Send", "Cancel"))
+ show_browser(user, "[fax_message.data]", "PREVIEW OF TWE FAX", "size=500x400")
+ var/send_choice = tgui_input_list(user, "Send this fax?", "Fax Confirmation", list("Send", "Cancel"))
if(send_choice != "Send")
return
- GLOB.fax_contents += fax_message // save a copy
-
- var/customname = input(src.owner, "Pick a title for the report", "Title") as text|null
- if(!customname)
- return
-
- GLOB.TWEFaxes.Add("\[view '[customname]' from [key_name(usr)] at [time2text(world.timeofday, "hh:mm:ss")]\]") //Add replies so that mods know what the hell is goin on with the RP
+ var/is_priority_fax = tgui_alert(usr, "Is this a priority fax?", "Priority Fax?", list("Yes", "No"))
- var/msg_ghost = SPAN_NOTICE("THREE WORLD EMPIRE FAX REPLY: ")
- msg_ghost += "Transmitting '[customname]' via secure connection ... "
- msg_ghost += "view message"
- announce_fax( ,msg_ghost)
-
- for(var/obj/structure/machinery/faxmachine/F in GLOB.machines)
- if(F == fax)
- if(!(F.inoperable()))
-
- // animate! it's alive!
- flick("faxreceive", F)
-
- // give the sprite some time to flick
- spawn(20)
- var/obj/item/paper/P = new /obj/item/paper( F.loc )
- P.name = "Three World Empire - [customname]"
- P.info = fax_message.data
- P.update_icon()
-
- playsound(F.loc, "sound/machines/fax.ogg", 15)
-
- // Stamps
- var/image/stampoverlay = image('icons/obj/items/paper.dmi')
- stampoverlay.icon_state = "paper_stamp-twe"
- if(!P.stamped)
- P.stamped = new
- P.stamped += /obj/item/tool/stamp
- P.overlays += stampoverlay
- P.stamps += "This paper has been stamped by the Three World Empire Quantum Relay (tm)."
-
- to_chat(src.owner, "Message reply to transmitted successfully.")
- message_admins(SPAN_STAFF_IC("[key_name_admin(src.owner)] replied to a fax message from [key_name_admin(H)]"), 1)
- return
- to_chat(src.owner, "/red Unable to locate fax!")
+ send_admin_fax(FACTION_TWE, fax_message, origin_fax, is_priority_fax, target_human)
else if(href_list["UPPFaxReply"])
- var/mob/living/carbon/human/H = locate(href_list["UPPFaxReply"])
- var/obj/structure/machinery/faxmachine/fax = locate(href_list["originfax"])
+ var/mob/user = usr
+ if(!user.client || !CLIENT_IS_STAFF(user.client))
+ to_chat(user, SPAN_WARNING("You cannot send fax replies!"))
+ return FALSE
+
+ var/mob/living/carbon/human/target_human = locate(href_list["UPPFaxReply"])
+ var/obj/structure/machinery/faxmachine/origin_fax = locate(href_list["originfax"])
- var/template_choice = tgui_input_list(usr, "Use the template or roll your own?", "Fax Template", list("Template", "Custom"))
+ var/template_choice = tgui_input_list(user, "Use the template or roll your own?", "Fax Template", list("Template", "Custom"))
if(!template_choice) return
var/datum/fax/fax_message
switch(template_choice)
if("Custom")
- var/input = input(src.owner, "Please enter a message to reply to [key_name(H)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use for line breaks.", "Outgoing message from UPP", "") as message|null
+ var/input = input(src.owner, "Please enter a message to reply to [key_name(target_human)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use for line breaks.", "Outgoing message from UPP", "") as message|null
if(!input)
return
fax_message = new(input)
@@ -1620,9 +1493,9 @@
if(!subject)
return
var/addressed_to = ""
- var/address_option = tgui_input_list(usr, "Address it to the sender or custom?", "Fax Template", list("Sender", "Custom"))
+ var/address_option = tgui_input_list(user, "Address it to the sender or custom?", "Fax Template", list("Sender", "Custom"))
if(address_option == "Sender")
- addressed_to = "[H.real_name]"
+ addressed_to = "[target_human.real_name]"
else if(address_option == "Custom")
addressed_to = input(src.owner, "Enter Addressee Line", "Outgoing message from UPP", "") as message|null
if(!addressed_to)
@@ -1636,63 +1509,29 @@
if(!sent_by)
return
fax_message = new(generate_templated_fax(0, "UNION OF PROGRESSIVE PEOPLES - MILITARY HIGH KOMMAND", subject, addressed_to, message_body, sent_by, "Military High Kommand", "Union of Progressive Peoples"))
- show_browser(usr, "[fax_message.data]", "PREVIEW OF UPP FAX", "size=500x400")
- var/send_choice = tgui_input_list(usr, "Send this fax?", "Fax Confirmation", list("Send", "Cancel"))
+ show_browser(user, "[fax_message.data]", "PREVIEW OF UPP FAX", "size=500x400")
+ var/send_choice = tgui_input_list(user, "Send this fax?", "Fax Confirmation", list("Send", "Cancel"))
if(send_choice != "Send")
return
- GLOB.fax_contents += fax_message // save a copy
-
- var/customname = input(src.owner, "Pick a title for the report", "Title") as text|null
- if(!customname)
- return
-
- GLOB.UPPFaxes.Add("\[view '[customname]' from [key_name(usr)] at [time2text(world.timeofday, "hh:mm:ss")]\]") //Add replies so that mods know what the hell is goin on with the RP
-
- var/msg_ghost = SPAN_NOTICE("UNION OF PROGRESSIVE PEOPLES FAX REPLY: ")
- msg_ghost += "Transmitting '[customname]' via secure connection ... "
- msg_ghost += "view message"
- announce_fax( ,msg_ghost)
-
- for(var/obj/structure/machinery/faxmachine/F in GLOB.machines)
- if(F == fax)
- if(!(F.inoperable()))
-
- // animate! it's alive!
- flick("faxreceive", F)
-
- // give the sprite some time to flick
- spawn(20)
- var/obj/item/paper/P = new /obj/item/paper( F.loc )
- P.name = "Union of Progressive Peoples - [customname]"
- P.info = fax_message.data
- P.update_icon()
-
- playsound(F.loc, "sound/machines/fax.ogg", 15)
+ var/is_priority_fax = tgui_alert(usr, "Is this a priority fax?", "Priority Fax?", list("Yes", "No"))
- // Stamps
- var/image/stampoverlay = image('icons/obj/items/paper.dmi')
- stampoverlay.icon_state = "paper_stamp-upp"
- if(!P.stamped)
- P.stamped = new
- P.stamped += /obj/item/tool/stamp
- P.overlays += stampoverlay
- P.stamps += "This paper has been stamped by the Union of Progressive Peoples Quantum Relay (tm)."
-
- to_chat(src.owner, "Message reply to transmitted successfully.")
- message_admins(SPAN_STAFF_IC("[key_name_admin(src.owner)] replied to a fax message from [key_name_admin(H)]"), 1)
- return
- to_chat(src.owner, "/red Unable to locate fax!")
+ send_admin_fax(FACTION_UPP, fax_message, origin_fax, is_priority_fax, target_human)
else if(href_list["CLFFaxReply"])
- var/mob/living/carbon/human/H = locate(href_list["CLFFaxReply"])
- var/obj/structure/machinery/faxmachine/fax = locate(href_list["originfax"])
+ var/mob/user = usr
+ if(!user.client || !CLIENT_IS_STAFF(user.client))
+ to_chat(user, SPAN_WARNING("You cannot send fax replies!"))
+ return FALSE
- var/template_choice = tgui_input_list(usr, "Use the template or roll your own?", "Fax Template", list("Template", "Custom"))
+ var/mob/living/carbon/human/target_human = locate(href_list["CLFFaxReply"])
+ var/obj/structure/machinery/faxmachine/origin_fax = locate(href_list["originfax"])
+
+ var/template_choice = tgui_input_list(user, "Use the template or roll your own?", "Fax Template", list("Template", "Custom"))
if(!template_choice) return
var/datum/fax/fax_message
switch(template_choice)
if("Custom")
- var/input = input(src.owner, "Please enter a message to reply to [key_name(H)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use for line breaks.", "Outgoing message from CLF", "") as message|null
+ var/input = input(src.owner, "Please enter a message to reply to [key_name(target_human)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use for line breaks.", "Outgoing message from CLF", "") as message|null
if(!input)
return
fax_message = new(input)
@@ -1701,9 +1540,9 @@
if(!subject)
return
var/addressed_to = ""
- var/address_option = tgui_input_list(usr, "Address it to the sender or custom?", "Fax Template", list("Sender", "Custom"))
+ var/address_option = tgui_input_list(user, "Address it to the sender or custom?", "Fax Template", list("Sender", "Custom"))
if(address_option == "Sender")
- addressed_to = "[H.real_name]"
+ addressed_to = "[target_human.real_name]"
else if(address_option == "Custom")
addressed_to = input(src.owner, "Enter Addressee Line", "Outgoing message from CLF", "") as message|null
if(!addressed_to)
@@ -1717,63 +1556,29 @@
if(!sent_by)
return
fax_message = new(generate_templated_fax(0, "COLONIAL LIBERATION FRONT - COLONIAL COUNCIL OF LIBERATION", subject, addressed_to, message_body, sent_by, "Guerilla Forces Command", "Colonial Liberation Front"))
- show_browser(usr, "[fax_message.data]", "PREVIEW OF CLF FAX", "size=500x400")
- var/send_choice = tgui_input_list(usr, "Send this fax?", "Fax Confirmation", list("Send", "Cancel"))
+ show_browser(user, "[fax_message.data]", "PREVIEW OF CLF FAX", "size=500x400")
+ var/send_choice = tgui_input_list(user, "Send this fax?", "Fax Confirmation", list("Send", "Cancel"))
if(send_choice != "Send")
return
- GLOB.fax_contents += fax_message // save a copy
-
- var/customname = input(src.owner, "Pick a title for the report", "Title") as text|null
- if(!customname)
- return
-
- GLOB.CLFFaxes.Add("\[view '[customname]' from [key_name(usr)] at [time2text(world.timeofday, "hh:mm:ss")]\]") //Add replies so that mods know what the hell is goin on with the RP
-
- var/msg_ghost = SPAN_NOTICE("COLONIAL LIBERATION FRONT FAX REPLY: ")
- msg_ghost += "Transmitting '[customname]' via secure connection ... "
- msg_ghost += "view message"
- announce_fax( ,msg_ghost)
-
- for(var/obj/structure/machinery/faxmachine/F in GLOB.machines)
- if(F == fax)
- if(!(F.inoperable()))
-
- // animate! it's alive!
- flick("faxreceive", F)
-
- // give the sprite some time to flick
- spawn(20)
- var/obj/item/paper/P = new /obj/item/paper( F.loc )
- P.name = "Colonial Liberation Front - [customname]"
- P.info = fax_message.data
- P.update_icon()
+ var/is_priority_fax = tgui_alert(usr, "Is this a priority fax?", "Priority Fax?", list("Yes", "No"))
- playsound(F.loc, "sound/machines/fax.ogg", 15)
-
- // Stamps
- var/image/stampoverlay = image('icons/obj/items/paper.dmi')
- stampoverlay.icon_state = "paper_stamp-clf"
- if(!P.stamped)
- P.stamped = new
- P.stamped += /obj/item/tool/stamp
- P.overlays += stampoverlay
- P.stamps += "This paper has been stamped and encrypted by the Colonial Liberation Front Quantum Relay (tm)."
-
- to_chat(src.owner, "Message reply to transmitted successfully.")
- message_admins(SPAN_STAFF_IC("[key_name_admin(src.owner)] replied to a fax message from [key_name_admin(H)]"), 1)
- return
- to_chat(src.owner, "/red Unable to locate fax!")
+ send_admin_fax(FACTION_CLF, fax_message, origin_fax, is_priority_fax, target_human)
else if(href_list["CMBFaxReply"])
- var/mob/living/carbon/human/H = locate(href_list["CMBFaxReply"])
- var/obj/structure/machinery/faxmachine/fax = locate(href_list["originfax"])
+ var/mob/user = usr
+ if(!user.client || !CLIENT_IS_STAFF(user.client))
+ to_chat(user, SPAN_WARNING("You cannot send fax replies!"))
+ return FALSE
+
+ var/mob/living/carbon/human/target_human = locate(href_list["CMBFaxReply"])
+ var/obj/structure/machinery/faxmachine/origin_fax = locate(href_list["originfax"])
- var/template_choice = tgui_input_list(usr, "Use the template or roll your own?", "Fax Template", list("Anchorpoint", "Custom"))
+ var/template_choice = tgui_input_list(user, "Use the template or roll your own?", "Fax Template", list("Anchorpoint", "Custom"))
if(!template_choice) return
var/datum/fax/fax_message
switch(template_choice)
if("Custom")
- var/input = input(src.owner, "Please enter a message to reply to [key_name(H)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use for line breaks.", "Outgoing message from The Colonial Marshal Bureau", "") as message|null
+ var/input = input(src.owner, "Please enter a message to reply to [key_name(target_human)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use for line breaks.", "Outgoing message from The Colonial Marshal Bureau", "") as message|null
if(!input)
return
fax_message = new(input)
@@ -1782,9 +1587,9 @@
if(!subject)
return
var/addressed_to = ""
- var/address_option = tgui_input_list(usr, "Address it to the sender or custom?", "Fax Template", list("Sender", "Custom"))
+ var/address_option = tgui_input_list(user, "Address it to the sender or custom?", "Fax Template", list("Sender", "Custom"))
if(address_option == "Sender")
- addressed_to = "[H.real_name]"
+ addressed_to = "[target_human.real_name]"
else if(address_option == "Custom")
addressed_to = input(src.owner, "Enter Addressee Line", "Outgoing message from The Colonial Marshal Bureau", "") as message|null
if(!addressed_to)
@@ -1798,53 +1603,13 @@
if(!sent_by)
return
fax_message = new(generate_templated_fax(0, "COLONIAL MARSHAL BUREAU INCIDENT COMMAND CENTER - ANCHORPOINT STATION", subject, addressed_to, message_body, sent_by, "Supervisory Deputy Marshal", "Colonial Marshal Bureau"))
- show_browser(usr, "[fax_message.data]", "PREVIEW OF CMB FAX", "size=500x400")
- var/send_choice = tgui_input_list(usr, "Send this fax?", "Fax Confirmation", list("Send", "Cancel"))
+ show_browser(user, "[fax_message.data]", "PREVIEW OF CMB FAX", "size=500x400")
+ var/send_choice = tgui_input_list(user, "Send this fax?", "Fax Confirmation", list("Send", "Cancel"))
if(send_choice != "Send")
return
- GLOB.fax_contents += fax_message // save a copy
-
- var/customname = input(src.owner, "Pick a title for the report", "Title") as text|null
- if(!customname)
- return
-
- GLOB.CMBFaxes.Add("\[view '[customname]' from [key_name(usr)] at [time2text(world.timeofday, "hh:mm:ss")]\]") //Add replies so that mods know what the hell is goin on with the RP
-
- var/msg_ghost = SPAN_NOTICE("COLONIAL MARSHAL BUREAU FAX REPLY: ")
- msg_ghost += "Transmitting '[customname]' via secure connection ... "
- msg_ghost += "view message"
- announce_fax( ,msg_ghost)
-
-
- for(var/obj/structure/machinery/faxmachine/F in GLOB.machines)
- if(F == fax)
- if(!(F.inoperable()))
+ var/is_priority_fax = tgui_alert(usr, "Is this a priority fax?", "Priority Fax?", list("Yes", "No"))
- // animate! it's alive!
- flick("faxreceive", F)
-
- // give the sprite some time to flick
- spawn(20)
- var/obj/item/paper/P = new /obj/item/paper( F.loc )
- P.name = "Colonial Marshal Bureau - [customname]"
- P.info = fax_message.data
- P.update_icon()
-
- playsound(F.loc, "sound/machines/fax.ogg", 15)
-
- // Stamps
- var/image/stampoverlay = image('icons/obj/items/paper.dmi')
- stampoverlay.icon_state = "paper_stamp-cmb"
- if(!P.stamped)
- P.stamped = new
- P.stamped += /obj/item/tool/stamp
- P.overlays += stampoverlay
- P.stamps += "This paper has been stamped by The Office of the Colonial Marshals."
-
- to_chat(src.owner, "Message reply to transmitted successfully.")
- message_admins(SPAN_STAFF_IC("[key_name_admin(src.owner)] replied to a fax message from [key_name_admin(H)]"), 1)
- return
- to_chat(src.owner, "/red Unable to locate fax!")
+ send_admin_fax(FACTION_MARSHAL, fax_message, origin_fax, is_priority_fax, target_human)
else if(href_list["customise_paper"])
if(!check_rights(R_MOD))
@@ -2404,3 +2169,106 @@
continue
temp += J.title
return temp
+
+
+
+
+/datum/admins/proc/send_admin_fax(sending_faction, datum/fax/fax_message, obj/structure/machinery/faxmachine/origin_fax, sending_priority, mob/living/carbon/human/target_human, press_organization)
+ GLOB.fax_contents += fax_message // save a copy
+
+ var/customname = input(src.owner, "Pick a title for the report", "Title") as text|null
+ if(!customname)
+ return
+
+ var/reply_log = "\[view '[customname]' from [key_name(usr)] at [time2text(world.timeofday, "hh:mm:ss")]\]" //Add replies so that mods know what the hell is goin on with the RP
+
+ var/faction_ghost_header
+ var/faction_prefix
+ var/fax_stamp_icon
+ var/fax_stamp_print
+ switch(sending_faction)
+ if(FACTION_MARSHAL)
+ GLOB.CMBFaxes.Add(reply_log)
+ faction_ghost_header = "COLONIAL MARSHAL BUREAU FAX REPLY: "
+ faction_prefix = "Colonial Marshal Bureau"
+ fax_stamp_icon = "paper_stamp-cmb"
+ fax_stamp_print = "This paper has been stamped by [FAX_NET_CMB]."
+ if(FACTION_MARINE)
+ GLOB.USCMFaxes.Add(reply_log)
+ faction_ghost_header = "USCM FAX REPLY: "
+ faction_prefix = "USCM High Command"
+ fax_stamp_icon = "paper_stamp-uscm"
+ fax_stamp_print = "This paper has been stamped by the [FAX_NET_USCM_HC]."
+ if(FACTION_CLF)
+ GLOB.CLFFaxes.Add(reply_log)
+ faction_ghost_header = "COLONIAL LIBERATION FRONT FAX REPLY: "
+ faction_prefix = "Colonial Liberation Front"
+ fax_stamp_icon = "paper_stamp-clf"
+ fax_stamp_print = "This paper has been stamped by the [FAX_NET_CLF_HC]."
+ if(FACTION_UPP)
+ GLOB.UPPFaxes.Add(reply_log)
+ faction_ghost_header = "UNION OF PROGRESSIVE PEOPLES FAX REPLY: "
+ faction_prefix = "Union of Progressive Peoples"
+ fax_stamp_icon = "paper_stamp-upp"
+ fax_stamp_print = "This paper has been stamped by the [FAX_NET_UPP_HC]."
+ if(FACTION_TWE)
+ GLOB.TWEFaxes.Add(reply_log)
+ faction_ghost_header = "THREE WORLD EMPIRE FAX REPLY: "
+ faction_prefix = "Three World Empire"
+ fax_stamp_icon = "paper_stamp-twe"
+ fax_stamp_print = "This paper has been stamped by the [FAX_NET_TWE_HC]."
+ if(FACTION_WY)
+ GLOB.WYFaxes.Add(reply_log)
+ faction_ghost_header = "WEYLAND-YUTANI FAX REPLY: "
+ faction_prefix = "Weyland-Yutani"
+ fax_stamp_icon = "paper_stamp-weyyu"
+ fax_stamp_print = "This paper has been stamped by the [FAX_NET_WY_HC]."
+ if("Press")
+ GLOB.PressFaxes.Add(reply_log)
+ faction_ghost_header = "PRESS FAX REPLY: "
+ faction_prefix = press_organization ? press_organization : "Free Press"
+ fax_stamp_icon = "paper_stamp-rd"
+ fax_stamp_print = "This paper has been stamped by the [FAX_NET_PRESS_HC]."
+
+ var/msg_ghost = SPAN_NOTICE(faction_ghost_header)
+ msg_ghost += "Transmitting '[customname]' via secure connection ... "
+ msg_ghost += "view message"
+ announce_fax( ,msg_ghost)
+
+
+ for(var/obj/structure/machinery/faxmachine/target_fax in GLOB.machines)
+ if(target_fax == origin_fax)
+ if(!(target_fax.inoperable()))
+
+ // animate! it's alive!
+ flick("faxreceive", target_fax)
+
+ // give the sprite some time to flick
+
+ sleep(2 SECONDS)
+ var/obj/item/paper/P = new /obj/item/paper(target_fax.loc)
+ P.name = "[faction_prefix] - [customname]"
+ P.info = fax_message.data
+ P.update_icon()
+
+ playsound(target_fax.loc, "sound/machines/fax.ogg", 15)
+
+ // Stamps
+ var/image/stampoverlay = image('icons/obj/items/paper.dmi')
+ stampoverlay.icon_state = fax_stamp_icon
+ if(!P.stamped)
+ P.stamped = new
+ P.stamped += /obj/item/tool/stamp
+ P.overlays += stampoverlay
+ P.stamps += fax_stamp_print
+ if(sending_priority == "Yes")
+ playsound(target_fax.loc, "sound/machines/twobeep.ogg", 45)
+ target_fax.langchat_speech("beeps with a priority message", get_mobs_in_view(GLOB.world_view_size, target_fax), GLOB.all_languages, skip_language_check = TRUE, animation_style = LANGCHAT_FAST_POP, additional_styles = list("langchat_small", "emote"))
+ target_fax.visible_message("[SPAN_BOLD(target_fax)] beeps with a priority message.")
+ if(target_fax.radio_alert_tag != null)
+ ai_silent_announcement("COMMUNICATIONS REPORT: Fax Machine [target_fax.machine_id_tag], [target_fax.sub_name ? "[target_fax.sub_name]" : ""], now receiving priority fax.", "[target_fax.radio_alert_tag]")
+
+ to_chat(src.owner, "Message reply to transmitted successfully.")
+ message_admins(SPAN_STAFF_IC("[key_name_admin(src.owner)] replied to a fax message from [key_name_admin(target_human)]"), 1)
+ return
+ to_chat(src.owner, SPAN_RED("Unable to locate fax!"))
diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm
index 68ee20e0ae6e..091d4b258fe2 100644
--- a/code/modules/clothing/head/helmet.dm
+++ b/code/modules/clothing/head/helmet.dm
@@ -405,6 +405,9 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
var/start_down_visor_type
///Refs of observing consoles
var/list/overwatch_consoles = list()
+ ///Faction owners of the inbuilt camera
+ var/list/camera_factions = FACTION_LIST_MARINE_WY
+
/obj/item/clothing/head/helmet/marine/Initialize(mapload, new_protection[] = list(MAP_ICE_COLONY = ICE_PLANET_MIN_COLD_PROT))
. = ..()
@@ -427,8 +430,8 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
pockets.bypass_w_limit = GLOB.allowed_helmet_items
pockets.max_storage_space = storage_max_storage_space
- camera = new /obj/structure/machinery/camera(src)
- camera.network = list(CAMERA_NET_OVERWATCH)
+ camera = new /obj/structure/machinery/camera/overwatch(src)
+ camera.owner_factions = camera_factions
for(var/obj/visor as anything in built_in_visors)
visor.forceMove(src)
@@ -1144,6 +1147,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
flags_inventory = BLOCKSHARPOBJ
flags_inv_hide = NO_FLAGS
flags_marine_helmet = NO_FLAGS
+ camera_factions = FACTION_LIST_WY
/obj/item/clothing/head/helmet/marine/veteran/pmc/leader
name = "\improper PMC beret"
@@ -1244,6 +1248,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
item_icons = list(
WEAR_HEAD = 'icons/mob/humans/onmob/clothing/head/misc_ert_colony.dmi',
)
+ camera_factions = FACTION_LIST_COLONY
//=============================//CMB\\==================================\\
//=======================================================================\\
@@ -1296,6 +1301,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
armor_bomb = CLOTHING_ARMOR_MEDIUM
armor_rad = CLOTHING_ARMOR_MEDIUM
flags_marine_helmet = HELMET_GARB_OVERLAY|HELMET_DAMAGE_OVERLAY
+ camera_factions = list(FACTION_DUTCH)
/obj/item/clothing/head/helmet/marine/veteran/dutch/cap
name = "\improper Dutch's Dozen cap"
@@ -1336,6 +1342,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
armor_internaldamage = CLOTHING_ARMOR_HIGH
min_cold_protection_temperature = ICE_PLANET_MIN_COLD_PROT
clothing_traits = list(TRAIT_EAR_PROTECTION) //the sprites clearly fully cover the ears and most of the head
+ camera_factions = FACTION_LIST_UPP
/obj/item/clothing/head/helmet/marine/veteran/UPP/engi
name = "\improper UM4-V helmet"
@@ -1381,7 +1388,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
flags_inv_hide = HIDEEARS
/obj/item/clothing/head/uppcap/civi
- name = "\improper UL2 UPP cap"
+ name = "\improper UL2C UPP cap"
desc = "UPP civilian headgear. It's of poor quality, and isn't expected to last all that long, however for as long as it's whole, it appears quite stylish."
icon_state = "upp_cap_civi"
@@ -1423,7 +1430,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
/obj/item/clothing/head/uppcap/ushanka/civi
- name = "\improper UL8c UPP ushanka"
+ name = "\improper UL8C UPP ushanka"
icon_state = "upp_ushanka_civi"
item_state = "upp_ushanka_civi"
original_state = "upp_ushanka_civi"
@@ -1438,6 +1445,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
WEAR_HEAD = 'icons/mob/humans/onmob/clothing/head/misc_ert_colony.dmi',
)
flags_marine_helmet = NO_FLAGS
+ camera_factions = FACTION_LIST_COLONY
//head rag
@@ -1566,8 +1574,9 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
flags_inventory = COVEREYES|COVERMOUTH|BLOCKSHARPOBJ
flags_inv_hide = HIDEEARS|HIDEEYES|HIDEFACE|HIDEMASK|HIDEALLHAIR
flags_marine_helmet = HELMET_DAMAGE_OVERLAY
+ camera_factions = FACTION_LIST_MERCENARY
-/obj/item/clothing/head/helmet/marine/veteran/mercenary
+/obj/item/clothing/head/helmet/marine/veteran/mercenary/heavy
name = "\improper Modified K12 ceramic helmet"
desc = "A sturdy helmet worn by an unknown mercenary group. Reinforced with extra plating."
armor_melee = CLOTHING_ARMOR_ULTRAHIGH
@@ -1588,6 +1597,8 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
armor_bomb = CLOTHING_ARMOR_MEDIUM
armor_internaldamage = CLOTHING_ARMOR_HIGHPLUS
+/obj/item/clothing/head/helmet/marine/veteran/mercenary/miner/clf
+ camera_factions = FACTION_LIST_CLF
/obj/item/clothing/head/helmet/marine/veteran/mercenary/support
name = "\improper Z7 helmet"
@@ -1629,6 +1640,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
var/mob/activator = null
var/active = FALSE
var/det_time = 40
+ camera_factions = list(FACTION_HEFA)
/obj/item/clothing/head/helmet/marine/specialist/hefa/Initialize(mapload, list/new_protection)
. = ..()
@@ -1745,6 +1757,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
flags_inv_hide = NO_FLAGS
flags_marine_helmet = NO_FLAGS
flags_atom = NO_NAME_OVERRIDE|NO_GAMEMODE_SKIN
+ camera_factions = FACTION_LIST_TWE
/obj/item/clothing/head/helmet/marine/veteran/royal_marine/breacher
name = "\improper L5A3 ballistic helmet"
diff --git a/code/modules/cm_tech/hologram.dm b/code/modules/cm_tech/hologram.dm
index 215578416007..4fbe0be20e28 100644
--- a/code/modules/cm_tech/hologram.dm
+++ b/code/modules/cm_tech/hologram.dm
@@ -18,6 +18,8 @@ GLOBAL_LIST_EMPTY_TYPED(hologram_list, /mob/hologram)
var/datum/action/leave_hologram/leave_button
///If can be detected on motion detectors.
var/motion_sensed = FALSE
+ ///If this hologram can hear speech.
+ var/hears_speech = FALSE
/mob/hologram/movement_delay()
. = -2 // Very fast speed, so they can navigate through easily, they can't ever have movement delay whilst as a hologram
diff --git a/code/modules/gear_presets/clf.dm b/code/modules/gear_presets/clf.dm
index 2e7977eeac93..70f0171a974e 100644
--- a/code/modules/gear_presets/clf.dm
+++ b/code/modules/gear_presets/clf.dm
@@ -995,7 +995,7 @@
access = get_access(ACCESS_LIST_CLF_ALL)
/datum/equipment_preset/clf/commander/load_gear(mob/living/carbon/human/new_human)
- new_human.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/marine/veteran/mercenary/miner(new_human), WEAR_HEAD)
+ new_human.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/marine/veteran/mercenary/miner/clf(new_human), WEAR_HEAD)
new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/CLF/command(new_human), WEAR_L_EAR)
new_human.equip_to_slot_or_del(new /obj/item/clothing/under/colonist/clf(new_human), WEAR_BODY)
new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/militia/smartgun(new_human), WEAR_JACKET)
@@ -1023,7 +1023,7 @@
list("Combat Pack", 0, /obj/item/storage/backpack/lightpack, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_MANDATORY),
list("HELMET (CHOOSE 1)", 0, null, null, null),
- list("Y8 Miner Helmet", 0, /obj/item/clothing/head/helmet/marine/veteran/mercenary/miner, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_REGULAR),
+ list("Y8 Miner Helmet", 0, /obj/item/clothing/head/helmet/marine/veteran/mercenary/miner/clf, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_REGULAR),
list("POUCHES (CHOOSE 2)", 0, null, null, null),
list("Bayonet Sheath", 0, /obj/item/storage/pouch/bayonet/upp, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
diff --git a/code/modules/gear_presets/fax_responders.dm b/code/modules/gear_presets/fax_responders.dm
index 1f1d27f3367b..0aaba046bd8c 100644
--- a/code/modules/gear_presets/fax_responders.dm
+++ b/code/modules/gear_presets/fax_responders.dm
@@ -16,6 +16,7 @@
idtype = /obj/item/card/id/lanyard
paygrades = list(PAY_SHORT_CIV = JOB_PLAYTIME_TIER_0)
+ languages = ALL_HUMAN_LANGUAGES
var/obj/item/device/radio/headset/headset_type = /obj/item/device/radio/headset
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index f605e68b689f..8010a51f0b47 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -388,28 +388,28 @@
the_hud = GLOB.huds[MOB_HUD_MEDICAL_OBSERVER]
the_hud.add_hud_to(src, src)
if("Security HUD")
- the_hud= GLOB.huds[MOB_HUD_SECURITY_ADVANCED]
+ the_hud = GLOB.huds[MOB_HUD_SECURITY_ADVANCED]
the_hud.add_hud_to(src, src)
if("Squad HUD")
- the_hud= GLOB.huds[MOB_HUD_FACTION_OBSERVER]
+ the_hud = GLOB.huds[MOB_HUD_FACTION_OBSERVER]
the_hud.add_hud_to(src, src)
if("Xeno Status HUD")
- the_hud= GLOB.huds[MOB_HUD_XENO_STATUS]
+ the_hud = GLOB.huds[MOB_HUD_XENO_STATUS]
the_hud.add_hud_to(src, src)
if("Faction UPP HUD")
- the_hud= GLOB.huds[MOB_HUD_FACTION_UPP]
+ the_hud = GLOB.huds[MOB_HUD_FACTION_UPP]
the_hud.add_hud_to(src, src)
if("Faction Wey-Yu HUD")
- the_hud= GLOB.huds[MOB_HUD_FACTION_WY]
+ the_hud = GLOB.huds[MOB_HUD_FACTION_WY]
the_hud.add_hud_to(src, src)
if("Faction TWE HUD")
- the_hud= GLOB.huds[MOB_HUD_FACTION_TWE]
+ the_hud = GLOB.huds[MOB_HUD_FACTION_TWE]
the_hud.add_hud_to(src, src)
if("Faction CLF HUD")
- the_hud= GLOB.huds[MOB_HUD_FACTION_CLF]
+ the_hud = GLOB.huds[MOB_HUD_FACTION_CLF]
the_hud.add_hud_to(src, src)
if(HUD_MENTOR_SIGHT)
- the_hud= GLOB.huds[MOB_HUD_NEW_PLAYER]
+ the_hud = GLOB.huds[MOB_HUD_NEW_PLAYER]
the_hud.add_hud_to(src, src)
see_invisible = INVISIBILITY_OBSERVER
@@ -923,6 +923,110 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
GLOB.xeno_tacmap_status.tgui_interact(src)
+/mob/dead/observer/verb/view_faxes()
+ set name = "View Sent Faxes"
+ set desc = "View faxes from this round"
+ set category = "Ghost.View"
+
+ var/list/options = list(
+ "Weyland-Yutani", "High Command", "Provost", "Press",
+ "Colonial Marshal Bureau", "Union of Progressive Peoples",
+ "Three World Empire", "Colonial Liberation Front",
+ "Other", "Cancel")
+ var/answer = tgui_input_list(src, "Which kind of faxes would you like to see?", "Faxes", options)
+ switch(answer)
+ if("Weyland-Yutani")
+ var/body = ""
+
+ for(var/text in GLOB.WYFaxes)
+ body += text
+ body += "
"
+
+ body += "
"
+ show_browser(src, body, "Faxes to Weyland-Yutani", "wyfaxviewer", "size=300x600")
+
+ if("High Command")
+ var/body = ""
+
+ for(var/text in GLOB.USCMFaxes)
+ body += text
+ body += "
"
+
+ body += "
"
+ show_browser(src, body, "Faxes to High Command", "uscmfaxviewer", "size=300x600")
+
+ if("Provost")
+ var/body = ""
+
+ for(var/text in GLOB.ProvostFaxes)
+ body += text
+ body += "
"
+
+ body += "
"
+ show_browser(src, body, "Faxes to the Provost Office", "provostfaxviewer", "size=300x600")
+
+ if("Press")
+ var/body = ""
+
+ for(var/text in GLOB.PressFaxes)
+ body += text
+ body += "
"
+
+ body += "
"
+ show_browser(src, body, "Faxes to Press organizations", "pressfaxviewer", "size=300x600")
+
+ if("Colonial Marshal Bureau")
+ var/body = ""
+
+ for(var/text in GLOB.CMBFaxes)
+ body += text
+ body += "
"
+
+ body += "
"
+ show_browser(src, body, "Faxes to the Colonial Marshal Bureau", "cmbfaxviewer", "size=300x600")
+
+ if("Union of Progressive Peoples")
+ var/body = ""
+
+ for(var/text in GLOB.UPPFaxes)
+ body += text
+ body += "
"
+
+ body += "
"
+ show_browser(src, body, "Faxes to the Union of Progressive Peoples", "uppfaxviewer", "size=300x600")
+
+ if("Three World Empire")
+ var/body = ""
+
+ for(var/text in GLOB.TWEFaxes)
+ body += text
+ body += "
"
+
+ body += "
"
+ show_browser(src, body, "Faxes to the Three World Empire", "twefaxviewer", "size=300x600")
+
+ if("Colonial Liberation Front")
+ var/body = ""
+
+ for(var/text in GLOB.CLFFaxes)
+ body += text
+ body += "
"
+
+ body += "
"
+ show_browser(src, body, "Faxes to the Colonial Liberation Front", "clffaxviewer", "size=300x600")
+
+ if("Other")
+ var/body = ""
+
+ for(var/text in GLOB.GeneralFaxes)
+ body += text
+ body += "