Ports TGUI Security Stuff (#7902)

This commit is contained in:
Cerebulon
2021-02-20 07:18:09 +00:00
committed by GitHub
parent 5d0ede0f13
commit 66b0338be2
6 changed files with 670 additions and 864 deletions

View File

@@ -1748,7 +1748,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
temp_closet.locked = 0
temp_closet.icon_state = "closed_unlocked"
for(var/obj/machinery/door_timer/temp_timer in src)
temp_timer.releasetime = 1
temp_timer.timer_duration = 1
..()
/area/security/prison
@@ -1760,7 +1760,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
temp_closet.locked = 0
temp_closet.icon_state = "closed_unlocked"
for(var/obj/machinery/door_timer/temp_timer in src)
temp_timer.releasetime = 1
temp_timer.timer_duration = 1
..()
/area/security/warden

View File

@@ -196,7 +196,7 @@ var/hadevent = 0
spawn(0) temp_glassairlock.prison_open()
for (var/obj/machinery/door_timer/temp_timer in A)
temp_timer.releasetime = 1
temp_timer.timer_duration = 1
sleep(150)
command_announcement.Announce("Gr3y.T1d3 virus detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert")

View File

@@ -15,90 +15,81 @@
var/stop = 0.0
var/screen = 0 // 0 - No Access Denied, 1 - Access allowed
/obj/machinery/computer/prisoner/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
attack_ai(var/mob/user as mob)
return src.attack_hand(user)
attack_hand(var/mob/user as mob)
if(..())
return
user.set_machine(src)
var/dat
dat += "<B>Prisoner Implant Manager System</B><BR>"
if(screen == 0)
dat += "<HR><A href='?src=\ref[src];lock=1'>Unlock Console</A>"
else if(screen == 1)
dat += "<HR>Chemical Implants<BR>"
var/turf/Tr = null
for(var/obj/item/weapon/implant/chem/C in all_chem_implants)
Tr = get_turf(C)
if(!Tr) continue//Out of range
if(!C.implanted) continue
dat += "[C.imp_in.name] | Remaining Units: [C.reagents.total_volume] | Inject: "
dat += "<A href='?src=\ref[src];inject1=\ref[C]'>(<font color=red>(1)</font>)</A>"
dat += "<A href='?src=\ref[src];inject5=\ref[C]'>(<font color=red>(5)</font>)</A>"
dat += "<A href='?src=\ref[src];inject10=\ref[C]'>(<font color=red>(10)</font>)</A><BR>"
dat += "********************************<BR>"
dat += "<HR>Tracking Implants<BR>"
for(var/obj/item/weapon/implant/tracking/T in all_tracking_implants)
Tr = get_turf(T)
if(!Tr) continue//Out of range
if(!T.implanted) continue
var/loc_display = "Unknown"
var/mob/living/carbon/M = T.imp_in
if((M.z in using_map.station_levels) && !istype(M.loc, /turf/space))
var/turf/mob_loc = get_turf(M)
loc_display = mob_loc.loc
if(T.malfunction)
loc_display = pick(teleportlocs)
dat += "ID: [T.id] | Location: [loc_display]<BR>"
dat += "<A href='?src=\ref[src];warn=\ref[T]'>(<font color=red><i>Message Holder</i></font>)</A> |<BR>"
dat += "********************************<BR>"
dat += "<HR><A href='?src=\ref[src];lock=1'>Lock Console</A>"
user << browse(dat, "window=computer;size=400x500")
onclose(user, "computer")
/obj/machinery/computer/prisoner/attack_hand(mob/user)
if(..())
return
tgui_interact(user)
/obj/machinery/computer/prisoner/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "PrisonerManagement", name)
ui.open()
/obj/machinery/computer/prisoner/tgui_data(mob/user)
var/list/data = list()
data["locked"] = !screen
data["chemImplants"] = list()
data["trackImplants"] = list()
if(screen)
for(var/obj/item/weapon/implant/chem/C in all_chem_implants)
var/turf/T = get_turf(C)
if(!T)
continue
if(!C.implanted)
continue
data["chemImplants"].Add(list(list(
"host" = C.imp_in,
"units" = C.reagents.total_volume,
"ref" = "\ref[C]"
)))
for(var/obj/item/weapon/implant/tracking/track in all_tracking_implants)
var/turf/T = get_turf(track)
if(!T)
continue
if(!track.implanted)
continue
var/loc_display = "Unknown"
var/mob/living/L = track.imp_in
if((get_z(L) in using_map.station_levels) && !istype(L.loc, /turf/space))
loc_display = T.loc
if(track.malfunction)
loc_display = pick(teleportlocs)
data["trackImplants"].Add(list(list(
"host" = L,
"ref" = "\ref[track]",
"id" = "[track.id]",
"loc" = "[loc_display]",
)))
return data
process()
if(!..())
src.updateDialog()
return
Topic(href, href_list)
if(..())
return
if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
usr.set_machine(src)
if(href_list["inject1"])
var/obj/item/weapon/implant/I = locate(href_list["inject1"])
if(I) I.activate(1)
else if(href_list["inject5"])
var/obj/item/weapon/implant/I = locate(href_list["inject5"])
if(I) I.activate(5)
else if(href_list["inject10"])
var/obj/item/weapon/implant/I = locate(href_list["inject10"])
if(I) I.activate(10)
else if(href_list["lock"])
if(src.allowed(usr))
screen = !screen
else
to_chat(usr, "Unauthorized Access.")
else if(href_list["warn"])
var/warning = sanitize(input(usr,"Message:","Enter your message here!",""))
if(!warning) return
var/obj/item/weapon/implant/I = locate(href_list["warn"])
if((I)&&(I.imp_in))
var/mob/living/carbon/R = I.imp_in
to_chat(R, "<span class='notice'>You hear a voice in your head saying: '[warning]'</span>")
src.add_fingerprint(usr)
src.updateUsrDialog()
return
/obj/machinery/computer/prisoner/tgui_act(action, list/params)
if(..())
return TRUE
switch(action)
if("inject")
var/obj/item/weapon/implant/I = locate(params["imp"])
if(I)
I.activate(clamp(params["val"], 0, 10))
. = TRUE
if("lock")
if(allowed(usr))
screen = !screen
else
to_chat(usr, "Unauthorized Access.")
. = TRUE
if("warn")
var/warning = sanitize(input(usr, "Message:", "Enter your message here!", ""))
if(!warning)
return
var/obj/item/weapon/implant/I = locate(params["imp"])
if(I && I.imp_in)
to_chat(I.imp_in, "<span class='notice'>You hear a voice in your head saying: '[warning]'</span>")
. = TRUE
add_fingerprint(usr)

View File

