Files
Paradise/code/modules/paperwork/faxmachine.dm
S34N d006c249c3 Sprite tweak for long range and syndie fax machines (#16843)
* cuts down on sprite bloat, recolours faxes

* Apply suggestions from code review

Co-authored-by: SteelSlayer <42044220+SteelSlayer@users.noreply.github.com>

* more prominent syndie stripe

* long range tweak

* denth tweaks

Co-authored-by: SteelSlayer <42044220+SteelSlayer@users.noreply.github.com>
2021-10-17 11:12:14 +01:00

374 lines
13 KiB
Plaintext

GLOBAL_LIST_EMPTY(allfaxes)
GLOBAL_LIST_INIT(admin_departments, list("Central Command"))
GLOBAL_LIST_INIT(hidden_admin_departments, list("Syndicate"))
GLOBAL_LIST_EMPTY(alldepartments)
GLOBAL_LIST_EMPTY(hidden_departments)
GLOBAL_LIST_EMPTY(fax_blacklist)
/obj/machinery/photocopier/faxmachine
name = "fax machine"
icon = 'icons/obj/library.dmi'
icon_state = "fax"
insert_anim = "faxsend"
var/receive_anim = "faxsend"
pass_flags = PASSTABLE
var/fax_network = "Local Fax Network"
/// If true, prevents fax machine from sending messages to NT machines
var/syndie_restricted = FALSE
/// Can we send messages off-station?
var/long_range_enabled = FALSE
req_one_access = list(ACCESS_LAWYER, ACCESS_HEADS, ACCESS_ARMORY)
use_power = IDLE_POWER_USE
idle_power_usage = 30
active_power_usage = 200
/// ID card inserted into the machine, used to log in with
var/obj/item/card/id/scan = null
/// Whether the machine is "logged in" or not
var/authenticated = FALSE
/// Next world.time at which this fax machine can send a message to CC/syndicate
var/sendcooldown = 0
/// After sending a message to CC/syndicate, cannot send another to them for this many deciseconds
var/cooldown_time = 1800
/// Our department, determines whether this machine gets faxes sent to a department
var/department = "Unknown"
/// Target department to send outgoing faxes to
var/destination
/obj/machinery/photocopier/faxmachine/Initialize(mapload)
. = ..()
GLOB.allfaxes += src
update_network()
/obj/machinery/photocopier/faxmachine/Destroy()
GLOB.allfaxes -= src
return ..()
/obj/machinery/photocopier/faxmachine/proc/update_network()
if(department != "Unknown")
if(!(("[department]" in GLOB.alldepartments) || ("[department]" in GLOB.hidden_departments) || ("[department]" in GLOB.admin_departments) || ("[department]" in GLOB.hidden_admin_departments)))
GLOB.alldepartments |= department
/obj/machinery/photocopier/faxmachine/longrange
name = "long range fax machine"
fax_network = "Central Command Quantum Entanglement Network"
long_range_enabled = TRUE
/obj/machinery/photocopier/faxmachine/longrange/Initialize(mapload)
. = ..()
add_overlay("longfax")
/obj/machinery/photocopier/faxmachine/longrange/syndie
name = "syndicate long range fax machine"
emagged = TRUE
syndie_restricted = TRUE
req_one_access = list(ACCESS_SYNDICATE)
//No point setting fax network, being emagged overrides that anyway.
/obj/machinery/photocopier/faxmachine/longrange/syndie/Initialize(mapload)
. = ..()
add_overlay("syndiefax")
/obj/machinery/photocopier/faxmachine/longrange/syndie/update_network()
if(department != "Unknown")
GLOB.hidden_departments |= department
/obj/machinery/photocopier/faxmachine/attack_hand(mob/user)
ui_interact(user)
/obj/machinery/photocopier/faxmachine/attack_ghost(mob/user)
ui_interact(user)
/obj/machinery/photocopier/faxmachine/attackby(obj/item/item, mob/user, params)
if(istype(item,/obj/item/card/id) && !scan)
scan(item)
else if(istype(item, /obj/item/paper) || istype(item, /obj/item/photo) || istype(item, /obj/item/paper_bundle))
..()
SStgui.update_uis(src)
else
return ..()
/obj/machinery/photocopier/faxmachine/emag_act(mob/user)
if(!emagged)
emagged = 1
req_one_access = list()
to_chat(user, "<span class='notice'>The transmitters realign to an unknown source!</span>")
else
to_chat(user, "<span class='warning'>You swipe the card through [src], but nothing happens.</span>")
/obj/machinery/photocopier/faxmachine/proc/is_authenticated(mob/user)
if(authenticated)
return TRUE
else if(user.can_admin_interact())
return TRUE
return FALSE
/obj/machinery/photocopier/faxmachine/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "FaxMachine", name, 540, 300, master_ui, state)
ui.open()
/obj/machinery/photocopier/faxmachine/ui_data(mob/user)
var/list/data = list()
data["authenticated"] = is_authenticated(user)
data["realauth"] = authenticated
data["scan_name"] = scan ? scan.name : FALSE
data["nologin"] = !data["scan_name"] && !data["realauth"]
if(!data["authenticated"])
data["network"] = "Disconnected"
else if(!emagged)
data["network"] = fax_network
else
data["network"] = "ERR*?*%!*"
data["paper"] = copyitem ? copyitem.name : FALSE
data["paperinserted"] = copyitem ? TRUE : FALSE
data["destination"] = destination ? destination : FALSE
data["sendError"] = FALSE
if(stat & (BROKEN|NOPOWER))
data["sendError"] = "No Power"
else if(!data["authenticated"])
data["sendError"] = "Not Logged In"
else if(!data["paper"])
data["sendError"] = "Nothing Inserted"
else if(!data["destination"])
data["sendError"] = "Destination Not Set"
else if((destination in GLOB.admin_departments) || (destination in GLOB.hidden_admin_departments))
var/cooldown_seconds = cooldown_seconds()
if(cooldown_seconds)
data["sendError"] = "Re-aligning in [cooldown_seconds] seconds..."
return data
/obj/machinery/photocopier/faxmachine/ui_act(action, params)
if(..())
return
var/is_authenticated = is_authenticated(usr)
. = TRUE
switch(action)
if("scan") // insert/remove your ID card
scan()
if("auth") // log in/out
if(!is_authenticated && scan)
if(scan.registered_name in GLOB.fax_blacklist)
to_chat(usr, "<span class='warning'>Login rejected: individual is blacklisted from fax network.</span>")
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
. = FALSE
else if(check_access(scan))
authenticated = TRUE
else // ID doesn't have access to this machine
to_chat(usr, "<span class='warning'>Login rejected: ID card does not have required access.</span>")
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
. = FALSE
else if(is_authenticated)
authenticated = FALSE
if("paper") // insert/eject paper/paperbundle/photo
if(copyitem)
copyitem.forceMove(get_turf(src))
if(ishuman(usr))
if(!usr.get_active_hand() && Adjacent(usr))
usr.put_in_hands(copyitem)
to_chat(usr, "<span class='notice'>You eject [copyitem] from [src].</span>")
copyitem = null
else
var/obj/item/I = usr.get_active_hand()
if(istype(I, /obj/item/paper) || istype(I, /obj/item/photo) || istype(I, /obj/item/paper_bundle))
usr.drop_item()
copyitem = I
I.forceMove(src)
to_chat(usr, "<span class='notice'>You insert [I] into [src].</span>")
flick(insert_anim, src)
else
to_chat(usr, "<span class='warning'>[src] only accepts paper, paper bundles, and photos.</span>")
. = FALSE
if("rename") // rename the item that is currently in the fax machine
if(copyitem)
var/n_name = sanitize(copytext(input(usr, "What would you like to label the fax?", "Fax Labelling", copyitem.name) as text, 1, MAX_MESSAGE_LEN))
if((copyitem && copyitem.loc == src && usr.stat == 0))
if(istype(copyitem, /obj/item/paper))
copyitem.name = "[(n_name ? text("[n_name]") : initial(copyitem.name))]"
copyitem.desc = "This is a paper titled '" + copyitem.name + "'."
else if(istype(copyitem, /obj/item/photo))
copyitem.name = "[(n_name ? text("[n_name]") : "photo")]"
else if(istype(copyitem, /obj/item/paper_bundle))
copyitem.name = "[(n_name ? text("[n_name]") : "paper")]"
else
. = FALSE
else
. = FALSE
else
. = FALSE
if("dept") // choose which department receives the fax
if(is_authenticated)
var/lastdestination = destination
var/list/combineddepartments = GLOB.alldepartments.Copy()
if(long_range_enabled)
combineddepartments += GLOB.admin_departments.Copy()
if(emagged)
combineddepartments += GLOB.hidden_admin_departments.Copy()
combineddepartments += GLOB.hidden_departments.Copy()
if(syndie_restricted)
combineddepartments = GLOB.hidden_admin_departments.Copy()
combineddepartments += GLOB.hidden_departments.Copy()
for(var/obj/machinery/photocopier/faxmachine/F in GLOB.allfaxes)
if(F.emagged)//we can contact emagged faxes on the station
combineddepartments |= F.department
destination = input(usr, "To which department?", "Choose a department", "") as null|anything in combineddepartments
if(!destination)
destination = lastdestination
if("send") // actually send the fax
if(!copyitem || !is_authenticated || !destination)
return
if(stat & (BROKEN|NOPOWER))
return
if((destination in GLOB.admin_departments) || (destination in GLOB.hidden_admin_departments))
var/cooldown_seconds = cooldown_seconds()
if(cooldown_seconds > 0)
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
to_chat(usr, "<span class='warning'>[src] is not ready for another [cooldown_seconds] seconds.</span>")
return
send_admin_fax(usr, destination)
sendcooldown = world.time + cooldown_time
else
sendfax(destination, usr)
if(.)
add_fingerprint(usr)
/obj/machinery/photocopier/faxmachine/proc/scan(obj/item/card/id/card = null)
if(scan) // Card is in machine
if(ishuman(usr))
scan.forceMove(get_turf(src))
if(!usr.get_active_hand() && Adjacent(usr))
usr.put_in_hands(scan)
scan = null
else
scan.forceMove(get_turf(src))
scan = null
else if(Adjacent(usr))
if(!card)
var/obj/item/I = usr.get_active_hand()
if(istype(I, /obj/item/card/id))
usr.drop_item()
I.forceMove(src)
scan = I
else if(istype(card))
usr.drop_item()
card.forceMove(src)
scan = card
SStgui.update_uis(src)
/obj/machinery/photocopier/faxmachine/verb/eject_id()
set category = null
set name = "Eject ID Card"
set src in oview(1)
if(usr.incapacitated())
return
if(scan)
to_chat(usr, "You remove [scan] from [src].")
scan.forceMove(get_turf(src))
if(!usr.get_active_hand() && Adjacent(usr))
usr.put_in_hands(scan)
scan = null
else
to_chat(usr, "There is nothing to remove from [src].")
/obj/machinery/photocopier/faxmachine/proc/sendfax(destination, mob/sender)
use_power(active_power_usage)
var/success = 0
for(var/obj/machinery/photocopier/faxmachine/F in GLOB.allfaxes)
if(F.department == destination)
success = F.receivefax(copyitem)
if(success)
var/datum/fax/F = new /datum/fax()
F.name = copyitem.name
F.from_department = department
F.to_department = destination
F.origin = src
F.message = copyitem
F.sent_by = sender
F.sent_at = world.time
visible_message("[src] beeps, \"Message transmitted successfully.\"")
else
visible_message("[src] beeps, \"Error transmitting message.\"")
/obj/machinery/photocopier/faxmachine/proc/receivefax(obj/item/incoming)
if(stat & (BROKEN|NOPOWER))
return FALSE
if(department == "Unknown")
return FALSE //You can't send faxes to "Unknown"
flick(receive_anim, src)
playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1)
// give the sprite some time to flick
sleep(20)
if(istype(incoming, /obj/item/paper))
copy(incoming)
else if(istype(incoming, /obj/item/photo))
photocopy(incoming)
else if(istype(incoming, /obj/item/paper_bundle))
bundlecopy(incoming)
else
return FALSE
use_power(active_power_usage)
return TRUE
/obj/machinery/photocopier/faxmachine/proc/send_admin_fax(mob/sender, destination)
use_power(active_power_usage)
if(!(istype(copyitem, /obj/item/paper) || istype(copyitem, /obj/item/paper_bundle) || istype(copyitem, /obj/item/photo)))
visible_message("[src] beeps, \"Error transmitting message.\"")
return
var/datum/fax/admin/A = new /datum/fax/admin()
A.name = copyitem.name
A.from_department = department
A.to_department = destination
A.origin = src
A.message = copyitem
A.sent_by = sender
A.sent_at = world.time
//message badmins that a fax has arrived
switch(destination)
if("Central Command")
message_admins(sender, "CENTCOM FAX", destination, copyitem, "#006100")
if("Syndicate")
message_admins(sender, "SYNDICATE FAX", destination, copyitem, "#DC143C")
for(var/obj/machinery/photocopier/faxmachine/F in GLOB.allfaxes)
if(F.department == destination)
F.receivefax(copyitem)
visible_message("[src] beeps, \"Message transmitted successfully.\"")
/obj/machinery/photocopier/faxmachine/proc/cooldown_seconds()
if(sendcooldown < world.time)
return 0
return round((sendcooldown - world.time) / 10)
/obj/machinery/photocopier/faxmachine/proc/message_admins(mob/sender, faxname, faxtype, obj/item/sent, font_colour="#9A04D1")
var/msg = "<span class='boldnotice'><font color='[font_colour]'>[faxname]: </font> [key_name_admin(sender)] | REPLY: (<A HREF='?_src_=holder;[faxname == "SYNDICATE FAX" ? "SyndicateReply" : "CentcommReply"]=[sender.UID()]'>RADIO</A>) (<a href='?_src_=holder;AdminFaxCreate=\ref[sender];originfax=\ref[src];faxtype=[faxtype];replyto=\ref[sent]'>FAX</a>) ([ADMIN_SM(sender,"SM")]) | REJECT: (<A HREF='?_src_=holder;FaxReplyTemplate=[sender.UID()];originfax=\ref[src]'>TEMPLATE</A>) ([ADMIN_BSA(sender,"BSA")]) (<A HREF='?_src_=holder;EvilFax=[sender.UID()];originfax=\ref[src]'>EVILFAX</A>) </span>: Receiving '[sent.name]' via secure connection... <a href='?_src_=holder;AdminFaxView=\ref[sent]'>view message</a>"
var/fax_sound = sound('sound/effects/adminhelp.ogg')
for(var/client/C in GLOB.admins)
if(check_rights(R_EVENT, 0, C.mob))
to_chat(C, msg)
if(C.prefs.sound & SOUND_ADMINHELP)
SEND_SOUND(C, fax_sound)
/obj/machinery/photocopier/faxmachine/proc/become_mimic()
if(scan)
scan.forceMove(get_turf(src))
var/mob/living/simple_animal/hostile/mimic/copy/M = new(loc, src, null, 1) // it will delete src on creation and override any machine checks
M.name = "angry fax machine"