@@ -1,4 +1,8 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
#define SEC_DATA_R_LIST 2 // Record list
#define SEC_DATA_MAINT 3 // Records maintenance
#define SEC_DATA_RECORD 4 // Record
#define FIELD(N, V, E) list(field = N, value = V, edit = E)
/obj/machinery/computer/secure_data//TODO:SANITY
name = "security records console"
@@ -14,15 +18,42 @@
var/screen = null
var/datum/data/record/active1 = null
var/datum/data/record/active2 = null
var/a_id = null
var/temp = null
var/list/temp = null
var/printing = null
var/can_change_id = 0
var/list/Perp
var/tempname = null
//Sorting Variables
var/sortBy = "name"
var/order = 1 // -1 = Descending - 1 = Ascending
// The below are used to make modal generation more convenient
var/static/list/field_edit_questions
var/static/list/field_edit_choices
/obj/machinery/computer/secure_data/Initialize()
..()
field_edit_questions = list(
// General
"name" = "Please enter new name:",
"id" = "Please enter new id:",
"sex" = "Please select new sex:",
"age" = "Please input new age:",
"rank" = "Please enter new rank:",
"fingerprint" = "Please input new fingerprint hash:",
// Security
"brain_type" = "Please select new brain type:",
"criminal" = "Please select new criminal status:",
"mi_crim" = "Please input new minor crime:",
"mi_crim_d" = "Please input minor crime summary.",
"ma_crim" = "Please input new major crime:",
"ma_crim_d" = "Please input new major crime summary.",
"notes" = "Please input new important notes:",
)
field_edit_choices = list(
// General
"sex" = all_genders_text_list,
// Security
"criminal" = list("*Arrest*", "Incarcerated", "Parolled", "Released", "None"),
)
/obj/machinery/computer/secure_data/Destroy()
active1 = null
active2 = null
return ..()
/obj/machinery/computer/secure_data/verb/eject_id()
set category = "Object"
@@ -41,13 +72,14 @@
to_chat(usr, "There is nothing to remove from the console.")
return
/obj/machinery/computer/secure_data/attackby(obj/item/O as obj, user as mob)
if(istype(O, /obj/item/weapon/card/id) && !scan)
usr.drop_item()
/obj/machinery/computer/secure_data/attackby(var/obj/item/O, var/mob/user)
if(istype(O, /obj/item/weapon/card/id) && !scan && user.unEquip(O))
O.loc = src
scan = O
to_chat(user, "You insert [O].")
..()
to_chat(user, "You insert \the [O].")
tgui_interact(user)
else
..()
/obj/machinery/computer/secure_data/attack_ai(mob/user as mob)
return attack_hand(user)
@@ -56,518 +88,380 @@
/obj/machinery/computer/secure_data/attack_hand(mob/user as mob)
if(..())
return
if (using_map && !(src.z in using_map.contact_levels))
to_chat(user, "<span class='warning'>Unable to establish a connection:</span> You're too far away from the station!")
return
var/dat
add_fingerprint(user)
tgui_interact(user)
if (temp)
dat = text("<TT>[]</TT><BR><BR><A href='?src=\ref[];choice=Clear Screen'>Clear Screen</A>", temp, src)
else
dat = text("Confirm Identity: <A href='?src=\ref[];choice=Confirm Identity'>[]</A><HR>", src, (scan ? text("[]", scan.name) : "----------"))
if (authenticated)
switch(screen)
if(1.0)
dat += {"
<p style='text-align:center;'>"}
dat += text("<A href='?src=\ref[];choice=Search Records'>Search Records</A><BR>", src)
dat += text("<A href='?src=\ref[];choice=New Record (General)'>New Record</A><BR>", src)
dat += {"
</p>
<table style="text-align:center;" cellspacing="0" width="100%">
<tr>
<th>Records:</th>
</tr>
</table>
<table style="text-align:center;" border="1" cellspacing="0" width="100%">
<tr>
<th><A href='?src=\ref[src];choice=Sorting;sort=name'>Name</A></th>
<th><A href='?src=\ref[src];choice=Sorting;sort=id'>ID</A></th>
<th><A href='?src=\ref[src];choice=Sorting;sort=rank'>Rank</A></th>
<th><A href='?src=\ref[src];choice=Sorting;sort=fingerprint'>Fingerprints</A></th>
<th>Criminal Status</th>
</tr>"}
if(!isnull(data_core.general))
for(var/datum/data/record/R in sortRecord(data_core.general, sortBy, order))
var/crimstat = ""
for(var/datum/data/record/E in data_core.security)
if ((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"]))
crimstat = E.fields["criminal"]
var/background
switch(crimstat)
if("*Arrest*")
background = "'background-color:#DC143C;'"
if("Incarcerated")
background = "'background-color:#CD853F;'"
if("Parolled")
background = "'background-color:#CD853F;'"
if("Released")
background = "'background-color:#3BB9FF;'"
if("None")
background = "'background-color:#00FF7F;'"
if("")
background = "'background-color:#FFFFFF;'"
crimstat = "No Record."
dat += text("<tr style=[]><td><A href='?src=\ref[];choice=Browse Record;d_rec=\ref[]'>[]</a></td>", background, src, R, R.fields["name"])
dat += text("<td>[]</td>", R.fields["id"])
dat += text("<td>[]</td>", R.fields["rank"])
dat += text("<td>[]</td>", R.fields["fingerprint"])
dat += text("<td>[]</td></tr>", crimstat)
dat += "</table><hr width='75%' />"
dat += text("<A href='?src=\ref[];choice=Record Maintenance'>Record Maintenance</A><br><br>", src)
dat += text("<A href='?src=\ref[];choice=Log Out'>{Log Out}</A>",src)
if(2.0)
dat += "<B>Records Maintenance</B><HR>"
dat += "<BR><A href='?src=\ref[src];choice=Delete All Records'>Delete All Records</A><BR><BR><A href='?src=\ref[src];choice=Return'>Back</A>"
if(3.0)
dat += "<CENTER><B>Security Record</B></CENTER><BR>"
if ((istype(active1, /datum/data/record) && data_core.general.Find(active1)))
user << browse_rsc(active1.fields["photo_front"], "front.png")
user << browse_rsc(active1.fields["photo_side"], "side.png")
dat += text("<table><tr><td> \
Name: <A href='?src=\ref[src];choice=Edit Field;field=name'>[active1.fields["name"]]</A><BR> \
ID: <A href='?src=\ref[src];choice=Edit Field;field=id'>[active1.fields["id"]]</A><BR>\n \
Entity Classification: <A href='?src=\ref[src];field=brain_type'>[active1.fields["brain_type"]]</A><BR>\n \
Sex: <A href='?src=\ref[src];choice=Edit Field;field=sex'>[active1.fields["sex"]]</A><BR>\n \
Age: <A href='?src=\ref[src];choice=Edit Field;field=age'>[active1.fields["age"]]</A><BR>\n \
Rank: <A href='?src=\ref[src];choice=Edit Field;field=rank'>[active1.fields["rank"]]</A><BR>\n \
Fingerprint: <A href='?src=\ref[src];choice=Edit Field;field=fingerprint'>[active1.fields["fingerprint"]]</A><BR>\n \
Physical Status: [active1.fields["p_stat"]]<BR>\n \
Mental Status: [active1.fields["m_stat"]]<BR></td> \
<td align = center valign = top>Photo:<br> \
<table><td align = center><img src=front.png height=80 width=80 border=4><BR><A href='?src=\ref[src];choice=Edit Field;field=photo front'>Update front photo</A></td> \
<td align = center><img src=side.png height=80 width=80 border=4><BR><A href='?src=\ref[src];choice=Edit Field;field=photo side'>Update side photo</A></td></table> \
</td></tr></table>")
else
dat += "<B>General Record Lost!</B><BR>"
if ((istype(active2, /datum/data/record) && data_core.security.Find(active2)))
dat += text("<BR>\n<CENTER><B>Security Data</B></CENTER><BR>\nCriminal Status: <A href='?src=\ref[];choice=Edit Field;field=criminal'>[]</A><BR>\n<BR>\nMinor Crimes: <A href='?src=\ref[];choice=Edit Field;field=mi_crim'>[]</A><BR>\nDetails: <A href='?src=\ref[];choice=Edit Field;field=mi_crim_d'>[]</A><BR>\n<BR>\nMajor Crimes: <A href='?src=\ref[];choice=Edit Field;field=ma_crim'>[]</A><BR>\nDetails: <A href='?src=\ref[];choice=Edit Field;field=ma_crim_d'>[]</A><BR>\n<BR>\nImportant Notes:<BR>\n\t<A href='?src=\ref[];choice=Edit Field;field=notes'>[]</A><BR>\n<BR>\n<CENTER><B>Comments/Log</B></CENTER><BR>", src, active2.fields["criminal"], src, active2.fields["mi_crim"], src, active2.fields["mi_crim_d"], src, active2.fields["ma_crim"], src, active2.fields["ma_crim_d"], src, decode(active2.fields["notes"]))
var/counter = 1
while(active2.fields[text("com_[]", counter)])
dat += text("[]<BR><A href='?src=\ref[];choice=Delete Entry;del_c=[]'>Delete Entry</A><BR><BR>", active2.fields[text("com_[]", counter)], src, counter)
counter++
dat += text("<A href='?src=\ref[];choice=Add Entry'>Add Entry</A><BR><BR>", src)
dat += text("<A href='?src=\ref[];choice=Delete Record (Security)'>Delete Record (Security Only)</A><BR><BR>", src)
else
dat += "<B>Security Record Lost!</B><BR>"
dat += text("<A href='?src=\ref[];choice=New Record (Security)'>New Security Record</A><BR><BR>", src)
dat += text("\n<A href='?src=\ref[];choice=Delete Record (ALL)'>Delete Record (ALL)</A><BR><BR>\n<A href='?src=\ref[];choice=Print Record'>Print Record</A><BR>\n<A href='?src=\ref[];choice=Return'>Back</A><BR>", src, src, src)
if(4.0)
if(!Perp.len)
dat += text("ERROR. String could not be located.<br><br><A href='?src=\ref[];choice=Return'>Back</A>", src)
else
dat += {"
<table style="text-align:center;" cellspacing="0" width="100%">
<tr> "}
dat += text("<th>Search Results for '[]':</th>", tempname)
dat += {"
</tr>
</table>
<table style="text-align:center;" border="1" cellspacing="0" width="100%">
<tr>
<th>Name</th>
<th>ID</th>
<th>Rank</th>
<th>Fingerprints</th>
<th>Criminal Status</th>
</tr> "}
for(var/i=1, i<=Perp.len, i += 2)
var/crimstat = ""
var/datum/data/record/R = Perp[i]
if(istype(Perp[i+1],/datum/data/record/))
var/datum/data/record/E = Perp[i+1]
crimstat = E.fields["criminal"]
var/background
switch(crimstat)
if("*Arrest*")
background = "'background-color:#DC143C;'"
if("Incarcerated")
background = "'background-color:#CD853F;'"
if("Parolled")
background = "'background-color:#CD853F;'"
if("Released")
background = "'background-color:#3BB9FF;'"
if("None")
background = "'background-color:#00FF7F;'"
if("")
background = "'background-color:#FFFFFF;'"
crimstat = "No Record."
dat += text("<tr style=[]><td><A href='?src=\ref[];choice=Browse Record;d_rec=\ref[]'>[]</a></td>", background, src, R, R.fields["name"])
dat += text("<td>[]</td>", R.fields["id"])
dat += text("<td>[]</td>", R.fields["rank"])
dat += text("<td>[]</td>", R.fields["fingerprint"])
dat += text("<td>[]</td></tr>", crimstat)
dat += "</table><hr width='75%' />"
dat += text("<br><A href='?src=\ref[];choice=Return'>Return to index.</A>", src)
/obj/machinery/computer/secure_data/tgui_interact(mob/user, datum/tgui/ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "SecurityRecords", "Security Records") // 800, 380
ui.open()
ui.set_autoupdate(FALSE)
/obj/machinery/computer/secure_data/tgui_data(mob/user)
var/data[0]
data["temp"] = temp
data["scan"] = scan ? scan.name : null
data["authenticated"] = authenticated
data["rank"] = rank
data["screen"] = screen
data["printing"] = printing
data["isAI"] = isAI(user)
data["isRobot"] = isrobot(user)
if(authenticated)
switch(screen)
if(SEC_DATA_R_LIST)
if(!isnull(data_core.general))
var/list/records = list()
data["records"] = records
for(var/datum/data/record/R in sortRecord(data_core.general))
var/color = null
var/criminal = "None"
for(var/datum/data/record/M in data_core.security)
if(M.fields["name"] == R.fields["name"] && M.fields["id"] == R.fields["id"])
switch(M.fields["criminal"])
if("*Arrest*")
color = "bad"
if("Incarcerated")
color = "brown"
if("Parolled", "Released")
color = "average"
if("None")
color = "good"
criminal = M.fields["criminal"]
break
records[++records.len] = list(
"ref" = "\ref[R]",
"id" = R.fields["id"],
"name" = R.fields["name"],
"color" = color,
"criminal" = criminal
)
if(SEC_DATA_RECORD)
var/list/general = list()
data["general"] = general
if(istype(active1, /datum/data/record) && data_core.general.Find(active1))
var/list/fields = list()
general["fields"] = fields
fields[++fields.len] = FIELD("Name", active1.fields["name"], "name")
fields[++fields.len] = FIELD("ID", active1.fields["id"], "id")
fields[++fields.len] = FIELD("Entity Classification", active1.fields["brain_type"], "brain_type")
fields[++fields.len] = FIELD("Sex", active1.fields["sex"], "sex")
fields[++fields.len] = FIELD("Age", "[active1.fields["age"]]", "age")
fields[++fields.len] = FIELD("Rank", active1.fields["rank"], "rank")
fields[++fields.len] = FIELD("Fingerprint", active1.fields["fingerprint"], "fingerprint")
fields[++fields.len] = FIELD("Physical Status", active1.fields["p_stat"], null)
fields[++fields.len] = FIELD("Mental Status", active1.fields["m_stat"], null)
var/list/photos = list()
general["photos"] = photos
photos[++photos.len] = active1.fields["photo-south"]
photos[++photos.len] = active1.fields["photo-west"]
general["has_photos"] = (active1.fields["photo-south"] || active1.fields["photo-west"] ? 1 : 0)
general["empty"] = 0
else
else
dat += text("<A href='?src=\ref[];choice=Log In'>{Log In}</A>", src)
user << browse(text("<HEAD><TITLE>Security Records</TITLE></HEAD><TT>[]</TT>", dat), "window=secure_rec;size=600x400")
onclose(user, "secure_rec")
return
general["empty"] = 1
/*Revised /N
I can't be bothered to look more of the actual code outside of switch but that probably needs revising too.
What a mess.*/
/obj/machinery/computer/secure_data/Topic(href, href_list)
var/list/security = list()
data["security"] = security
if(istype(active2, /datum/data/record) && data_core.security.Find(active2))
var/list/fields = list()
security["fields"] = fields
fields[++fields.len] = FIELD("Criminal Status", active2.fields["criminal"], "criminal")
fields[++fields.len] = FIELD("Minor Crimes", active2.fields["mi_crim"], "mi_crim")
fields[++fields.len] = FIELD("Details", active2.fields["mi_crim_d"], "mi_crim_d")
fields[++fields.len] = FIELD("Major Crimes", active2.fields["ma_crim"], "ma_crim")
fields[++fields.len] = FIELD("Details", active2.fields["ma_crim_d"], "ma_crim_d")
fields[++fields.len] = FIELD("Important Notes", active2.fields["notes"], "notes")
if(!active2.fields["comments"] || !islist(active2.fields["comments"]))
active2.fields["comments"] = list()
security["comments"] = active2.fields["comments"]
security["empty"] = 0
else
security["empty"] = 1
data["modal"] = tgui_modal_data(src)
return data
/obj/machinery/computer/secure_data/tgui_act(action, params)
if(..())
return 1
if (!( data_core.general.Find(active1) ))
active1 = null
if (!( data_core.security.Find(active2) ))
active2 = null
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon)))
usr.set_machine(src)
switch(href_list["choice"])
// SORTING!
if("Sorting")
// Reverse the order if clicked twice
if(sortBy == href_list["sort"])
if(order == 1)
order = -1
else
order = 1
else
// New sorting order!
sortBy = href_list["sort"]
order = initial(order)
//BASIC FUNCTIONS
if("Clear Screen")
temp = null
return TRUE
if ("Return")
screen = 1
if(!data_core.general.Find(active1))
active1 = null
if(!data_core.security.Find(active2))
active2 = null
. = TRUE
if(tgui_act_modal(action, params))
return
switch(action)
if("cleartemp")
temp = null
if("scan")
if(scan)
scan.forceMove(loc)
if(ishuman(usr) && !usr.get_active_hand())
usr.put_in_hands(scan)
scan = null
else
var/obj/item/I = usr.get_active_hand()
if(istype(I, /obj/item/weapon/card/id))
usr.drop_item()
I.forceMove(src)
scan = I
if("login")
var/login_type = text2num(params["login_type"])
if(login_type == LOGIN_TYPE_NORMAL && istype(scan))
if(check_access(scan))
authenticated = scan.registered_name
rank = scan.assignment
else if(login_type == LOGIN_TYPE_AI && isAI(usr))
authenticated = usr.name
rank = "AI"
else if(login_type == LOGIN_TYPE_ROBOT && isrobot(usr))
authenticated = usr.name
var/mob/living/silicon/robot/R = usr
rank = "[R.modtype] [R.braintype]"
if(authenticated)
active1 = null
active2 = null
screen = SEC_DATA_R_LIST
else
. = FALSE
if("Confirm Identity")
if (scan)
if(istype(usr,/mob/living/carbon/human) && !usr.get_active_hand())
if(.)
return
if(authenticated)
. = TRUE
switch(action)
if("logout")
if(scan)
scan.forceMove(loc)
if(ishuman(usr) && !usr.get_active_hand())
usr.put_in_hands(scan)
else
scan.loc = get_turf(src)
scan = null
else
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I))
I.loc = src
scan = I
if("Log Out")
authenticated = null
screen = null
active1 = null
active2 = null
if("Log In")
if (istype(usr, /mob/living/silicon/ai))
src.active1 = null
src.active2 = null
src.authenticated = usr.name
src.rank = "AI"
src.screen = 1
else if (istype(usr, /mob/living/silicon/robot))
src.active1 = null
src.active2 = null
src.authenticated = usr.name
var/mob/living/silicon/robot/R = usr
src.rank = "[R.modtype] [R.braintype]"
src.screen = 1
else if (istype(scan, /obj/item/weapon/card/id))
active1 = null
active2 = null
if(check_access(scan))
authenticated = scan.registered_name
rank = scan.assignment
screen = 1
//RECORD FUNCTIONS
if("Search Records")
var/t1 = input("Search String: (Partial Name or ID or Fingerprints or Rank)", "Secure. records", null, null) as text
if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || !in_range(src, usr)))
return
Perp = new/list()
t1 = lowertext(t1)
var/list/components = splittext(t1, " ")
if(components.len > 5)
return //Lets not let them search too greedily.
for(var/datum/data/record/R in data_core.general)
var/temptext = R.fields["name"] + " " + R.fields["id"] + " " + R.fields["fingerprint"] + " " + R.fields["rank"]
for(var/i = 1, i<=components.len, i++)
if(findtext(temptext,components[i]))
var/prelist = new/list(2)
prelist[1] = R
Perp += prelist
for(var/i = 1, i<=Perp.len, i+=2)
for(var/datum/data/record/E in data_core.security)
var/datum/data/record/R = Perp[i]
if ((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"]))
Perp[i+1] = E
tempname = t1
screen = 4
if("Record Maintenance")
screen = 2
if("screen")
screen = clamp(text2num(params["screen"]) || 0, SEC_DATA_R_LIST, SEC_DATA_RECORD)
active1 = null
active2 = null
if ("Browse Record")
var/datum/data/record/R = locate(href_list["d_rec"])
var/S = locate(href_list["d_rec"])
if (!( data_core.general.Find(R) ))
temp = "Record Not Found!"
else
for(var/datum/data/record/E in data_core.security)
if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
S = E
active1 = R
active2 = S
screen = 3
/* if ("Search Fingerprints")
var/t1 = input("Search String: (Fingerprint)", "Secure. records", null, null) as text
if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || (!in_range(src, usr)) && (!istype(usr, /mob/living/silicon))))
return
active1 = null
active2 = null
t1 = lowertext(t1)
for(var/datum/data/record/R in data_core.general)
if (lowertext(R.fields["fingerprint"]) == t1)
active1 = R
if (!( active1 ))
temp = text("Could not locate record [].", t1)
else
for(var/datum/data/record/E in data_core.security)
if ((E.fields["name"] == active1.fields["name"] || E.fields["id"] == active1.fields["id"]))
active2 = E
screen = 3 */
if ("Print Record")
if (!( printing ))
printing = 1
var/datum/data/record/record1 = null
var/datum/data/record/record2 = null
if ((istype(active1, /datum/data/record) && data_core.general.Find(active1)))
record1 = active1
if ((istype(active2, /datum/data/record) && data_core.security.Find(active2)))
record2 = active2
sleep(50)
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( loc )
P.info = "<CENTER><B>Security Record</B></CENTER><BR>"
if (record1)
P.info += text("Name: [] ID: []<BR>\nSex: []<BR>\nAge: []<BR>\nFingerprint: []<BR>\nPhysical Status: []<BR>\nMental Status: []<BR>", record1.fields["name"], record1.fields["id"], record1.fields["sex"], record1.fields["age"], record1.fields["fingerprint"], record1.fields["p_stat"], record1.fields["m_stat"])
P.name = text("Security Record ([])", record1.fields["name"])
else
P.info += "<B>General Record Lost!</B><BR>"
P.name = "Security Record"
if (record2)
P.info += text("<BR>\n<CENTER><B>Security Data</B></CENTER><BR>\nCriminal Status: []<BR>\n<BR>\nMinor Crimes: []<BR>\nDetails: []<BR>\n<BR>\nMajor Crimes: []<BR>\nDetails: []<BR>\n<BR>\nImportant Notes:<BR>\n\t[]<BR>\n<BR>\n<CENTER><B>Comments/Log</B></CENTER><BR>", record2.fields["criminal"], record2.fields["mi_crim"], record2.fields["mi_crim_d"], record2.fields["ma_crim"], record2.fields["ma_crim_d"], decode(record2.fields["notes"]))
var/counter = 1
while(record2.fields[text("com_[]", counter)])
P.info += text("[]<BR>", record2.fields[text("com_[]", counter)])
counter++
else
P.info += "<B>Security Record Lost!</B><BR>"
P.info += "</TT>"
printing = null
updateUsrDialog()
//RECORD DELETE
if ("Delete All Records")
temp = ""
temp += "Are you sure you wish to delete all Security records?<br>"
temp += "<a href='?src=\ref[src];choice=Purge All Records'>Yes</a><br>"
temp += "<a href='?src=\ref[src];choice=Clear Screen'>No</a>"
if ("Purge All Records")
if("del_all")
for(var/datum/data/record/R in data_core.security)
qdel(R)
temp = "All Security records deleted."
if ("Add Entry")
if (!( istype(active2, /datum/data/record) ))
set_temp("All security records deleted.")
if("del_r")
if(active2)
set_temp("Security record deleted.")
qdel(active2)
if("del_r_2")
set_temp("All records for [active1.fields["name"]] deleted.")
if(active1)
for(var/datum/data/record/R in data_core.medical)
if((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"]))
qdel(R)
qdel(active1)
if(active2)
qdel(active2)
if("d_rec")
var/datum/data/record/general_record = locate(params["d_rec"] || "")
if(!data_core.general.Find(general_record))
set_temp("Record not found.", "danger")
return
var/a2 = active2
var/t1 = sanitize(input("Add Comment:", "Secure. records", null, null) as message)
if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active2 != a2))
var/datum/data/record/security_record
for(var/datum/data/record/M in data_core.security)
if(M.fields["name"] == general_record.fields["name"] && M.fields["id"] == general_record.fields["id"])
security_record = M
break
active1 = general_record
active2 = security_record
screen = SEC_DATA_RECORD
if("new")
if(istype(active1, /datum/data/record) && !istype(active2, /datum/data/record))
var/datum/data/record/R = new /datum/data/record()
R.fields["name"] = active1.fields["name"]
R.fields["id"] = active1.fields["id"]
R.name = "Security Record #[R.fields["id"]]"
R.fields["brain_type"] = "Unknown"
R.fields["criminal"] = "None"
R.fields["mi_crim"] = "None"
R.fields["mi_crim_d"] = "No minor crime convictions."
R.fields["ma_crim"] = "None"
R.fields["ma_crim_d"] = "No major crime convictions."
R.fields["notes"] = "No notes."
R.fields["notes"] = "No notes."
data_core.security += R
active2 = R
screen = SEC_DATA_RECORD
set_temp("Security record created.", "success")
if("del_c")
var/index = text2num(params["del_c"] || "")
if(!index || !istype(active2, /datum/data/record))
return
var/counter = 1
while(active2.fields[text("com_[]", counter)])
counter++
active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD")] [stationtime2text()], [game_year]<BR>[t1]")
if ("Delete Record (ALL)")
if (active1)
temp = "<h5>Are you sure you wish to delete the record (ALL)?</h5>"
temp += "<a href='?src=\ref[src];choice=Delete Record (ALL) Execute'>Yes</a><br>"
temp += "<a href='?src=\ref[src];choice=Clear Screen'>No</a>"
if ("Delete Record (Security)")
if (active2)
temp = "<h5>Are you sure you wish to delete the record (Security Portion Only)?</h5>"
temp += "<a href='?src=\ref[src];choice=Delete Record (Security) Execute'>Yes</a><br>"
temp += "<a href='?src=\ref[src];choice=Clear Screen'>No</a>"
if ("Delete Entry")
if ((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])]))
active2.fields[text("com_[]", href_list["del_c"])] = "<B>Deleted</B>"
//RECORD CREATE
if ("New Record (Security)")
if ((istype(active1, /datum/data/record) && !( istype(active2, /datum/data/record) )))
active2 = data_core.CreateSecurityRecord(active1.fields["name"], active1.fields["id"])
screen = 3
if ("New Record (General)")
active1 = data_core.CreateGeneralRecord()
var/list/comments = active2.fields["comments"]
index = clamp(index, 1, length(comments))
if(comments[index])
comments.Cut(index, index + 1)
if("search")
active1 = null
active2 = null
//FIELD FUNCTIONS
if ("Edit Field")
if (is_not_allowed(usr))
var/t1 = lowertext(params["t1"] || "")
if(!length(t1))
return
var/a1 = active1
var/a2 = active2
switch(href_list["field"])
if("name")
if (istype(active1, /datum/data/record))
var/t1 = sanitizeName(input("Please input name:", "Secure. records", active1.fields["name"], null) as text)
if (!t1 || active1 != a1)
return
active1.fields["name"] = t1
if("id")
if (istype(active2, /datum/data/record))
var/t1 = sanitize(input("Please input id:", "Secure. records", active1.fields["id"], null) as text)
if (!t1 || active1 != a1)
return
active1.fields["id"] = t1
if("fingerprint")
if (istype(active1, /datum/data/record))
var/t1 = sanitize(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text)
if (!t1 || active1 != a1)
return
active1.fields["fingerprint"] = t1
if("sex")
if (istype(active1, /datum/data/record))
if (active1.fields["sex"] == "Male")
active1.fields["sex"] = "Female"
else
active1.fields["sex"] = "Male"
if("age")
if (istype(active1, /datum/data/record))
var/t1 = input("Please input age:", "Secure. records", active1.fields["age"], null) as num
if (!t1 || active1 != a1)
return
active1.fields["age"] = t1
if("mi_crim")
if (istype(active2, /datum/data/record))
var/t1 = sanitize(input("Please input minor disabilities list:", "Secure. records", active2.fields["mi_crim"], null) as text)
if (!t1 || active2 != a2)
return
active2.fields["mi_crim"] = t1
if("mi_crim_d")
if (istype(active2, /datum/data/record))
var/t1 = sanitize(input("Please summarize minor dis.:", "Secure. records", active2.fields["mi_crim_d"], null) as message)
if (!t1 || active2 != a2)
return
active2.fields["mi_crim_d"] = t1
if("ma_crim")
if (istype(active2, /datum/data/record))
var/t1 = sanitize(input("Please input major diabilities list:", "Secure. records", active2.fields["ma_crim"], null) as text)
if (!t1 || active2 != a2)
return
active2.fields["ma_crim"] = t1
if("ma_crim_d")
if (istype(active2, /datum/data/record))
var/t1 = sanitize(input("Please summarize major dis.:", "Secure. records", active2.fields["ma_crim_d"], null) as message)
if (!t1 || active2 != a2)
return
active2.fields["ma_crim_d"] = t1
if("notes")
if (istype(active2, /datum/data/record))
var/t1 = sanitize(input("Please summarize notes:", "Secure. records", html_decode(active2.fields["notes"]), null) as message, extra = 0, max_length = MAX_RECORD_LENGTH)
if (!t1 || active2 != a2)
return
active2.fields["notes"] = t1
if("criminal")
if (istype(active2, /datum/data/record))
temp = "<h5>Criminal Status:</h5>"
temp += "<ul>"
temp += "<li><a href='?src=\ref[src];choice=Change Criminal Status;criminal2=none'>None</a></li>"
temp += "<li><a href='?src=\ref[src];choice=Change Criminal Status;criminal2=arrest'>*Arrest*</a></li>"
temp += "<li><a href='?src=\ref[src];choice=Change Criminal Status;criminal2=incarcerated'>Incarcerated</a></li>"
temp += "<li><a href='?src=\ref[src];choice=Change Criminal Status;criminal2=parolled'>Parolled</a></li>"
temp += "<li><a href='?src=\ref[src];choice=Change Criminal Status;criminal2=released'>Released</a></li>"
temp += "</ul>"
if("rank")
var/list/L = list( "Head of Personnel", "Site Manager", "AI" )
//This was so silly before the change. Now it actually works without beating your head against the keyboard. /N
if ((istype(active1, /datum/data/record) && L.Find(rank)))
temp = "<h5>Rank:</h5>"
temp += "<ul>"
for(var/rank in joblist)
temp += "<li><a href='?src=\ref[src];choice=Change Rank;rank=[rank]'>[rank]</a></li>"
temp += "</ul>"
else
alert(usr, "You do not have the required rank to do this!")
if("species")
if (istype(active1, /datum/data/record))
var/t1 = sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message)
if (!t1 || active1 != a1)
return
active1.fields["species"] = t1
if("photo front")
var/icon/photo = get_photo(usr)
if(photo)
active1.fields["photo_front"] = photo
if("photo side")
var/icon/photo = get_photo(usr)
if(photo)
active1.fields["photo_side"] = photo
for(var/datum/data/record/R in data_core.general)
if(t1 == lowertext(R.fields["name"]) || t1 == lowertext(R.fields["id"]) || t1 == lowertext(R.fields["fingerprint"]))
active1 = R
break
if(!active1)
set_temp("Security record not found. You must enter the person's exact name, ID, or fingerprint.", "danger")
return
for(var/datum/data/record/E in data_core.security)
if(E.fields["name"] == active1.fields["name"] && E.fields["id"] == active1.fields["id"])
active2 = E
break
screen = SEC_DATA_RECORD
if("print_p")
if(!printing)
printing = TRUE
// playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, TRUE)
SStgui.update_uis(src)
addtimer(CALLBACK(src, .proc/print_finish), 5 SECONDS)
if("photo_front")
var/icon/photo = get_photo(usr)
if(photo && active1)
active1.fields["photo_front"] = photo
active1.fields["photo-south"] = "'data:image/png;base64,[icon2base64(photo)]'"
if("photo_side")
var/icon/photo = get_photo(usr)
if(photo && active1)
active1.fields["photo_side"] = photo
active1.fields["photo-west"] = "'data:image/png;base64,[icon2base64(photo)]'"
else
return FALSE
//TEMPORARY MENU FUNCTIONS
else//To properly clear as per clear screen.
temp=null
switch(href_list["choice"])
if ("Change Rank")
if (active1)
active1.fields["rank"] = href_list["rank"]
if(href_list["rank"] in joblist)
active1.fields["real_rank"] = href_list["real_rank"]
if ("Change Criminal Status")
if (active2)
for(var/mob/living/carbon/human/H in player_list)
BITSET(H.hud_updateflag, WANTED_HUD)
switch(href_list["criminal2"])
if("none")
active2.fields["criminal"] = "None"
if("arrest")
active2.fields["criminal"] = "*Arrest*"
if("incarcerated")
active2.fields["criminal"] = "Incarcerated"
if("parolled")
active2.fields["criminal"] = "Parolled"
if("released")
active2.fields["criminal"] = "Released"
if ("Delete Record (Security) Execute")
if (active2)
qdel(active2)
if ("Delete Record (ALL) Execute")
if (active1)
for(var/datum/data/record/R in data_core.medical)
if ((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"]))
qdel(R)
else
qdel(active1)
if (active2)
qdel(active2)
/**
* Called in tgui_act() to process modal actions
*
* Arguments:
* * action - The action passed by tgui
* * params - The params passed by tgui
*/
/obj/machinery/computer/secure_data/proc/tgui_act_modal(action, params)
. = TRUE
var/id = params["id"] // The modal's ID
var/list/arguments = istext(params["arguments"]) ? json_decode(params["arguments"]) : params["arguments"]
switch(tgui_modal_act(src, action, params))
if(TGUI_MODAL_OPEN)
switch(id)
if("edit")
var/field = arguments["field"]
if(!length(field) || !field_edit_questions[field])
return
var/question = field_edit_questions[field]
var/choices = field_edit_choices[field]
if(length(choices))
tgui_modal_choice(src, id, question, arguments = arguments, value = arguments["value"], choices = choices)
else
temp = "This function does not appear to be working at the moment. Our apologies."
tgui_modal_input(src, id, question, arguments = arguments, value = arguments["value"])
if("add_c")
tgui_modal_input(src, id, "Please enter your message:")
else
return FALSE
if(TGUI_MODAL_ANSWER)
var/answer = params["answer"]
switch(id)
if("edit")
var/field = arguments["field"]
if(!length(field) || !field_edit_questions[field])
return
var/list/choices = field_edit_choices[field]
if(length(choices) && !(answer in choices))
return
add_fingerprint(usr)
updateUsrDialog()
return
if(field == "age")
answer = text2num(answer)
if(field == "rank")
if(answer in joblist)
active1.fields["real_rank"] = answer
if(field == "criminal")
for(var/mob/living/carbon/human/H in player_list)
BITSET(H.hud_updateflag, WANTED_HUD)
if(istype(active2) && (field in active2.fields))
active2.fields[field] = answer
if(istype(active1) && (field in active1.fields))
active1.fields[field] = answer
if("add_c")
if(!length(answer) || !istype(active2) || !length(authenticated))
return
active2.fields["comments"] += list(list(
header = "Made by [authenticated] ([rank]) at [worldtime2stationtime(world.time)]",
text = answer
))
else
return FALSE
else
return FALSE
/**
* Called when the print timer finishes
*/
/obj/machinery/computer/secure_data/proc/print_finish()
var/obj/item/weapon/paper/P = new(loc)
P.info = "<center><b>Security Record</b></center><br>"
if(istype(active1, /datum/data/record) && data_core.general.Find(active1))
P.info += {"Name: [active1.fields["name"]] ID: [active1.fields["id"]]
<br>\nSex: [active1.fields["sex"]]
<br>\nAge: [active1.fields["age"]]
<br>\nFingerprint: [active1.fields["fingerprint"]]
<br>\nPhysical Status: [active1.fields["p_stat"]]
<br>\nMental Status: [active1.fields["m_stat"]]<br>"}
else
P.info += "<b>General Record Lost!</b><br>"
if(istype(active2, /datum/data/record) && data_core.security.Find(active2))
P.info += {"<br>\n<center><b>Security Data</b></center>
<br>\nCriminal Status: [active2.fields["criminal"]]<br>\n
<br>\nMinor Crimes: [active2.fields["mi_crim"]]
<br>\nDetails: [active2.fields["mi_crim_d"]]<br>\n
<br>\nMajor Crimes: [active2.fields["ma_crim"]]
<br>\nDetails: [active2.fields["ma_crim_d"]]<br>\n
<br>\nImportant Notes:
<br>\n\t[active2.fields["notes"]]<br>\n
<br>\n
<center><b>Comments/Log</b></center><br>"}
for(var/c in active2.fields["comments"])
P.info += "[c["header"]]<br>[c["text"]]<br>"
else
P.info += "<b>Security Record Lost!</b><br>"
P.info += "</tt>"
P.name = "paper - 'Security Record: [active1.fields["name"]]'"
printing = FALSE
SStgui.update_uis(src)
/**
* Sets a temporary message to display to the user
*
* Arguments:
* * text - Text to display, null/empty to clear the message from the UI
* * style - The style of the message: (color name), info, success, warning, danger, virus
*/
/obj/machinery/computer/secure_data/proc/set_temp(text = "", style = "info", update_now = FALSE)
temp = list(text = text, style = style)
if(update_now)
SStgui.update_uis(src)
/obj/machinery/computer/secure_data/proc/is_not_allowed(var/mob/user)
return !src.authenticated || user.stat || user.restrained() || (!in_range(src, user) && (!istype(user, /mob/living/silicon)))
@@ -614,3 +508,5 @@ What a mess.*/
/obj/machinery/computer/secure_data/detective_computer
icon_state = "messyfiles"
#undef FIELD

View File

@@ -1,9 +1,12 @@
#define CHARS_PER_LINE 5
#define FONT_SIZE "5pt"
#define FONT_COLOR "#09f"
#define FONT_STYLE "Arial Black"
#define FONT_STYLE "Small Fonts"
#define MAX_TIMER 36000
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
#define PRESET_SHORT 1 MINUTES
#define PRESET_MEDIUM 5 MINUTES
#define PRESET_LONG 10 MINUTES
///////////////////////////////////////////////////////////////////////////////////////////////
// Brig Door control displays.
@@ -23,11 +26,12 @@
anchored = 1.0 // can't pick it up
density = 0 // can walk through it.
var/id = null // id of door it controls.
var/releasetime = 0 // when world.timeofday reaches it - release the prisoner
var/timing = 1 // boolean, true/1 timer is on, false/0 means it's not timing
var/picture_state // icon_state of alert picture, if not displaying text/numbers
var/list/obj/machinery/targets
var/timetoset = 0 // Used to set releasetime upon starting the timer
var/activation_time = 0
var/timer_duration = 0
var/timing = FALSE // boolean, true/1 timer is on, false/0 means it's not timing
var/list/obj/machinery/targets = list()
maptext_height = 26
maptext_width = 32
@@ -41,15 +45,15 @@
. = ..()
for(var/obj/machinery/door/window/brigdoor/M in machines)
if (M.id == src.id)
if(M.id == id)
LAZYADD(targets,M)
for(var/obj/machinery/flasher/F in machines)
if(F.id == src.id)
if(F.id == id)
LAZYADD(targets,F)
for(var/obj/structure/closet/secure_closet/brig/C in all_brig_closets)
if(C.id == src.id)
if(C.id == id)
LAZYADD(targets,C)
if(!LAZYLEN(targets))
@@ -65,212 +69,156 @@
// update the door_timer window and the icon
/obj/machinery/door_timer/process()
if(stat & (NOPOWER|BROKEN)) return
if(src.timing)
// poorly done midnight rollover
// (no seriously there's gotta be a better way to do this)
var/timeleft = timeleft()
if(timeleft > 1e5)
src.releasetime = 0
if(world.timeofday > src.releasetime)
src.timer_end() // open doors, reset timer, clear status screen
src.timing = 0
src.updateUsrDialog()
src.update_icon()
else
timer_end()
return
if(stat & (NOPOWER|BROKEN))
return
if(timing)
if(world.time - activation_time >= timer_duration)
timer_end() // open doors, reset timer, clear status screen
update_icon()
// has the door power situation changed, if so update icon.
/obj/machinery/door_timer/power_change()
..()
update_icon()
return
// open/closedoor checks if door_timer has power, if so it checks if the
// linked door is open/closed (by density) then opens it/closes it.
// Closes and locks doors, power check
/obj/machinery/door_timer/proc/timer_start()
if(stat & (NOPOWER|BROKEN)) return 0
if(!LAZYLEN(targets)) return 0
if(stat & (NOPOWER|BROKEN))
return 0
// Set releasetime
releasetime = world.timeofday + timetoset
activation_time = world.time
timing = TRUE
for(var/obj/machinery/door/window/brigdoor/door in targets)
if(door.density) continue
spawn(0)
door.close()
if(door.density)
continue
INVOKE_ASYNC(door, /obj/machinery/door/window/brigdoor.proc/close)
for(var/obj/structure/closet/secure_closet/brig/C in targets)
if(C.broken) continue
if(C.opened && !C.close()) continue
C.locked = 1
if(C.broken)
continue
if(C.opened && !C.close())
continue
C.locked = TRUE
C.icon_state = "closed_locked"
return 1
/// Opens and unlocks doors, power check
/obj/machinery/door_timer/proc/timer_end(forced = FALSE)
if(stat & (NOPOWER|BROKEN))
return 0
// Opens and unlocks doors, power check
/obj/machinery/door_timer/proc/timer_end()
if(stat & (NOPOWER|BROKEN)) return 0
if(!LAZYLEN(targets)) return 0
// Reset releasetime
releasetime = 0
timing = FALSE
activation_time = null
set_timer(0)
update_icon()
for(var/obj/machinery/door/window/brigdoor/door in targets)
if(!door.density) continue
spawn(0)
door.open()
if(!door.density)
continue
INVOKE_ASYNC(door, /obj/machinery/door/window/brigdoor.proc/open)
for(var/obj/structure/closet/secure_closet/brig/C in targets)
if(C.broken) continue
if(C.opened) continue
C.locked = 0
if(C.broken)
continue
if(C.opened)
continue
C.locked = FALSE
C.icon_state = "closed_unlocked"
return 1
// Check for releasetime timeleft
/obj/machinery/door_timer/proc/timeleft()
. = (releasetime - world.timeofday)/10
if(. < 0)
. = 0
/obj/machinery/door_timer/proc/time_left(seconds = FALSE)
. = max(0, timer_duration - (activation_time ? (world.time - activation_time) : 0))
if(seconds)
. /= 10
// Set timetoset
/obj/machinery/door_timer/proc/timeset(var/seconds)
timetoset = seconds * 10
/obj/machinery/door_timer/proc/set_timer(value)
var/new_time = clamp(value, 0, MAX_TIMER)
. = new_time == timer_duration //return 1 on no change
timer_duration = new_time
if(timer_duration && activation_time && timing) // Setting it while active will reset the activation time
activation_time = world.time
if(timetoset <= 0)
timetoset = 0
return
//Allows AIs to use door_timer, see human attack_hand function below
/obj/machinery/door_timer/attack_ai(var/mob/user as mob)
/obj/machinery/door_timer/attack_ai(mob/user)
return src.attack_hand(user)
/obj/machinery/door_timer/attack_hand(mob/user)
if(..())
return TRUE
tgui_interact(user)
//Allows humans to use door_timer
//Opens dialog window when someone clicks on door timer
// Allows altering timer and the timing boolean.
// Flasher activation limited to 150 seconds
/obj/machinery/door_timer/attack_hand(var/mob/user as mob)
/obj/machinery/door_timer/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "BrigTimer", name)
ui.open()
/obj/machinery/door_timer/tgui_data()
var/list/data = list()
data["time_left"] = time_left()
data["max_time_left"] = MAX_TIMER
data["timing"] = timing
data["flash_found"] = FALSE
data["flash_charging"] = FALSE
data["preset_short"] = PRESET_SHORT
data["preset_medium"] = PRESET_MEDIUM
data["preset_long"] = PRESET_LONG
for(var/obj/machinery/flasher/F in targets)
data["flash_found"] = TRUE
if(F.last_flash && (F.last_flash + 150) > world.time)
data["flash_charging"] = TRUE
break
return data
/obj/machinery/door_timer/tgui_act(action, params)
if(..())
return
. = TRUE
// Used for the 'time left' display
var/second = round(timeleft() % 60)
var/minute = round((timeleft() - second) / 60)
if(!allowed(usr))
to_chat(usr, "<span class='warning'>Access denied.</span>")
return FALSE
// Used for 'set timer'
var/setsecond = round((timetoset / 10) % 60)
var/setminute = round(((timetoset / 10) - setsecond) / 60)
user.set_machine(src)
// dat
var/dat = "<HTML><BODY><TT>"
dat += "<HR>Timer System:</hr>"
dat += " <b>Door [src.id] controls</b><br/>"
// Start/Stop timer
if (src.timing)
dat += "<a href='?src=\ref[src];timing=0'>Stop Timer and open door</a><br/>"
else
dat += "<a href='?src=\ref[src];timing=1'>Activate Timer and close door</a><br/>"
// Time Left display (uses releasetime)
dat += "Time Left: [(minute ? text("[minute]:") : null)][second] <br/>"
dat += "<br/>"
// Set Timer display (uses timetoset)
if(src.timing)
dat += "Set Timer: [(setminute ? text("[setminute]:") : null)][setsecond] <a href='?src=\ref[src];change=1'>Set</a><br/>"
else
dat += "Set Timer: [(setminute ? text("[setminute]:") : null)][setsecond]<br/>"
// Controls
dat += "<a href='?src=\ref[src];tp=-60'>-</a> <a href='?src=\ref[src];tp=-1'>-</a> <a href='?src=\ref[src];tp=1'>+</a> <A href='?src=\ref[src];tp=60'>+</a><br/>"
// Mounted flash controls
if(LAZYLEN(targets))
for(var/obj/machinery/flasher/F in targets)
if(F.last_flash && (F.last_flash + 150) > world.time)
dat += "<br/><A href='?src=\ref[src];fc=1'>Flash Charging</A>"
switch(action)
if("time")
var/real_new_time = 0
var/new_time = params["time"]
var/list/L = splittext(new_time, ":")
if(LAZYLEN(L))
for(var/i in 1 to LAZYLEN(L))
real_new_time += text2num(L[i]) * (60 ** (LAZYLEN(L) - i))
else
dat += "<br/><A href='?src=\ref[src];fc=1'>Activate Flash</A>"
dat += "<br/><br/><a href='?src=\ref[user];mach_close=computer'>Close</a>"
dat += "</TT></BODY></HTML>"
user << browse(dat, "window=computer;size=400x500")
onclose(user, "computer")
return
//Function for using door_timer dialog input, checks if user has permission
// href_list to
// "timing" turns on timer
// "tp" value to modify timer
// "fc" activates flasher
// "change" resets the timer to the timetoset amount while the timer is counting down
// Also updates dialog window and timer icon
/obj/machinery/door_timer/Topic(href, href_list)
if(..())
return
if(!src.allowed(usr))
return
usr.set_machine(src)
if(href_list["timing"])
src.timing = text2num(href_list["timing"])
if(src.timing)
src.timer_start()
real_new_time = text2num(new_time)
if(real_new_time)
set_timer(real_new_time * 10)
if("start")
timer_start()
if("stop")
timer_end(forced = TRUE)
if("flash")
for(var/obj/machinery/flasher/F in targets)
F.flash()
if("preset")
var/preset = params["preset"]
var/preset_time = time_left()
switch(preset)
if("short")
preset_time = PRESET_SHORT
if("medium")
preset_time = PRESET_MEDIUM
if("long")
preset_time = PRESET_LONG
set_timer(timer_duration + preset_time)
if(timing)
activation_time = world.time
else
src.timer_end()
else
if(href_list["tp"]) //adjust timer, close door if not already closed
var/tp = text2num(href_list["tp"])
var/addtime = (timetoset / 10)
addtime += tp
addtime = min(max(round(addtime), 0), 3600)
timeset(addtime)
if(href_list["fc"])
if(LAZYLEN(targets))
for(var/obj/machinery/flasher/F in targets)
F.flash()
if(href_list["change"])
src.timer_start()
src.add_fingerprint(usr)
src.updateUsrDialog()
src.update_icon()
/* if(src.timing)
src.timer_start()
else
src.timer_end() */
return
. = FALSE
//icon update function
@@ -281,53 +229,39 @@
if(stat & (NOPOWER))
icon_state = "frame"
return
if(stat & (BROKEN))
set_picture("ai_bsod")
return
if(src.timing)
if(timing)
var/disp1 = id
var/timeleft = timeleft()
var/disp2 = "[add_zero(num2text((timeleft / 60) % 60),2)]~[add_zero(num2text(timeleft % 60), 2)]"
var/timeleft = time_left(seconds = TRUE)
var/disp2 = "[add_leading(num2text((timeleft / 60) % 60), 2, "0")]:[add_leading(num2text(timeleft % 60), 2, "0")]"
if(length(disp2) > CHARS_PER_LINE)
disp2 = "Error"
update_display(disp1, disp2)
else
if(maptext) maptext = ""
if(maptext)
maptext = ""
return
// Adds an icon in case the screen is broken/off, stolen from status_display.dm
/obj/machinery/door_timer/proc/set_picture(var/state)
picture_state = state
overlays.Cut()
overlays += image('icons/obj/status_display.dmi', icon_state=picture_state)
/obj/machinery/door_timer/proc/set_picture(state)
if(maptext)
maptext = ""
cut_overlays()
add_overlay(mutable_appearance('icons/obj/status_display.dmi', state))
//Checks to see if there's 1 line or 2, adds text-icons-numbers/letters over display
// Stolen from status_display
/obj/machinery/door_timer/proc/update_display(var/line1, var/line2)
/obj/machinery/door_timer/proc/update_display(line1, line2)
line1 = uppertext(line1)
line2 = uppertext(line2)
var/new_text = {"<div style="font-size:[FONT_SIZE];color:[FONT_COLOR];font:'[FONT_STYLE]';text-align:center;" valign="top">[line1]<br>[line2]</div>"}
if(maptext != new_text)
maptext = new_text
//Actual string input to icon display for loop, with 5 pixel x offsets for each letter.
//Stolen from status_display
/obj/machinery/door_timer/proc/texticon(var/tn, var/px = 0, var/py = 0)
var/image/I = image('icons/obj/status_display.dmi', "blank")
var/len = length(tn)
for(var/d = 1 to len)
var/char = copytext(tn, len-d+1, len-d+2)
if(char == " ")
continue
var/image/ID = image('icons/obj/status_display.dmi', icon_state=char)
ID.pixel_x = -(d-1)*5 + px
ID.pixel_y = py
I.overlays += ID
return I
/obj/machinery/door_timer/cell_1
name = "Cell 1"
id = "Cell 1"
@@ -352,7 +286,12 @@
name = "Cell 6"
id = "Cell 6"
/obj/machinery/door_timer/tactical_pet_storage //Vorestation Addition
name = "Tactical Pet Storage"
id = "tactical_pet_storage"
desc = "Opens and Closes on a timer. This one seals away a tactical boost in morale."
#undef FONT_SIZE
#undef FONT_COLOR
#undef FONT_STYLE
#undef CHARS_PER_LINE
#undef CHARS_PER_LINE

View File

@@ -9,7 +9,6 @@
circuit = /obj/item/weapon/circuitboard/dna_analyzer
var/obj/item/weapon/forensics/swab/bloodsamp = null
var/closed = 0
var/scanning = 0
var/scanner_progress = 0
var/scanner_rate = 5
@@ -20,80 +19,76 @@
. = ..()
default_apply_parts()
/obj/machinery/dnaforensics/attackby(var/obj/item/W, mob/user as mob)
/obj/machinery/dnaforensics/attackby(obj/item/W, mob/user)
if(bloodsamp)
to_chat(user, "<span class='warning'>There is already a sample in the machine.</span>")
to_chat(user, "<span class='warning'>There is a sample in the machine.</span>")
return
if(closed)
if(!scanning)
if(default_deconstruction_screwdriver(user, W))
return
if(default_deconstruction_crowbar(user, W))
return
else
to_chat(user, "<span class='warning'>Open the cover before inserting the sample.</span>")
if(scanning)
to_chat(user, "<span class='warning'>[src] is busy scanning right now.</span>")
return
if(default_deconstruction_screwdriver(user, W))
return
if(default_deconstruction_crowbar(user, W))
return
var/obj/item/weapon/forensics/swab/swab = W
if(istype(swab) && swab.is_used())
user.unEquip(W)
src.bloodsamp = swab
swab.loc = src
to_chat(user, "<span class='notice'>You insert \the [W] into \the [src].</span>")
bloodsamp = swab
swab.forceMove(src)
to_chat(user, "<span class='notice'>You insert [W] into [src].</span>")
update_icon()
else
to_chat(user, "<span class='warning'>\The [src] only accepts used swabs.</span>")
return
/obj/machinery/dnaforensics/ui_interact(mob/user, ui_key = "main",var/datum/nanoui/ui = null)
if(stat & (NOPOWER)) return
if(user.stat || user.restrained()) return
var/list/data = list()
/obj/machinery/dnaforensics/tgui_interact(mob/user, datum/tgui/ui)
if(stat & (NOPOWER))
return
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "DNAForensics", "QuikScan DNA Analyzer") // 540, 326
ui.open()
/obj/machinery/dnaforensics/tgui_data(mob/user)
var/list/data = ..()
data["scan_progress"] = round(scanner_progress)
data["scanning"] = scanning
data["bloodsamp"] = (bloodsamp ? bloodsamp.name : "")
data["bloodsamp_desc"] = (bloodsamp ? (bloodsamp.desc ? bloodsamp.desc : "No information on record.") : "")
data["lidstate"] = closed
return data
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data)
if (!ui)
ui = new(user, src, ui_key, "dnaforensics.tmpl", "QuikScan DNA Analyzer", 540, 326)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/dnaforensics/Topic(href, href_list)
if(..()) return 1
/obj/machinery/dnaforensics/tgui_act(action, list/params)
if(..())
return TRUE
if(stat & (NOPOWER))
return 0 // don't update UIs attached to this object
return FALSE // don't update UIs attached to this object
if(href_list["scanItem"])
if(scanning)
scanning = 0
else
if(bloodsamp)
if(closed == 1)
. = TRUE
switch(action)
if("scanItem")
if(scanning)
scanning = FALSE
update_icon()
else
if(bloodsamp)
scanner_progress = 0
scanning = 1
scanning = TRUE
to_chat(usr, "<span class='notice'>Scan initiated.</span>")
update_icon()
else
to_chat(usr, "<span class='notice'>Please close sample lid before initiating scan.</span>")
else
to_chat(usr, "<span class='warning'>Insert an item to scan.</span>")
to_chat(usr, "<span class='warning'>Insert an item to scan.</span>")
. = TRUE
if(href_list["ejectItem"])
if(bloodsamp)
bloodsamp.forceMove(src.loc)
bloodsamp = null
if(href_list["toggleLid"])
toggle_lid()
return 1
if("ejectItem")
if(bloodsamp)
bloodsamp.forceMove(loc)
bloodsamp = null
scanning = FALSE
update_icon()
/obj/machinery/dnaforensics/process()
if(scanning)
@@ -110,7 +105,7 @@
last_process_worldtime = world.time
/obj/machinery/dnaforensics/proc/complete_scan()
src.visible_message("<span class='notice'>[bicon(src)] makes an insistent chime.</span>", 2)
visible_message("<span class='notice'>[bicon(src)] makes an insistent chime.</span>", 2)
update_icon()
if(bloodsamp)
var/obj/item/weapon/paper/P = new(src)
@@ -127,38 +122,23 @@
data += "No DNA found.<br>"
P.info = "<b>[src] analysis report #[report_num]</b><br>"
P.info += "<b>Scanned item:</b><br>[bloodsamp.name]<br>[bloodsamp.desc]<br><br>" + data
P.forceMove(src.loc)
P.forceMove(loc)
P.update_icon()
scanning = 0
scanning = FALSE
update_icon()
return
/obj/machinery/dnaforensics/attack_ai(mob/user as mob)
ui_interact(user)
/obj/machinery/dnaforensics/attack_ai(mob/user)
tgui_interact(user)
/obj/machinery/dnaforensics/attack_hand(mob/user as mob)
ui_interact(user)
/obj/machinery/dnaforensics/verb/toggle_lid()
set category = "Object"
set name = "Toggle Lid"
set src in oview(1)
if(usr.stat || !isliving(usr))
return
if(scanning)
to_chat(usr, "<span class='warning'>You can't do that while [src] is scanning!</span>")
return
closed = !closed
src.update_icon()
/obj/machinery/dnaforensics/attack_hand(mob/user)
tgui_interact(user)
/obj/machinery/dnaforensics/update_icon()
..()
if(!(stat & NOPOWER) && scanning)
icon_state = "dnaworking"
else if(closed)
else if(bloodsamp)
icon_state = "dnaclosed"
else
icon_state = "dnaopen"
icon_state = "dnaopen"